00001 /* 00002 SagaEngine library 00003 Cpyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "O3dPre.hpp" 00023 #include "O3dAreaComponent.hpp" 00024 #include "O3dManager.hpp" 00025 #include "../schema/O3dSchema.hpp" 00026 #include "../thing/ThingMO.hpp" 00027 #include "../thing/ThingMOInfo.hpp" 00028 #include "../thing/MultiO3dThingComponent.hpp" 00029 #include "sim/area/Area.hpp" 00030 #include "comp/CompositeFactory.hpp" 00031 #include "util/task/TaskList.hpp" 00032 #include <OgreSceneManager.h> 00033 #include <OgreStaticGeometry.h> 00034 #include <OgreEntity.h> 00035 00036 using namespace se_core; 00037 using namespace se_client; 00038 00039 namespace se_ogre { 00040 00041 O3dAreaComponent 00042 ::O3dAreaComponent(Composite* owner, const se_core::ComponentFactory* factory) 00043 : O3dNodeComponent(sct_RENDER, owner, factory), Task(0, 32), staticGeometry_(0) 00044 , isVisible_(false), isInitialized_(false) { 00045 setPriority(1); 00046 setWeight(16); 00047 O3dSchema::taskList.add(*this); 00048 } 00049 00050 00051 O3dAreaComponent 00052 ::~O3dAreaComponent() { 00053 O3dSchema::taskList.remove(*this); 00054 } 00055 00056 00057 void O3dAreaComponent 00058 ::init() { 00059 Assert(this != 0); 00060 if(isInitialized_) 00061 return; 00062 isInitialized_ = true; 00063 } 00064 00065 00066 void O3dAreaComponent 00067 ::cleanup() { 00068 if(!isInitialized_) 00069 return; 00070 isInitialized_ = false; 00071 } 00072 00073 00074 void O3dAreaComponent 00075 ::initStaticGeometry() { 00076 if(!staticGeometry_) { 00077 node_ = O3dSchema::sceneManager->createSceneNode(); 00078 areaOffset(offset_); 00079 node_->setPosition(offset_); 00080 00081 areaOffset(offset_); 00082 //LogDetail(owner()->name() << ": " << offset_.x << ", " << offset_.y << ", " << offset_.z); 00083 staticGeometry_ = compileStaticGeometry(); 00084 } 00085 } 00086 00087 00088 void O3dAreaComponent 00089 ::cleanupStaticGeometry() { 00090 if(staticGeometry_) { 00091 staticGeometry_->destroy(); 00092 staticGeometry_->reset(); 00093 O3dSchema::sceneManager->destroyStaticGeometry(staticGeometry_); 00094 staticGeometry_ = 0; 00095 } 00096 00097 if(O3dSchema::sceneManager && node_) { 00098 00099 setVisible(false); 00100 node_->removeAndDestroyAllChildren(); 00101 O3dSchema::sceneManager->destroySceneNode(node_->getName()); 00102 } 00103 node_ = 0; 00104 } 00105 00106 00107 void O3dAreaComponent 00108 ::perform() { 00109 if(!isActive()) 00110 return; 00111 00112 init(); 00113 node_->_updateBounds(); 00114 setVisible(true); 00115 } 00116 00117 00118 void O3dAreaComponent 00119 ::setActive(bool state) { 00120 if(state) { 00121 if(ClientSchema::player->nextPos().area() == PosComponent::get(*this)) { 00122 setPriority(0); 00123 setWeight(0); 00124 } 00125 else { 00126 setPriority(2); 00127 setWeight(isInitialized_ ? 16 : 64); 00128 } 00129 O3dSchema::taskList.add(*this); 00130 } 00131 else { 00132 O3dSchema::taskList.remove(*this); 00133 setVisible(false); 00134 } 00135 } 00136 00137 00138 void O3dAreaComponent 00139 ::setVisible(bool state) { 00140 if(isVisible_ == state) 00141 return; 00142 00143 isVisible_ = state; 00144 if(isVisible_) { 00145 //LogDetail("Now visible: " << owner()->name()); 00146 O3dSchema::sceneManager->getRootSceneNode()->addChild(node_); 00147 if(staticGeometry_) 00148 staticGeometry_->setVisible(true); 00149 } 00150 else { 00151 O3dSchema::sceneManager->getRootSceneNode()->removeChild(node_); 00152 if(staticGeometry_) 00153 staticGeometry_->setVisible(false); 00154 } 00155 } 00156 00157 00158 void O3dAreaComponent 00159 ::areaOffset(Ogre::Vector3& dest) { 00160 const Point3& c = PosComponent::Ptr(*this)->pos().worldCoor(); 00161 dest.x = c.x_; 00162 dest.y = c.y_; 00163 dest.z = c.z_; 00164 00165 if(O3dSchema::worldManager->isAreaGeomCentreAligned_) { 00166 Area::Ptr a(*this); 00167 dest.x += a->width() / 2.0f; 00168 dest.z += a->height() / 2.0f; 00169 } 00170 } 00171 00172 00173 bool O3dAreaComponent 00174 ::hasStaticGeometry(se_core::Composite& thing) { 00175 // Find which mesh this thing should use 00176 short index = O3dSchema::thingMOManager.infoIndex(thing.name()); 00177 if(index < 0) 00178 return false; 00179 00180 return O3dSchema::thingMOManager.info(index)->isStatic_; 00181 } 00182 00183 00184 00185 Ogre::StaticGeometry* O3dAreaComponent 00186 ::compileStaticGeometry() { 00187 Assert(!staticGeometry_); 00188 Area::Ptr a(*this); 00189 Ogre::StaticGeometry* sg = O3dSchema::sceneManager->createStaticGeometry(owner()->name()); 00190 00191 Ogre::Entity* entity; 00192 00193 00194 sg->setOrigin(offset_); 00195 00196 // Area geometry 00197 const char* areaType = (a->owner()->factory() != 0) ? a->owner()->factory()->name() : a->owner()->name(); 00198 // 00199 static int unique = 0; 00200 char name[256]; 00201 sprintf(name, "%s_%d", areaType, unique++); 00202 Ogre::String type(areaType); 00203 00204 if(O3dSchema::sceneManager->hasEntity(name)) { 00205 entity = O3dSchema::sceneManager->getEntity(name); 00206 } 00207 else { 00208 entity = O3dSchema::sceneManager->createEntity(name, type + ".mesh"); 00209 entity->setNormaliseNormals(true); 00210 } 00211 sg->addEntity(entity, offset_, Ogre::Quaternion::IDENTITY, Ogre::Vector3(1, 1, 1)); 00212 00213 #ifdef SE_INTERNAL 00214 type += "_navmesh"; 00215 00216 sprintf(name, "%s_%d_navMesh", areaType, unique++); 00217 if(O3dSchema::sceneManager->hasEntity(name)) { 00218 entity = O3dSchema::sceneManager->getEntity(name); 00219 } 00220 else { 00221 entity = O3dSchema::sceneManager->createEntity(name, type + ".mesh"); 00222 entity->setNormaliseNormals(true); 00223 } 00224 entity->setMaterialName("Basic/NavMesh"); 00225 sg->addEntity(entity, offset_, Ogre::Quaternion::IDENTITY, Ogre::Vector3(1, 1, 1)); 00226 #endif 00227 00228 // Add static things 00229 CompositeList::Iterator it(owner()->children()); 00230 while(it.hasNext()) { 00231 Composite& thing = it.next(); 00232 00233 if(!hasStaticGeometry(thing)) { 00234 continue; 00235 } 00236 00237 // Create entity 00238 const ThingMOInfo* info = O3dSchema::thingMOManager.info(thing.name()); 00239 Ogre::Entity* entity; 00240 if(O3dSchema::sceneManager->hasEntity(thing.name())) { 00241 entity = O3dSchema::sceneManager->getEntity(thing.name()); 00242 } 00243 else { 00244 Ogre::MovableObject* mo 00245 = O3dSchema::sceneManager->createMovableObject(thing.name(), Ogre::EntityFactory::FACTORY_TYPE_NAME, &info->params_); 00246 entity = static_cast<Ogre::Entity*>(mo); 00247 entity->setNormaliseNormals(true); 00248 } 00249 00250 00251 PosComponent* p = PosComponent::get(thing); 00252 Assert(p); 00253 ViewPoint& nextPos = p->nextPos().world_; 00254 Ogre::Vector3 pos( 00255 CoorT::toFloat(nextPos.coor_.x_), 00256 CoorT::toFloat(nextPos.coor_.y_), 00257 CoorT::toFloat(nextPos.coor_.z_) 00258 ); 00259 00260 Quat4 face(nextPos.face_); 00261 Ogre::Quaternion rot( 00262 QuatT::toFloat(face.w_), 00263 QuatT::toFloat(face.x_), 00264 QuatT::toFloat(face.y_), 00265 QuatT::toFloat(face.z_) 00266 ); 00267 00268 Ogre::Real scale = info->scale_; 00269 // If radius scales the model 00270 if(info->doScaleByRadius_) { 00271 // Interpolate between present radius and next radius 00272 scale *= CoorT::toFloat(p->nextPos().radius()); 00273 } 00274 00275 Ogre::Vector3 s(scale, scale, scale); 00276 sg->addEntity(entity, pos, rot, s); 00277 } 00278 00279 sg->setCastShadows(false); 00280 sg->setRegionDimensions(Ogre::Vector3(64, 64, 64)); 00281 sg->setRenderingDistance(256); 00282 sg->setRenderQueueGroup(Ogre::RENDER_QUEUE_WORLD_GEOMETRY_1); 00283 sg->setVisible(isActive()); 00284 sg->build(); 00285 00286 return sg; 00287 } 00288 00289 00290 void O3dAreaComponent 00291 ::move(long when, float stepDelta, float timeSinceLastFrame) { 00292 NodeComponentList::Iterator it(children_); 00293 while(it.hasNext()) { 00294 O3dThingComponent* tc = static_cast<O3dThingComponent*>(&it.next()); 00295 tc->move(when, stepDelta, timeSinceLastFrame); 00296 } 00297 } 00298 00299 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:04 2007 by Doxygen version 1.3.9.1.