#include "munga.h" #pragma hdrstop #include "terrain.h" #include "boxsolid.h" #include "app.h" #include "interest.h" //############################################################################# //############################### Terrain ################################# //############################################################################# //############################################################################# // Shared Data Support // Derivation* Terrain::GetClassDerivations() { static Derivation classDerivations(Entity::GetClassDerivations(), "Terrain"); return &classDerivations; } Terrain::SharedData Terrain::DefaultData( Terrain::GetClassDerivations(), Terrain::GetMessageHandlers(), Terrain::GetAttributeIndex(), Terrain::StateCount, (Entity::MakeHandler)Terrain::Make ); //############################################################################# // Attribute Support // const Terrain::IndexEntry Terrain::AttributePointers[]= { { Terrain::LocalScaleAttributeID, "LocalScale", (Entity::AttributePointer)&Terrain::localScale } }; Terrain::AttributeIndexSet& Terrain::GetAttributeIndex() { static Terrain::AttributeIndexSet attributeIndex(ELEMENTS(Terrain::AttributePointers), Terrain::AttributePointers, Entity::GetAttributeIndex() ); return attributeIndex; } //############################################################################# // Construction and Destruction // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Terrain::Terrain( Terrain::MakeMessage *creation_message, Terrain::SharedData &virtual_data ): Entity(creation_message, virtual_data) { localScale = creation_message->localScale; SetValidFlag(); // //--------------------------------------------------------------------- // For now, load in the collision resources into the tree pointed to by // this resource //--------------------------------------------------------------------- // ResourceFile *res_file = application->GetResourceFile(); Check(res_file); ResourceDescription *res = res_file->SearchList( resourceID, ResourceDescription::BoxedSolidStreamResourceType ); collisionVolumes = NULL; if (res) { Check(res); res->Lock(); InterestManager *interest_mgr = application->GetInterestManager(); Check(interest_mgr); InterestZone *zone = interest_mgr->GetInterestZone(interestZoneID); Check(zone); BoxedSolidTree* tree = zone->GetCollisionRoot(); Check(tree); BoxedSolidResource* solids = (BoxedSolidResource*)res->resourceAddress; int size = res->resourceSize / sizeof(BoxedSolidResource); Dump(localOrigin); while (size--) { // // Don't forget about scaling... // BoxedSolidResource rot_box; rot_box.Instance(*solids,localOrigin); collisionVolumes = BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes); Register_Object(collisionVolumes); tree->Add(collisionVolumes, rot_box.sliceExtents); ++solids; } res->Unlock(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical Terrain::CreateMakeMessage( MakeMessage *creation_message, NotationFile *model_file, const ResourceDirectories *directories ) { Check(creation_message); Check(model_file); if (!Entity::CreateMakeMessage(creation_message, model_file, directories)) { return false; } creation_message->messageLength = sizeof(MakeMessage); creation_message->classToCreate = TerrainClassID; creation_message->instanceFlags = HermitInstance|TrappedFlag; char *p; if ((p = strtok(NULL, " ")) == NULL) { std::cerr << "Scale missing!\n"; return false; } creation_message->localScale = atof(p); return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Terrain* Terrain::Make(Terrain::MakeMessage *creation_message) { return new Terrain(creation_message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Terrain::~Terrain() { BoxedSolid *box = collisionVolumes; while (box) { BoxedSolid *next_box = box->GetNextSolid(); Unregister_Object(box); delete box; box = next_box; } } Logical Terrain::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); } //############################################################################# //######################### UnscalableTerrain ########################### //############################################################################# //############################################################################# // Shared Data Support // Derivation* UnscalableTerrain::GetClassDerivations() { static Derivation classDerivations(Terrain::GetClassDerivations(), "UnscalableTerrain"); return &classDerivations; } UnscalableTerrain::SharedData UnscalableTerrain::DefaultData( UnscalableTerrain::GetClassDerivations(), UnscalableTerrain::GetMessageHandlers(), UnscalableTerrain::GetAttributeIndex(), UnscalableTerrain::StateCount, (Entity::MakeHandler)UnscalableTerrain::Make ); //############################################################################# // Construction and Destruction // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // UnscalableTerrain::UnscalableTerrain( UnscalableTerrain::MakeMessage *creation_message, UnscalableTerrain::SharedData &virtual_data ): Entity(creation_message, virtual_data) { // //--------------------------------------------------------------------- // For now, load in the collision resources into the tree pointed to by // this resource //--------------------------------------------------------------------- // SetValidFlag(); ResourceFile *res_file = application->GetResourceFile(); Check(res_file); ResourceDescription *res = res_file->SearchList( resourceID, ResourceDescription::BoxedSolidStreamResourceType ); collisionVolumes = NULL; if (res) { Check(res); res->Lock(); InterestManager *interest_mgr = application->GetInterestManager(); Check(interest_mgr); InterestZone *zone = interest_mgr->GetInterestZone(interestZoneID); Check(zone); BoxedSolidTree* tree = zone->GetCollisionRoot(); Check(tree); BoxedSolidResource* solids = (BoxedSolidResource*)res->resourceAddress; int size = res->resourceSize / sizeof(BoxedSolidResource); while (size--) { BoxedSolidResource rot_box; rot_box.Instance(*solids,localOrigin); collisionVolumes = BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes); Register_Object(collisionVolumes); tree->Add(collisionVolumes, rot_box.sliceExtents); ++solids; } res->Unlock(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical UnscalableTerrain::CreateMakeMessage( MakeMessage *creation_message, NotationFile *model_file, const ResourceDirectories *directories ) { Check(creation_message); Check(model_file); if (!Entity::CreateMakeMessage(creation_message, model_file, directories)) { return false; } creation_message->classToCreate = UnscalableTerrainClassID; creation_message->instanceFlags = HermitInstance|TrappedFlag; return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // UnscalableTerrain* UnscalableTerrain::Make(UnscalableTerrain::MakeMessage *creation_message) { return new UnscalableTerrain(creation_message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // UnscalableTerrain::~UnscalableTerrain() { BoxedSolid *box = collisionVolumes; while (box) { BoxedSolid *next_box = box->GetNextSolid(); Unregister_Object(box); delete box; box = next_box; } } Logical UnscalableTerrain::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); }