[Gcblue-commits] gcb_wx/src/graphics tcSmoker.cpp,NONE,1.1 ObjectUpdater.cpp,1.11,1.12 tc3DModel.cpp
Status: Alpha
Brought to you by:
ddcforge
|
From: Dewitt C. <ddc...@us...> - 2005-01-16 18:36:40
|
Update of /cvsroot/gcblue/gcb_wx/src/graphics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32325/src/graphics Modified Files: ObjectUpdater.cpp tc3DModel.cpp Added Files: tcSmoker.cpp Log Message: Added xml 3D model wrapper for better modularity Improved animation support --- NEW FILE: tcSmoker.cpp --- /** ** @file tcSmoker.cpp */ /* Copyright (C) 2004 Dewitt Colclough (de...@tw...) ** All rights reserved. ** This file is part of the Global Conflict Blue (GCB) program. ** GCB is free software; you can redistribute it and/or modify ** it under the terms of version 2 of the GNU General Public License as ** published by the Free Software Foundation. ** GCB is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with GCB; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "stdwx.h" // precompiled header file #ifndef WX_PRECOMP #include "wx/wx.h" #endif // WX_PRECOMP #include "tcSmoker.h" #include "tcGameObject.h" #include "tcParticleEffect.h" #include "tcParticlePlacer.h" #ifdef _DEBUG #define new DEBUG_NEW #endif osg::ref_ptr<osg::Group> tcSmoker::world; /** * Static method to set common world frame to all tcSmoker objects */ void tcSmoker::SetWorldFrame(osg::Group* worldFrame) { world = worldFrame; } /** * */ void tcSmoker::AddSmokeTrail(const osg::Vec3& smokeSource, int smokeMode) { tcSmokeTrail trail; trail.smokeEffect = new tcParticleEffect(smokeMode); trail.smokeEffect->AddToSceneGraph(world.get()); trail.smokePlacer = trail.smokeEffect->GetParticlePlacer(); trail.smokeSource = smokeSource; smokeTrails.push_back(trail); } /** * */ void tcSmoker::DeleteTrails() { size_t nSmoke = smokeTrails.size(); for (size_t n=0; n<nSmoke; n++) { tcSmokeTrail& trail = smokeTrails[n]; trail.smokeEffect->DetachFromSceneGraph(); delete trail.smokeEffect; } smokeTrails.clear(); } /** * */ bool tcSmoker::IsEnabled() const { return smokeTrails.size() != 0; } /** * */ void tcSmoker::SetGameObject(tcGameObject* obj) { gameObj = obj; } /** * */ void tcSmoker::UpdateSmokePosition(float x, float y, float z) { wxASSERT(gameObj); // create rotation matrix (using euler angles for now) const osg::Vec3 xaxis(-1, 0, 0); const osg::Vec3 yaxis(0, 1, 0); const osg::Vec3 zaxis(0, 0, 1); osg::Vec3 pos(x, y, z); // heading, pitch, roll osg::Matrixf rotation; rotation.makeRotate(gameObj->mcKin.mfHeading_rad, zaxis, gameObj->mcKin.mfPitch_rad, xaxis, gameObj->mcKin.mfRoll_rad, yaxis); size_t nSmoke = smokeTrails.size(); for (size_t n=0; n<nSmoke; n++) { tcSmokeTrail& trail = smokeTrails[n]; wxASSERT(trail.smokePlacer); if (trail.smokePlacer == 0) return; osg::Vec3 smokeOffset = rotation * trail.smokeSource; osg::Vec3 offsetPos = pos + smokeOffset; trail.smokePlacer->setCenter(offsetPos.x(), offsetPos.y(), offsetPos.z()); } } /** * */ tcSmoker::tcSmoker() : gameObj(0) { } /** * */ tcSmoker::~tcSmoker() { } Index: ObjectUpdater.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/ObjectUpdater.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** ObjectUpdater.cpp 6 Nov 2004 15:13:41 -0000 1.11 --- ObjectUpdater.cpp 16 Jan 2005 18:36:29 -0000 1.12 *************** *** 68,71 **** --- 68,74 ---- if (nAnimations == 0) return; + tcGameObject* gameObject = model->GetGameObj(); + wxASSERT(gameObject); + // do not update animations if camera is beyond animation LOD distance //if (distanceFromCamera > 10000.0f) return; *************** *** 75,83 **** tcAnimationInfo& info = model->animationInfo[n]; int isActive = (info.switchVariable) ? *info.switchVariable : true; ! if (isActive) { osg::MatrixTransform *xform = info.transform; osg::Matrix matrix = xform->getMatrix(); double angle = info.omega * viewer->GetGameTime(); xform->setMatrix(matrix.rotate(angle , info.axis)); } --- 78,93 ---- tcAnimationInfo& info = model->animationInfo[n]; int isActive = (info.switchVariable) ? *info.switchVariable : true; ! if (info.bound && isActive) { osg::MatrixTransform *xform = info.transform; osg::Matrix matrix = xform->getMatrix(); double angle = info.omega * viewer->GetGameTime(); + + // scale rotation rate by platform speed for propeller animation type + if (info.animationType == 0) + { + angle *= gameObject->mcKin.mfSpeed_kts; + } + xform->setMatrix(matrix.rotate(angle , info.axis)); } *************** *** 140,144 **** - float yawCorrection = C_PI; // 180 degrees added to yaw for different 3D model convention --- 150,153 ---- *************** *** 156,161 **** osg::Matrix m = osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(pitch),1.0f,0.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(yaw + yawCorrection),0.0f,0.0f,1.0f)*osg::Matrix::translate(x,y,z) ; --- 165,170 ---- osg::Matrix m = osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* ! osg::Matrix::rotate(osg::inRadians(pitch),1.0f,0.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(yaw),0.0f,0.0f,1.0f)*osg::Matrix::translate(x,y,z) ; *************** *** 172,176 **** float x, y, z; bool isVisible = true; - float yawCorrection = 0; tcGameObject* gameObject = model->GetGameObj(); --- 181,184 ---- *************** *** 188,192 **** z = kin->mfAlt_m; ! yawCorrection = C_PI; // 180 degrees added to yaw for different 3D model convention } else --- 196,200 ---- z = kin->mfAlt_m; ! } else *************** *** 196,201 **** pitch = pos->pitch; roll = pos->roll; ! x = -pos->dx; // backwards because of 180 deg model issue ! y = pos->dz; // backwards because of 180 deg model issue z = pos->dy; isVisible = pos->isVisible; --- 204,209 ---- pitch = pos->pitch; roll = pos->roll; ! x = pos->dx; ! y = -pos->dz; z = pos->dy; isVisible = pos->isVisible; *************** *** 215,220 **** osg::Matrix m = osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(pitch),1.0f,0.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(yaw + yawCorrection),0.0f,0.0f,1.0f)*osg::Matrix::translate(x,y,z) ; if (isVisible) --- 223,228 ---- osg::Matrix m = osg::Matrix::rotate(osg::inRadians(roll),0.0f,1.0f,0.0f)* ! osg::Matrix::rotate(osg::inRadians(pitch),1.0f,0.0f,0.0f)* ! osg::Matrix::rotate(-osg::inRadians(yaw),0.0f,0.0f,1.0f)*osg::Matrix::translate(x,y,z) ; if (isVisible) Index: tc3DModel.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tc3DModel.cpp,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** tc3DModel.cpp 10 Jan 2005 00:30:54 -0000 1.19 --- tc3DModel.cpp 16 Jan 2005 18:36:29 -0000 1.20 *************** *** 34,37 **** --- 34,38 ---- #include "tcParticlePlacer.h" #include "tcGenericDBObject.h" + #include "common/tinyxml.h" #include <osg/MatrixTransform> #include <osg/Switch> *************** *** 57,65 **** osg::ref_ptr<osg::Node> m_Root; std::vector<tcAnimationInfo>& animationInfo; // vector of animation state info to update ! std::vector<animationDBInfo>& databaseInfo; ///< database info to find and configure animations public: ! AnimationProcessor(std::vector<tcAnimationInfo>& ai, std::vector<animationDBInfo>& adb) : NodeVisitor(TRAVERSE_ALL_CHILDREN) ! , animationInfo(ai), databaseInfo(adb) { } --- 58,66 ---- osg::ref_ptr<osg::Node> m_Root; std::vector<tcAnimationInfo>& animationInfo; // vector of animation state info to update ! public: ! AnimationProcessor(std::vector<tcAnimationInfo>& ai) : NodeVisitor(TRAVERSE_ALL_CHILDREN) ! , animationInfo(ai) { } *************** *** 80,91 **** } */ ! // search database for entry matching this node bool animateNode = false; ! animationDBInfo info; ! size_t nAnimations = databaseInfo.size(); ! for(size_t n=0;(n<nAnimations)&&(!animateNode);n++) { ! info = databaseInfo[n]; ! if (info.objectName == name) animateNode = true; } --- 81,93 ---- } */ ! ! // search for entry matching this node bool animateNode = false; ! tcAnimationInfo* info = 0; ! size_t nAnimations = animationInfo.size(); ! for(size_t n=0; (n<nAnimations)&&(!animateNode); n++) { ! info = &animationInfo[n]; ! if (info->objectName == name) animateNode = true; } *************** *** 116,143 **** ! tcAnimationInfo ai; ! if (info.animationType == "propeller") ! { ! ai.axis = osg::Vec3(0,1.0f,0); ! ai.animationType = 0; ! ai.omega = 10.0f; ! } ! else if (info.animationType == "rotor") ! { ! ai.axis = osg::Vec3(0,0,1.0f); ! ai.animationType = 2; ! ai.omega = 10.0f; ! } ! else ! { ! ai.axis = osg::Vec3(0,0,1.0f); ! ai.animationType = 1; ! ai.omega = 0.2f; ! ai.param = info.param; ! } ! ai.switchVariable = NULL; ! ai.transform = rotateTransform; - animationInfo.push_back(ai); if (tcOptions::Get()->OptionStringExists("Log3DModelDetails")) { --- 118,125 ---- ! info->switchVariable = NULL; ! info->transform = rotateTransform; ! info->bound = true; if (tcOptions::Get()->OptionStringExists("Log3DModelDetails")) { *************** *** 263,266 **** --- 245,257 ---- bool tc3DModel::useSmoothing = true; + /** + * Static method to set common world frame to all tc3DModel objects + */ + void tc3DModel::SetWorldFrame(osg::Group* worldFrame) + { + world = worldFrame; + tcSmoker::SetWorldFrame(worldFrame); + } + /** * Static method to load unknowns models. Should be called *************** *** 326,334 **** void tc3DModel::DisableSmoke() { ! if (smokeTrail) { ! smokeTrail->DetachFromSceneGraph(); ! smokeTrail = 0; ! smokePlacer = 0; } } --- 317,323 ---- void tc3DModel::DisableSmoke() { ! if (smokeTrails.IsEnabled()) { ! smokeTrails.DeleteTrails(); } } *************** *** 340,355 **** void tc3DModel::EnableSmoke() { ! smokeTrail = new tcParticleEffect(smokeMode); ! smokeTrail->AddToSceneGraph(world.get()); ! smokePlacer = smokeTrail->GetParticlePlacer(); ! ! if (smokeMode == tcParticleEffect::BUBBLES) ! { ! smokeSource.set(0, -GetRadius(), 0); ! } ! else { ! smokeSource.set(0, 0, 0); } } --- 329,346 ---- void tc3DModel::EnableSmoke() { ! switch (smokeMode) { ! case tcParticleEffect::AFTERBURNER: ! case tcParticleEffect::BUBBLES: ! for (size_t n=0; n<engineSmokeSources.size(); n++) ! { ! smokeTrails.AddSmokeTrail(engineSmokeSources[n], smokeMode); ! } ! break; ! default: ! smokeTrails.AddSmokeTrail(osg::Vec3(0, 0, 0), smokeMode); ! break; } + } *************** *** 397,400 **** --- 388,402 ---- } + /** + * @return true if smokeTrails object is active + */ + bool tc3DModel::IsSmokeEnabled() const + { + return smokeTrails.IsEnabled(); + } + + /** + * @param model_name model file name with extension + */ void tc3DModel::Load(std::string model_name) { *************** *** 405,423 **** } ! // try ive load first ! std::string full_name = model_name + ".ive"; ! ! modelNode = osgDB::readNodeFile(full_name.c_str()); if (!modelNode.valid()) { ! full_name = model_name + ".3ds"; ! modelNode = osgDB::readNodeFile(full_name.c_str()); ! if (!modelNode.valid()) ! { ! std::cout << "Load of 3D model: " << model_name << " failed.\n"; ! std::cerr << "Load of 3D model: " << model_name << " failed.\n"; ! return; ! } } if (useSmoothing) { --- 407,417 ---- } ! modelNode = osgDB::readNodeFile(model_name.c_str()); if (!modelNode.valid()) { ! std::cout << "Load of 3D model: " << model_name << " failed.\n"; ! std::cerr << "Load of 3D model: " << model_name << " failed.\n"; } + if (useSmoothing) { *************** *** 426,436 **** } ! fprintf(stdout,"tc3DModel--Loaded 3D model: %s\n", full_name.c_str()); } ! void tc3DModel::ProcessAnimations(std::vector<animationDBInfo>& animDBInfo) { ! AnimationProcessor animationProcessor(animationInfo, animDBInfo); modelNode->accept(animationProcessor); } --- 420,572 ---- } ! fprintf(stdout, "tc3DModel--Loaded 3D model: %s\n", model_name.c_str()); } ! /** ! * Newer 3D model system. Loads from an Xml file which has ! * animation info along with model file name and other info. ! * This can also be used to support multiple resolution and damage ! * models in the future. ! */ ! void tc3DModel::LoadXml(const std::string& file_name) { ! std::string fileNameWithPath = "3d\\"; ! fileNameWithPath += file_name; ! ! TiXmlDocument* doc = new TiXmlDocument(fileNameWithPath.c_str()); ! if (!doc->LoadFile()) ! { ! delete doc; ! fprintf(stderr, "Error loading XML file %s\n", file_name.c_str()); ! modelNode = unknownAll.get(); // use unknown model as default ! return; ! } ! ! TiXmlNode* node = doc->FirstChild("Model"); ! ! ! if (!node) ! { ! delete doc; ! fprintf(stderr, "Model entry missing in XML file %s\n", file_name.c_str()); ! modelNode = unknownAll.get(); // use unknown model as default ! return; ! } ! ! TiXmlElement* current = node->ToElement(); ! wxASSERT(current); ! ! std::string modelFileName = current->Attribute("File"); ! ! Load(modelFileName); ! ! LoadXmlAnimationInfo(doc); ! ! LoadXmlSmokeInfo(doc); ! ! ProcessAnimations(); ! ! delete doc; ! } ! ! /** ! * Loads animation info for model (if available) ! * This will populate the animationInfo vector ! */ ! void tc3DModel::LoadXmlAnimationInfo(TiXmlDocument* doc) ! { ! animationInfo.clear(); ! ! TiXmlNode* current = doc->FirstChild("Animation"); ! while (current) ! { ! if (TiXmlElement* elt = current->ToElement()) ! { ! tcAnimationInfo ai; ! double axisx = 0; ! double axisy = 0; ! double axisz = 0; ! double angleRate = 0.1; ! ! ai.bound = false; ! ai.objectName = elt->Attribute("Object"); ! ai.animationTypeName = elt->Attribute("Type"); ! ai.param = 0; ! ai.transform = 0; ! ai.axis.set(1, 0, 0); // default ! ! if (ai.animationTypeName == "Sensor") ! { ! elt->Attribute("SensorIndex", &ai.param); ! ai.animationType = 1; ! } ! else if (ai.animationTypeName == "Propeller") ! { ! ai.animationType = 0; ! } ! else if (ai.animationTypeName == "Rotor") ! { ! ai.animationType = 2; ! } ! else ! { ! fprintf(stderr, "Unrecognized animation type (%s)\n", ai.animationTypeName.c_str()); ! } ! ! // read rotation axis values ! elt->Attribute("AxisX", &axisx); ! elt->Attribute("AxisY", &axisy); ! elt->Attribute("AxisZ", &axisz); ! ! ai.axis.set(axisx, axisy, axisz); ! ai.axis.normalize(); ! ! elt->Attribute("AngleRate", &angleRate); ! ai.omega = angleRate; ! ! animationInfo.push_back(ai); ! ! } ! current = current->NextSibling("Animation"); ! } ! } ! ! ! /** ! * Loads smoke trails location info for model (if available) ! * This will populate the engineSmokeSources vector ! */ ! void tc3DModel::LoadXmlSmokeInfo(TiXmlDocument* doc) ! { ! engineSmokeSources.clear(); ! ! TiXmlNode* current = doc->FirstChild("Smoke"); ! while (current) ! { ! if (TiXmlElement* elt = current->ToElement()) ! { ! double x = 0; ! double y = 0; ! double z = 0; ! ! elt->Attribute("X", &x); ! elt->Attribute("Y", &y); ! elt->Attribute("Z", &z); ! ! engineSmokeSources.push_back(osg::Vec3(x, y, z)); ! } ! ! current = current->NextSibling("Smoke"); ! } ! ! } ! ! /** ! * ! */ ! void tc3DModel::ProcessAnimations() ! { ! AnimationProcessor animationProcessor(animationInfo); modelNode->accept(animationProcessor); } *************** *** 510,518 **** * Bind switchVariable for animations */ ! void tc3DModel::SetupUpdate(tcGameObject *obj) { wxASSERT(modelTransform->getUpdateCallback() == NULL); gameObj = obj; modelTransform->setUpdateCallback(new ObjectUpdater(this)); } --- 646,656 ---- * Bind switchVariable for animations */ ! void tc3DModel::SetupUpdate(tcGameObject* obj) { wxASSERT(modelTransform->getUpdateCallback() == NULL); gameObj = obj; modelTransform->setUpdateCallback(new ObjectUpdater(this)); + + smokeTrails.SetGameObject(obj); } *************** *** 543,566 **** void tc3DModel::UpdateSmokePosition(float x, float y, float z) { ! wxASSERT(smokePlacer); ! if (smokePlacer == 0) return; ! wxASSERT(gameObj); ! ! const osg::Vec3 xaxis(-1, 0, 0); ! const osg::Vec3 yaxis(0, 1, 0); ! const osg::Vec3 zaxis(0, 0, 1); ! ! osg::Vec3 pos(x, y, z); ! ! // heading, pitch, roll ! osg::Matrixf rotation; ! ! rotation.makeRotate(gameObj->mcKin.mfHeading_rad, zaxis, ! gameObj->mcKin.mfPitch_rad, xaxis, ! gameObj->mcKin.mfRoll_rad, yaxis); ! osg::Vec3 smokeOffset = rotation * smokeSource; ! pos = pos + smokeOffset; ! ! smokePlacer->setCenter(pos.x(), pos.y(), pos.z()); } --- 681,685 ---- void tc3DModel::UpdateSmokePosition(float x, float y, float z) { ! smokeTrails.UpdateSmokePosition(x, y, z); } *************** *** 579,584 **** */ tc3DModel::tc3DModel(const tc3DModel* source) ! : smokePlacer(0), smokeTrail(0), ! distanceFromCamera(1e10) { wxASSERT(source->modelNode.valid()); // error if modelNode not loaded yet --- 698,702 ---- */ tc3DModel::tc3DModel(const tc3DModel* source) ! : distanceFromCamera(1e10) { wxASSERT(source->modelNode.valid()); // error if modelNode not loaded yet *************** *** 608,611 **** --- 726,731 ---- } + engineSmokeSources = source->engineSmokeSources; + modelNode = dynamic_cast<osg::Node*>(source->modelNode->clone(ModelCopyOp(this,true,0))); |