#include "rpl4.h" #pragma hdrstop #include "rpl4vid.h" #include "..\rp\chute.h" #include "..\munga\door.h" #include "..\munga\doorfram.h" #include "..\munga_l4\l4vidrnd.h" #include "..\munga\mission.h" #include "..\rp\rpplayer.h" #include "..\rp\weapsys.h" #include "..\munga\notation.h" #include "..\munga\namelist.h" #include "..\rp\vtv.h" #include "..\munga\app.h" // RB 1/14/07 //#include //#include //#include extern Entity *Entity_Being_Created; // !!! temp, till callback handlers become a class // HACK, this code makes sure the left and right engine geometry is loaded // one time and re-used. A more generic solution using the connection // manager will be created once we are sure it is safe to apply this // optimization to all cases. d3d_OBJECT *left_engine, *right_engine; // //############################################################################# // Constructor for the video renderer //############################################################################# // RPL4VideoRenderer::RPL4VideoRenderer( HWND hWnd, unsigned int screenWidth, unsigned int screenHeight, bool fullscreen, InterestType interest_type, InterestDepth depth_calibration ) : DPLRenderer(hWnd, screenWidth, screenHeight, fullscreen, interest_type, depth_calibration) { //STUBBED: DPL RB 1/14/07 vtvCount = 0; vtvsExpected = 999; //// //// Preload a couple of things for DPL //// // dpl_LoadObject ( "chg", dpl_load_normal ); // dpl_LoadObject ( "rivet", dpl_load_normal ); // dpl_LoadObject ( "lsaber", dpl_load_normal ); // dpl_LoadObject ( "bst", dpl_load_normal ); // dpl_LoadObject ( "tsphere", dpl_load_normal ); } // //############################################################################# // Destructor for the video renderer //############################################################################# // RPL4VideoRenderer::~RPL4VideoRenderer() { } #if 0 void RPL4VideoRenderer::MakeJointedMoverRenderables( Entity *entity ViewFrom view_type ) { bool inDeathZone dpl_ISECT_MODE intersect_mode; uint32 intersect_mask; char my_filename[40]; dpl_LOAD_MODE cache_mode; JointedMover *jointed_mover; Verify(entity->IsDerivedFrom(JointedMover::GetClassDerivations()); jointed_mover = Cast_Object( JointedMover*, entity ); cache_mode = dpl_load_nocache; // //~~~~~~~~~~~~~~~~~~~~~~~ // Outside or Inside View //~~~~~~~~~~~~~~~~~~~~~~~ // if (type == inside_entity) { inDepthZone = true; //buildInZone = dplDeathZone; intersect_mode = dpl_isect_mode_obj; intersect_mask = NULL; skl_type = EntitySegment::SkeletonType_A; } else { inDepthZone = true; //buildInZone = dplDeathZone; intersect_mode = dpl_isect_mode_geometry; intersect_mask = INTERSECT_ALL; skl_type = EntitySegment::SkeletonType_N; } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Create the root renderable and tie it to the entity //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RootRenderable *this_root = new RootRenderable( entity, // Entity to attach the renderable to RootRenderable::Dynamic, // How/when to execute the renderable NULL, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask); // intersection mask for the object Register_Object(this_root); if(eyeRelative && (entity == GetLinkedEntity())) { dpl_DCS* aDCS=this_root->GetDCS(); Check_Pointer(aDCS); Check_Pointer(dplTestEyeDCS); dpl_AddDCSToDCS( aDCS, dplTestEyeDCS ); } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // create an array for the parent DCS' sizeof(segmentTable) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // dpl_DCS **dcs_array = new (dpl_DCS(*[jointed_mover->segmentCount])); Register_Pointer(dcs_array); // //~~~~~~~~~~~~~~~~~~~~~~~~ // Get The Joint Subsystem //~~~~~~~~~~~~~~~~~~~~~~~~ // CString *object_file_name; JointSubsystem* joint_subsystem = jointed_mover->GetJointSubsystem(); Check(joint_subsystem); // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get the Segment table for this jointed Mover //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EntitySegment::SegmentTableIterator segment_iterator(jointed_mover->segmentTable); EntitySegment *current_segment; while ((current_segment = segment_iterator.ReadAndNext()) != NULL) { Check(current_segment); // //~~~~~~~~~~~~~~~~~~~~~~ // Get the offset matrix //~~~~~~~~~~~~~~~~~~~~~~ // LinearMatrix offset_matrix; offset_matrix = current_segment->GetBaseOffset(); // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get the parent DCS of the DCS we will be creating //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // dpl_DCS *parent_DCS; if(!current_segment->GetParent()) { parent_DCS = this_root->GetDCS(); } else { int parent_index; parent_index = current_segment->GetParentIndex(); Verify( (parent_index >= 0) && (parent_index < jointed_mover->segmentCount) ); parent_DCS = dcs_array[parent_index]; } Check_Pointer(parent_DCS); // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // See if this segment is a Site //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // if(current_segment->IsSiteSegment()) { // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // If this is an eye site build the eye renderable //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // if(type == insideEntity && strcmp(current_segment->GetName(), "siteeyepoint") == 0) { EulerAngles* eyepoint_rotation = (EulerAngles*)entity->GetAttributePointer("EyepointRotation"); #if 0 //DEBUG_LEVEL > 0 DPLEyeRenderable* this_eye = #endif mCamera = new DPLEyeRenderable( entity, false, offset_matrix, parent_DCS, dplMainView, eyepoint_rotation ); Register_Object(this_eye); } continue; } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get the dpl object and load it //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // object_file_name = current_segment->GetVideoObjectName(skl_type); if(object_file_name) { Dump(*object_file_name); //cout<<"normal object "<<*object_file_name<<"\n"; strcpy(my_filename,*object_file_name); *(my_filename + (strlen(my_filename) - 4)) = '\0'; this_object = dpl_LoadObject ( my_filename,cache_mode ); } else { this_object = NULL; } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get the segment index //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int this_segment_index; this_segment_index = current_segment->GetIndex(); Verify( (this_segment_index >= 0) && (this_segment_index < jointed_mover->segmentCount) ); // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // If this segment has a joint Get it //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int joint_index; joint_index = current_segment->GetJointIndex(); Joint::JointType joint_type; Joint *this_joint = NULL; if(joint_index == -1) { joint_type = Joint::StaticJointType; } else { Verify(joint_index < joint_subsystem->GetJointCount()); this_joint = joint_subsystem->GetJoint(joint_index); Check(this_joint); joint_type = this_joint->GetJointType(); } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Make the appropriate renderable //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // switch(joint_type) { case Joint::HingeXJointType: case Joint::HingeYJointType: case Joint::HingeZJointType: { HingeRenderable *this_child = new HingeRenderable( entity, // Entity to attach the renderable to HingeRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent_DCS, // the parent DCS we will be offsetting from &offset_matrix, // offset matrix to be applied prior to joint DCS this_joint->GetHingePtr()); // Hinge attribute we will use to control the joint Register_Object(this_child); dcs_array[this_segment_index] = this_child->GetDCS(); } break; } case Joint::BallJointType: { BallJointRenderable *this_child = new BallJointRenderable( entity, // Entity to attach the renderable to BallJointRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent_DCS, // the parent DCS we will be offsetting from &offset_matrix, // offset matrix to be applied prior to joint DCS this_joint->GetEulerAnglesPtr());// Euler angles to control rotation of the ball joint Register_Object(this_child); dcs_array[this_segment_index] = this_child->GetDCS(); break; } case Joint::BallTranslationJointType: { BallTranslateJointRenderable *this_child = new BallTranslateJointRenderable( entity, // Entity to attach the renderable to BallTranslateJointRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent_DCS, // the parent DCS we will be offsetting from &offset_matrix, // offset matrix to be applied prior to joint DCS this_joint->GetEulerAnglesPtr(), // Euler angles to control rotation of the ball joint this_joint->GetTranslationPtr() // offset for the translation part of the joint ); Register_Object(this_child); dcs_array[this_segment_index] = this_child->GetDCS(); break; } case Joint::StaticJointType: default: { DPLStaticChildRenderable *this_child = new DPLStaticChildRenderable( entity, false, this_object, intersect_mode, intersect_mask, offset_matrix, parent_DCS ); Register_Object(this_child); dcs_array[this_segment_index] = this_child->GetDCS(); break; } } } // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Cycle through the VTV's subsystems and create the site renderables //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // for(int ii=0;iiGetSubsystemCount();++ii) { // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Controls Mapper is not propagated across // the network so we must ignore it here for replicants //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // if (ii == VTV::ControlsMapperSubsystem) { continue; } Subsystem *current_subsystem = entity->GetSubsystem(ii); Check(current_subsystem); int site_index = current_subsystem->GetSegmentIndex(); if (site_index != -1) { EntitySegment *site_segment = entity->GetSegment(site_index); Check(site_segment); // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get the parentDCS for this site //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // dpl_DCS *parent_DCS; if(!site_segment->GetParent()) { parent_DCS = this_root->GetDCS(); } else { int parent_index; parent_index = site_segment->GetParentIndex(); Verify( (parent_index >= 0) && (parent_index < jointed_mover->segmentCount) ); parent_DCS = dcs_array[parent_index]; } Check_Pointer(parent_DCS); // //~~~~~~~~~~~~~~~~~~~~ // Get the base offset //~~~~~~~~~~~~~~~~~~~~ // LinearMatrix base_offset = site_segment->GetBaseOffset(); switch(current_subsystem->GetClassID()) { class LaserDrillClassID: this_object = dpl_LoadObject ( "lsaber", dpl_load_normal ); Check_Pointer(this_object); Vector3D* laser_scale = (Vector3D*)current_subsystem->GetAttributePointer("LaserScale"); Logical* laser_on = (Logical*)current_subsystem->GetAttributePointer("LaserOn"); DPLScaleRenderable *this_scaler = new DPLScaleRenderable( entity, buildInZone, this_object, dpl_isect_mode, NULL, base_offset, parent_DCS, laser_scale, laser_on ); Register_Object(this_scaler); break; } } } Unregister_Pointer(dcs_array); delete[] dcs_array; Check_Fpu(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RPL4VideoRenderer::RecurseSKLFile This routine is called recursively to // to descend the hiearchy of a notation file and create all the renderables // needed to get an object visible. // void RPL4VideoRenderer::RecurseSKLFile( Entity *entity, HierarchicalDrawComponent *parent, NotationFile *mech_skeleton, const char *page_name, int recursion_depth, ViewFrom type, int *joint_counter, dpl_LOAD_MODE cache_mode ) { //STUBBED: DPL RB 1/14/07 NameList *joint_pages, *site_pages; NameList::Entry *entry; const char *site_page_name, *next_joint_page_name; // The next joint name (argument to a recursive call) const char *object_file_name, *my_joint_type; char *gun_name, *gun_attribute_name, my_filename[40]; int gun_site; #ifdef NOISY_RENDERER int i; // loop counter #endif Point3D translation(0,0,0); EulerAngles rotation(0,0,0); HierarchicalDrawComponent *next_parent; d3d_OBJECT *this_object = NULL; dpl_ISECT_MODE intersect_mode; uint32 intersect_mask; bool inDeathZone; // // get the intersect mode hooked up properly // if(type == insideEntity) { inDeathZone = true; //buildInZone = dplDeathZone; // intersect_mode = dpl_isect_mode_obj; intersect_mask = NULL; } else { inDeathZone = false; //buildInZone = dplMainZone; // intersect_mode = dpl_isect_mode_geometry; intersect_mask = INTERSECT_ALL; } // // indent by the recursion depth and print out the current page name // #ifdef NOISY_RENDERER Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Tell(page_name << "\n"); #endif // // suck the brains out of this page to create the renderable from // mech_skeleton->GetEntry(page_name, "tranx" ,&translation.x); mech_skeleton->GetEntry(page_name, "trany" ,&translation.y); mech_skeleton->GetEntry(page_name, "tranz" ,&translation.z); mech_skeleton->GetEntry(page_name, "pitch" ,&rotation.pitch.angle); mech_skeleton->GetEntry(page_name, "yaw" ,&rotation.yaw.angle); mech_skeleton->GetEntry(page_name, "roll" ,&rotation.roll.angle); if(mech_skeleton->GetEntry(page_name, "Object" ,&object_file_name)) { strcpy(my_filename,object_file_name); *(my_filename + (strlen(my_filename) - 4)) = '\0'; #ifdef NOISY_RENDERER Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Tell("BGF file: " << my_filename << "\n"); #endif // // HACK, this code makes sure the left and right engine geometry is loaded // // one time and re-used. A more generic solution using the connection // // manager will be created once we are sure it is safe to apply this // // optimization to all cases. // if( (strcmp("vra",my_filename) == 0) || // (strcmp("vrc",my_filename) == 0) || // (strcmp("vrn",my_filename) == 0) || // (strcmp("vrt",my_filename) == 0)) // { // if(right_engine == 0) // { // char *file = new char[strlen(my_filename) + 5]; // strcpy_s(file,strlen(my_filename)+5,my_filename); // strcat_s(file,strlen(my_filename)+5,".bgf"); // this_object = d3d_OBJECT::LoadObject ( GetDevice(), file ); // right_engine = this_object; //// cout<<"Load right engine\n"; // } // else // { // this_object = right_engine; //// cout<<"re-use right engine\n"; // } // } // else if( (strcmp("vla",my_filename) == 0) || // (strcmp("vlc",my_filename) == 0) || // (strcmp("vln",my_filename) == 0) || // (strcmp("vlt",my_filename) == 0)) // { // if(left_engine == 0) // { // char *file = new char[strlen(my_filename) + 5]; // strcpy_s(file,strlen(my_filename)+5,my_filename); // strcat_s(file,strlen(my_filename)+5,".bgf"); // this_object = d3d_OBJECT::LoadObject ( GetDevice(), file ); // left_engine = this_object; //// cout<<"Load left engine\n"; // } // else // { // this_object = left_engine; //// cout<<"re-use left engine\n"; // } // } // else { char *file = new char[strlen(my_filename) + 5]; strcpy_s(file,strlen(my_filename)+5,my_filename); strcat_s(file,strlen(my_filename)+5,".bgf"); this_object = d3d_OBJECT::LoadObject ( GetDevice(), file ); } } else { this_object = NULL; } // // dump out the data for me to look at // #ifdef NOISY_RENDERER Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Dump(translation); Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Dump(rotation); #endif // // Construct the renderable to display this part of the thing // LinearMatrix Offset_Matrix; Offset_Matrix = translation; Offset_Matrix = rotation; my_joint_type = "none"; mech_skeleton->GetEntry(page_name, "Type" ,&my_joint_type); if(recursion_depth>1) (*joint_counter)++; if(strncmp(my_joint_type,"hinge",5) == 0) { Tell("Hinge Joint " << (*joint_counter) << "\n"); VTV *vtv = (VTV*) entity; JointSubsystem *joint_subsystem = vtv->GetJointSubsystem(); Verify( (joint_subsystem->GetJoint(*joint_counter)->GetJointType() == Joint::HingeXJointType) || (joint_subsystem->GetJoint(*joint_counter)->GetJointType() == Joint::HingeYJointType) || (joint_subsystem->GetJoint(*joint_counter)->GetJointType() == Joint::HingeZJointType) ); const Hinge *hinge_joint = &joint_subsystem->GetJoint(*joint_counter)->GetHinge(); HingeRenderable *this_child = new HingeRenderable( entity, // Entity to attach the renderable to HingeRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later inDeathZone, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent, // the parent DCS we will be offsetting from &Offset_Matrix, // offset matrix to be applied prior to joint DCS hinge_joint); // Hinge attribute we will use to control the joint Register_Object(this_child); next_parent = this_child; } else if(strcmp(my_joint_type,"ball") == 0) { Tell("Ball Joint " << (*joint_counter) << "\n"); VTV *vtv = (VTV*) entity; JointSubsystem *joint_subsystem = vtv->GetJointSubsystem(); const EulerAngles *euler_angles = &joint_subsystem->GetJoint(*joint_counter)->GetEulerAngles(); Verify(joint_subsystem->GetJoint(*joint_counter)->GetJointType() == Joint::BallJointType); BallJointRenderable *this_child = new BallJointRenderable( entity, // Entity to attach the renderable to BallJointRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent, // the parent DCS we will be offsetting from &Offset_Matrix, // offset matrix to be applied prior to joint DCS euler_angles); // Euler angles to control rotation of the ball joint Register_Object(this_child); next_parent = this_child; } else if(strcmp(my_joint_type,"balltranslate") == 0) { Tell("Ball Translation Joint " << (*joint_counter) << "\n"); VTV *vtv = (VTV*) entity; JointSubsystem *joint_subsystem = vtv->GetJointSubsystem(); const EulerAngles *euler_angles = &joint_subsystem->GetJoint(*joint_counter)->GetEulerAngles(); const Point3D *point_3D = &joint_subsystem->GetJoint(*joint_counter)->GetTranslation(); Verify(joint_subsystem->GetJoint(*joint_counter)->GetJointType() == Joint::BallTranslationJointType); BallTranslateJointRenderable *this_child = new BallTranslateJointRenderable( entity, // Entity to attach the renderable to BallTranslateJointRenderable::Dynamic, // How/when to execute the renderable this_object, // object to hang on the DCS, may be a list later false, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask, // intersection mask for the object parent, // the parent DCS we will be offsetting from &Offset_Matrix, // offset matrix to be applied prior to joint DCS euler_angles, // Euler angles to control rotation of the ball joint point_3D); // offset for the translation part of the joint Register_Object(this_child); next_parent = this_child; } else { // Tell("Static Joint" << (*joint_counter) << "\n"); DPLStaticChildRenderable *this_child = new DPLStaticChildRenderable( entity, inDeathZone, this_object, intersect_mode, intersect_mask, Offset_Matrix, parent ); Register_Object(this_child); next_parent = this_child; } // // Get a the list of joint pages from the current page // if(type == insideEntity) { // dpl_SetDCSNearField ( next_parent_dcs, True ); // dpl_FlushDCS(next_parent_dcs); } joint_pages = mech_skeleton->MakeEntryList(page_name,"joint"); Register_Object(joint_pages); recursion_depth++; // // Recursively process all the joint pages on the current page // for( entry = joint_pages->GetFirstEntry(); entry; entry = entry->GetNextEntry()) { // Get the name of the next joint page next_joint_page_name = (char *)entry->dataReference; // Process the next page recursively through this routine RecurseSKLFile( entity, next_parent, mech_skeleton, next_joint_page_name, recursion_depth, type, joint_counter, cache_mode); } // // now check the list of sites for stuff to hook up // site_pages = mech_skeleton->MakeEntryList(page_name,"site"); Register_Object(site_pages); // // process all the site pages on the current page // for( entry = site_pages->GetFirstEntry(); entry; entry = entry->GetNextEntry()) { // Get the name of the next joint page site_page_name = (char *)entry->dataReference; // // Setup a eyepoint site, connect it to a rotation attribute so we can move it // arround. // if(type == insideEntity && strcmp(site_page_name, "siteeyepoint") == 0) { mech_skeleton->GetEntry(site_page_name, "tranx" ,&translation.x); mech_skeleton->GetEntry(site_page_name, "trany" ,&translation.y); mech_skeleton->GetEntry(site_page_name, "tranz" ,&translation.z); mech_skeleton->GetEntry(site_page_name, "pitch" ,&rotation.pitch.angle); mech_skeleton->GetEntry(site_page_name, "yaw" ,&rotation.yaw.angle); mech_skeleton->GetEntry(site_page_name, "roll" ,&rotation.roll.angle); #ifdef NOISY_RENDERER Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Tell(site_page_name << "\n"); Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Dump(translation); Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Dump(rotation); #endif EulerAngles* eyepoint_rotation = (EulerAngles*)entity->GetAttributePointer("EyepointRotation"); Offset_Matrix = translation; Offset_Matrix = rotation; #if 0 //DEBUG_LEVEL > 0 DPLEyeRenderable* this_eye = #endif mCamera = new DPLEyeRenderable( entity, // buildInZone, Offset_Matrix, next_parent, eyepoint_rotation ); Register_Object(this_eye); } // // Setup a gunport site, this works for all the sites // this is kind of funky but will be replaced as the VID file goes on line. // !!! Hack // gun_site = False; gun_name = ""; gun_attribute_name = ""; if(strcmp(site_page_name,"sitefrontrightport") == 0) { gun_site = True; gun_name = "LaserGun1"; gun_attribute_name = "FrontLaserOn"; } else if(strcmp(site_page_name,"sitefrontleftport") == 0) { gun_site = True; gun_name = "LaserGun2"; gun_attribute_name = "FrontLaserOn"; } else if(strcmp(site_page_name,"sitefrontcenterport") == 0) { gun_site = True; gun_name = "LaserGun"; gun_attribute_name = "FrontLaserOn"; } else if(strcmp(site_page_name,"sitebackrightport") == 0) { gun_site = True; gun_name = "LaserGun1"; gun_attribute_name = "RearLaserOn"; } else if(strcmp(site_page_name,"sitebackleftport") == 0) { gun_site = True; gun_name = "LaserGun2"; gun_attribute_name = "RearLaserOn"; } else if(strcmp(site_page_name,"sitebackcenterport") == 0) { gun_site = True; gun_name = "LaserGun"; gun_attribute_name = "RearLaserOn"; } if(gun_site) { LaserGun* laser_subsystem= (LaserGun*)entity->FindSubsystem(gun_name); if(laser_subsystem) { mech_skeleton->GetEntry(site_page_name, "tranx" ,&translation.x); mech_skeleton->GetEntry(site_page_name, "trany" ,&translation.y); mech_skeleton->GetEntry(site_page_name, "tranz" ,&translation.z); mech_skeleton->GetEntry(site_page_name, "pitch" ,&rotation.pitch.angle); mech_skeleton->GetEntry(site_page_name, "yaw" ,&rotation.yaw.angle); mech_skeleton->GetEntry(site_page_name, "roll" ,&rotation.roll.angle); Vector3D* laser_scale = (Vector3D*)laser_subsystem->GetAttributePointer("LaserScale"); Logical* laser_on = (Logical*)laser_subsystem->GetAttributePointer(gun_attribute_name); this_object = d3d_OBJECT::LoadObject ( GetDevice(), "lsaber.bgf" ); if( laser_subsystem && laser_scale && laser_on && this_object) { Tell("Hooked "< 0 DPLScaleRenderable *this_scaler = #endif new DPLScaleRenderable( entity, inDeathZone, this_object, intersect_mode, intersect_mask, Offset_Matrix, next_parent, laser_scale, laser_on); Register_Object(this_scaler); } } } // // Setup a chute site, get the position and attributes to control it and bind // them all up for use. // if(strcmp(site_page_name, "sitechute") == 0) { mech_skeleton->GetEntry(site_page_name, "tranx" ,&translation.x); mech_skeleton->GetEntry(site_page_name, "trany" ,&translation.y); mech_skeleton->GetEntry(site_page_name, "tranz" ,&translation.z); Chute* chute_subsystem= (Chute*)entity->FindSubsystem("Chute"); if (chute_subsystem) { Check(chute_subsystem); Quaternion* chute_rotation = (Quaternion*)chute_subsystem->GetAttributePointer("ChuteDirection"); Vector3D* chute_scale = (Vector3D*)chute_subsystem->GetAttributePointer("ScaleFactor"); Logical* chute_open = (Logical*)chute_subsystem->GetAttributePointer("ChuteOn"); this_object = d3d_OBJECT::LoadObject ( GetDevice(), "cht.bgf" ); if(chute_rotation && chute_scale && chute_open && this_object) { Check(chute_rotation); Check(chute_scale); Check_Pointer(chute_open); Check_Pointer(this_object); Offset_Matrix.BuildIdentity(); Offset_Matrix = translation; #if DEBUG_LEVEL > 0 DPLScaleQuatRenderable *this_scaler = #endif new DPLScaleQuatRenderable( entity, inDeathZone, this_object, intersect_mode, intersect_mask, Offset_Matrix, next_parent, chute_rotation, chute_scale, chute_open); Register_Object(this_scaler); } else { if(!chute_rotation) DEBUG_STREAM<<"ChuteSite couldn't find ChuteDirection attribute\n" << std::flush; if(!chute_scale) DEBUG_STREAM<<"ChuteSite couldn't find ChuteScale attribute\n" << std::flush; if(!chute_open) DEBUG_STREAM<<"ChuteSite couldn't find ChuteOn attribute\n" << std::flush; if(!this_object) DEBUG_STREAM<<"ChuteSite couldn't find chute DPL object\n" << std::flush; } } } // // Setup a booster site, get the site position and the attribute(s) that will // control the booster. Setup origin matrix and renderables to control the // appearance of the booster. // if(strcmp(site_page_name, "sitebooster") == 0) { #ifdef NOISY_RENDERER Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Tell(site_page_name << "\n"); Tell(recursion_depth); for (i = 0; i < recursion_depth; i++) Tell(".."); Dump(translation); #endif mech_skeleton->GetEntry(site_page_name, "tranx" ,&translation.x); mech_skeleton->GetEntry(site_page_name, "trany" ,&translation.y); mech_skeleton->GetEntry(site_page_name, "tranz" ,&translation.z); Vector3D* booster_scale = (Vector3D*)entity->GetAttributePointer("BoosterScale"); Logical* booster_on = (Logical*)entity->GetAttributePointer("BoosterOn"); this_object = d3d_OBJECT::LoadObject ( GetDevice(), "bst.bgf" ); if( booster_scale && booster_on && this_object) { Check(booster_scale); Check_Pointer(booster_on); Offset_Matrix.BuildIdentity(); Offset_Matrix = translation; #if DEBUG_LEVEL > 0 DPLScaleRenderable* this_scaler = #endif /*new DPLScaleRenderable( entity, inDeathZone, this_object, intersect_mode, intersect_mask, Offset_Matrix, next_parent, booster_scale, booster_on);*/ } else { if(!booster_scale) DEBUG_STREAM<<"BoosterSite couldn't find BoosterScale attribute\n" << std::flush; if(!booster_on) DEBUG_STREAM<<"BoosterSite couldn't find BoosterOn attribute\n" << std::flush; if(!this_object) DEBUG_STREAM<<"BoosterSite couldn't find booster DPL object\n" << std::flush; } Scalar* booster_smoke_density = (Scalar*)entity->GetAttributePointer("BoosterSmokeDensity"); if( booster_smoke_density ) { translation.z +=3.0; #if 1 #if DEBUG_LEVEL > 0 DPLRepeatSFXRenderable* this_effect = #endif new DPLRepeatSFXRenderable( entity, inDeathZone, translation, next_parent, // offset is relative to this 0, // type code for the effect booster_smoke_density); Register_Object(this_effect); #else DPLPSFXRenderable* this_effect = new DPLPSFXRenderable( entity, // Entity to attach the renderable to DPLPSFXRenderable::Dynamic, // How/when to execute the renderable booster_on, // address containing the trigger myPSFXDescriptons[4], // Pointer to the psfx description in memory next_parent_dcs, // DCS the effect is relative to (may be NULL) &translation); // Offset (or world coordinants if DCS is NULL) Register_Object(this_effect); #endif } else { if(!booster_smoke_density) DEBUG_STREAM<<"BoosterSite couldn't find BoosterSmokeDensity attribute\n" << std::flush; } } } // // Unregister the namelist objects we created in this subroutine // Check(joint_pages); Unregister_Object(joint_pages); delete joint_pages; Check(site_pages); Unregister_Object(site_pages); delete site_pages; } // //############################################################################# // This starts the process for of reading in a .skl file for a vtv. //############################################################################# // HierarchicalDrawComponent* RPL4VideoRenderer::ReadSKLFile( Entity *entity, // The entity we are dealing with ResourceDescription *model_resource, // Pointer to the video resource ViewFrom type, // type of reference to create char skeleton_type) // TEMPORARY!!!! to handle color substitutions { //STUBBED: DPL RB 1/14/07 //dpl_ZONE // *buildInZone; bool inDeathZone; int joint_counter; char *skl_filename, TempFileName[256]; NotationFile *object_skeleton; dpl_ISECT_MODE intersect_mode; uint32 intersect_mask; // test code for load size reduction left_engine = 0; right_engine = 0; // // Currently, the name of the .skl file to read in is in the video resource // After reading in the .skl file we die if the page count was zero, // indicating an empty file. // strcpy(TempFileName,"video\\"); //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // HACK to test video resource format changes skl_filename = (char *)model_resource->resourceAddress; skl_filename += sizeof(int); strcat(TempFileName, skl_filename); //strcat(TempFileName, ".skl"); //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // !!! Temporary hack to get proper vtv skl file to load TempFileName[8] = skeleton_type; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifdef NOISY_RENDERER Tell("RPL4VID.cpp loading .skl file "<PageCount() == 0) { DEBUG_STREAM << "RPL4VID.cpp couldn't load .skl file "< inDeathZone, // DPL Zone this stuff will live in (for culling) intersect_mode, // type of intersections to do on this object intersect_mask); // intersection mask for the object Register_Object(this_root); if(eyeRelative && entity == GetLinkedEntity()) { dpl_DCS* aDCS=this_root->GetDCS(); Check_Pointer(aDCS); Check_Pointer(dplTestEyeDCS); // dpl_AddDCSToDCS( aDCS, dplTestEyeDCS ); } // // Process all the interesting notation file pages // Check(object_skeleton); joint_counter = -1; LinearMatrix starting_matrix(True); dpl_LOAD_MODE dpl_load_nocache; RecurseSKLFile( entity, this_root, object_skeleton, "ROOT", 1, type, &joint_counter, dpl_load_nocache); // // Close the notation file // Unregister_Object(object_skeleton); delete object_skeleton; return this_root; } // //############################################################################# // This is the routine that will eventually process the script to create all // the renderables necessary to get an object on the screen. For the moment it // is just executing a hardwired script. //############################################################################# // void RPL4VideoRenderer::MakeEntityRenderables( Entity *entity, // The entity we are dealing with ResourceDescription *model_resource, // Pointer to the video resource ViewFrom view_type) // Type of reference (inside/outside...etc.) { #define MAX_DOS_FILENAME 15 HierarchicalDrawComponent *root; // // Make sure the callback system knows what entity is being created // !!!! This global will be replaced later. // Entity_Being_Created = entity; // // Examine the class id of the entity and call the appropriate creation script. // If we don't recognize the entity ID here we fall through to the inhereted // level and let it take care of it. // switch(entity->GetClassID()) { case VTVClassID: { vtvCount++; Tell("-------Creating VTV #"<GetAttributePointer("TargetReticle"); if(vehicleReticle) { Tell("RPL4VideoRenderer::vehicleReticle should be hooked up\n"); mReticle = new ReticleRenderable( entity, // Entity to attach the renderable to ReticleRenderable::Dynamic, // How/when to execute the renderable &vehicleReticle, // Pointer to the reticle structure in the entity dplMainView); // the view associated with our eye Register_Object(this_reticle); } else { Tell("RPL4VideoRenderer::vehicleReticle NOT hooked up\n"); } StateIndicator* simulation_state = (StateIndicator *)entity->GetAttributePointer("SimulationState"); if(simulation_state) { Tell("RPL4VideoRenderer::translocate effect hooked up\n"); #if DEBUG_LEVEL > 0 POVTranslocateRenderable* translocate = #endif new POVTranslocateRenderable( entity, // Entity to attach the renderable to POVTranslocateRenderable::Watcher, // How/when to execute the renderable true, // DPL zone the world is in dplDeathZone, // DPL zone the player's VTV and death effect are in root, // the parent DCS we will be offsetting from simulation_state, // State dial we use to control the translocation VTV::BurningState); // State that controls start/end of the effect Register_Object(translocate); } else { Tell("RPL4VideoRenderer::translocate effect NOT hooked up\n"); } } else { // // Script for renderables needed for outside view of the vehicle // Point3D my_offset_point(0.0, 0.0, 0.0); StateIndicator* simulation_state = (StateIndicator *)entity->GetAttributePointer("SimulationState"); if(simulation_state) { Tell("RPL4VideoRenderer::death effect hooked up\n"); #if 1 #if DEBUG_LEVEL > 0 DPLSFXRenderable* my_death_effect = #endif new DPLSFXRenderable( entity, // Entity to attach the effect to false, // DPL zone everything will be in my_offset_point, // Point offset from the parent DCS root, // Parent DCS (can be NULL for world) simulation_state, // Trigger effect when this attribute changes VTV::BurningState, // Trigger effect when in this state 6, // Type of effect to trigger 0.1); // Effect repeat speed. #else #if DEBUG_LEVEL > 0 DPLPSFXStateRenderable* my_death_effect = #endif new DPLPSFXStateRenderable( entity, // Entity to attach the renderable to DPLPSFXStateRenderable::Watcher, // How/when to execute the renderable simulation_state, // Trigger effect when this state changes VTV::BurningState, // The state to edge trigger on myPSFXDescriptons[2], // name of file with the PFX description in it root_DCS, // DCS the effect is relative to (may be NULL) &my_offset_point); // Offset (or world coordinants if DCS is NULL) #endif Register_Object(my_death_effect); } else { Tell("RPL4VideoRenderer::death effect NOT hooked up\n"); } StateIndicator* collision_state = (StateIndicator *)entity->GetAttributePointer("CollisionState"); if(simulation_state) { Tell("RPL4VideoRenderer::collision effects hooked up\n"); #if DEBUG_LEVEL > 0 DPLSFXRenderable* initial_collision_effect = #endif new DPLSFXRenderable( entity, // Entity to attach the effect to false, // DPL zone everything will be in my_offset_point, // Point offset from the parent DCS root, // Parent DCS (can be NULL for world) collision_state, // Trigger effect when this attribute changes VTV::InitialHitState, // Trigger effect when in this state 1, // Type of effect to trigger 0.1); // Effect repeat speed. Register_Object(initial_collision_effect); #if DEBUG_LEVEL > 0 DPLSFXRenderable* scrape_collision_effect = #endif new DPLSFXRenderable( entity, // Entity to attach the effect to false, // DPL zone everything will be in my_offset_point, // Point offset from the parent DCS root, // Parent DCS (can be NULL for world) collision_state, // Trigger effect when this attribute changes VTV::SlideState, // Trigger effect when in this state 1, // Type of effect to trigger 0.1); // Effect repeat speed. Register_Object(scrape_collision_effect); } else { Tell("RPL4VideoRenderer::collision effects NOT hooked up\n"); } } // // Teardown the vtv materal substitution namelists and disconnect DPL substitution handler // TearDownMaterialSubstitutionList(); #if 0 // // Check for all players loaded // if((vtvCount >= vtvsExpected) && (GetRendererStatus() == LoadingRendererStatus)) { Tell("Renderer Status set to running in RPL4VideoRenderer::MakeEntityRenderables\n"); SetRendererStatusToRunning(); } #endif break; } // // This constructs the renderables needed for the player class // case CrusherClassID: case BlockerClassID: case RunnerClassID: case PlayerClassID: case RPPlayerClassID: { // // We need to construct the translocate effect but only if this is a // player on another computer. We check this by asking if this is // a replicant instance. // StateIndicator* player_simulation_state = (StateIndicator *)entity->GetAttributePointer("SimulationState"); if(entity->GetInstance() == Player::ReplicantInstance) { // // Setup the translocation effect for third party view // Point3D* drop_zone_position = (Point3D *)entity->GetAttributePointer("DropZoneLocation"); if(player_simulation_state && drop_zone_position) { Tell("third party translocate effect is hooked up\n"); #if DEBUG_LEVEL > 0 TranslocationRenderable *my_translocate= #endif new TranslocationRenderable( entity, // Entity to attach the renderable to TranslocationRenderable::Watcher, // How/when to execute the renderable false, // DPL zone everything will be in player_simulation_state, // Trigger effects off of this state dial drop_zone_position, // Attribute that holds where the new drop will be RPPlayer::DropZoneAcquiredState); // State that indicates drop zone is valid (starts effect) Register_Object(my_translocate); } else { Tell("third party translocate effect NOT hooked up\n"); } } else { if(player_simulation_state) { Tell("Start/end effect hooked up\n"); #if DEBUG_LEVEL > 0 POVStartEndRenderable* start_end = #endif new POVStartEndRenderable( entity, // Entity to attach the renderable to POVStartEndRenderable::Watcher, // How/when to execute the renderable true, // DPL zone the world is in dplDeathZone, // DPL zone the player's VTV and death effect are in dplMainView, // The view containing our eye player_simulation_state, // State dial we use to control the translocation fogRed, // Fog color fogGreen, fogBlue, fogNear, // The near fog plane fogFar, // The far fog plane RPPlayer::MissionStartingState, // State that signals start of mission RPPlayer::MissionEndingState); // State that signals end of mission Register_Object(start_end); } else { Tell("Start/end effect NOT hooked up\n"); } } break; } // // At the RP level we have no default method for creating objects so we call the // next level down (l4) and let it have a try at creating the renderables. // default: { DPLRenderer::MakeEntityRenderables( entity, // The entity we are dealing with model_resource, // video resource for this entity view_type); // type of reference to create !!! should be enum break; } } // // Make sure the callback system knows what entity is being created // !!!! This global will be replaced later. // Entity_Being_Created = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LoadMissionImplementation For the moment it doesn't do much, just determines // how many players we should be expecting and sets a variable in the renderer // about it. // void RPL4VideoRenderer::LoadMissionImplementation(Mission* mission) { Tell("RPL4VideoRenderer::LoadMissionImplementation has been called\n"); // // First call our inhereted method to make sure the division card is initialized right // DPLRenderer::LoadMissionImplementation(mission); #if 0 // // This is a !!! HACK to figure out in advance how many VTV's to expect so we can // setup the game state properly. // Mission::HostAddressIterator mission_iterator(mission); vtvsExpected = mission_iterator.GetSize(); // // Check for all players loaded // if((vtvCount >= vtvsExpected) && (GetRendererStatus() == LoadingRendererStatus)) { Tell("Renderer Status set to running in RPL4VideoRenderer::LoadMissionImplementation\n"); SetRendererStatusToRunning(); } #endif } // //############################################################################# // SetupMaterialSubstitutionList This routine sets up the material substitution // prior to loading a vehicle. //############################################################################# // char RPL4VideoRenderer::SetupMaterialSubstitutionList( Entity* entity, ViewFrom view_type) // The entity we will be substituting for. { //STUBBED: DPL RB 1/14/07 extern NameList *materialSubstitutionList; static const char * const color_parameter = "%color%", * const badge_parameter = "%badge%"; static int color_parm_len = strlen(color_parameter), badge_parm_len = strlen(badge_parameter); NotationFile *veh_tbl; // vehicle table from resource file NameList::Entry *entry; // used to loop through namelists const char *egg_color, // color name in egg file (from entity) *egg_badge, // badge name in egg file (from entity) *veh_color, // color code from vehicle table *veh_badge; // badge code from vehicle table const char *source, // tracks progress in source string *pc; // jumps ahead of source pointer char *destination, // tracks progress in destination string buffer[80]; // holds result while being constructed int len; // misc. length char *vehicleTableResource; long vehicleTableResourceLength; char geometry_substitution = 'n'; Verify(materialSubstitutionList == NULL); // // Get the vehicle table out of resources. // ResourceDescription *res = application->GetResourceFile()->FindResourceDescription( "vehicletable", ResourceDescription::VehicleTableResourceType ); if (!res) { return(geometry_substitution); } Check(res); res->Lock(); vehicleTableResource = (char *)res->resourceAddress; vehicleTableResourceLength = (long)res->resourceSize; char *vehicle_table = new char[vehicleTableResourceLength]; Register_Pointer(vehicle_table); memcpy(vehicle_table, vehicleTableResource, vehicleTableResourceLength); veh_tbl = new NotationFile; Register_Object(veh_tbl); veh_tbl->ReadText(vehicle_table, vehicleTableResourceLength); Unregister_Pointer(vehicle_table); delete vehicle_table; res->Unlock(); // // Fetch the color and badge pointers out of the entity and into our local stuff // egg_color = ((VTV *)entity)->vehicleColor; egg_badge = ((VTV *)entity)->vehicleBadge; Check_Pointer(egg_color); Check_Pointer(egg_badge); if (!veh_tbl->GetEntry("color", egg_color, &veh_color)) { veh_color = NULL; } if (!veh_tbl->GetEntry("badge", egg_badge, &veh_badge)) { veh_badge = NULL; } else { if(view_type == insideEntity) { geometry_substitution = *(veh_badge + strlen(veh_badge) - 2); //ourself } else { geometry_substitution = *(veh_badge + strlen(veh_badge) - 1); //someone else } } //-------------------------------------------------- // get generic substitution list from vehicle table //-------------------------------------------------- materialSubstitutionList = veh_tbl->MakeEntryList("substitute"); Register_Object(materialSubstitutionList); //------------------------------------------------------------- // fill in % place holders with specifics for vtv being loaded //------------------------------------------------------------- entry = materialSubstitutionList->GetFirstEntry(); while (entry) { source = entry->GetChar(); *(destination = buffer) = '\0'; while ((pc = strchr(source, '%')) != NULL) { if ((len = pc-source) != 0) { strncpy(destination, source, len); source = pc; destination += len; } if (!strncmp(pc, color_parameter, color_parm_len)) { if (veh_color) { Str_Copy( destination, veh_color, sizeof(buffer)-(destination-buffer) ); destination += strlen(veh_color); } source += color_parm_len; } else if (!strncmp(pc, badge_parameter, badge_parm_len)) { if (veh_badge) { const char *qc = veh_badge; while (isgraph(*qc)) { ++qc; } if ((len = qc - veh_badge) != 0) { strncpy(destination, veh_badge, len); destination += len; } } source += badge_parm_len; } else { //------------------------------------- // % was not from recognized parameter //------------------------------------- *destination++ = *source++; } } if (*source) { Str_Copy( destination, source, sizeof(buffer)-(destination-buffer) ); } else { *destination = '\0'; } //--------------------------------------- // make copy of result and store in list //--------------------------------------- destination = new char[strlen(buffer)+1]; Register_Pointer(destination); strcpy(destination, buffer); entry->dataReference = (void *)destination; entry = entry->GetNextEntry(); } Unregister_Object(veh_tbl); delete veh_tbl; //dpl_SetMaterialNameCallback(substituteMaterial); return geometry_substitution; } // //############################################################################# // TearDownMaterialSubstitutionList This routine destroys and disconnects the // material substitution stuff after a vehicle has been loaded. //############################################################################# // void RPL4VideoRenderer::TearDownMaterialSubstitutionList() { //STUBBED: DPL RB 1/14/07 NameList::Entry *entry; char *p; extern NameList *materialSubstitutionList; if (materialSubstitutionList) { entry = materialSubstitutionList->GetFirstEntry(); while (entry) { if ((p = entry->GetChar()) != NULL) { Unregister_Pointer(p); delete p; entry->dataReference = NULL; } entry = entry->GetNextEntry(); } Unregister_Object(materialSubstitutionList); delete materialSubstitutionList; materialSubstitutionList = NULL; } //dpl_SetMaterialNameCallback(NULL); } //===========================================================================//