00001 /* 00002 SagaEngine library 00003 Copyright (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 "O3dThingComponent.hpp" 00023 #include "../schema/O3dSchema.hpp" 00024 #include "ThingMO.hpp" 00025 #include "MultiO3dThingComponent.hpp" 00026 #include "util/math/ScaleT.hpp" 00027 #include "util/task/TaskList.hpp" 00028 #include <OgreSceneManager.h> 00029 00030 using namespace se_core; 00031 using namespace se_client; 00032 00033 namespace se_ogre { 00034 00035 O3dThingComponent 00036 ::O3dThingComponent(Composite* owner, const se_core::ComponentFactory* factory) 00037 : O3dNodeComponent(sct_RENDER, owner, factory), Task(2, 8), parentNode_(0), isVisible_(false) 00038 , isInitialized_(false) 00039 , size_(0) { 00040 } 00041 00042 00043 O3dThingComponent 00044 ::~O3dThingComponent() { 00045 Assert(!isInitialized_); 00046 } 00047 00048 00049 void O3dThingComponent 00050 ::init() { 00051 if(isInitialized_) 00052 return; 00053 isInitialized_ = true; 00054 00055 if(!node_) { 00056 node_ = O3dSchema::sceneManager->createSceneNode(); 00057 } 00058 00059 if(!parentNode_) { 00060 const PosComponent* a = PosComponent::Ptr(*this)->pos().area(); 00061 if(!a) { 00062 LogFatal("!"); 00063 return; 00064 } 00065 Assert(a); 00066 O3dNodeComponent::Ptr c(*a); 00067 Assert(!c.isNull()); 00068 Assert(c->node()); 00069 setParentNode(c->node()); 00070 } 00071 00072 O3dSchema::thingMOManager.create(this); 00073 } 00074 00075 void O3dThingComponent 00076 ::cleanup() { 00077 clear(); 00078 O3dSchema::taskList.remove(*this); 00079 } 00080 00081 00082 void O3dThingComponent 00083 ::clear() { 00084 if(!isInitialized_) 00085 return; 00086 isInitialized_ = false; 00087 00088 resetParentNode(); 00089 00090 while(!moList_.isEmpty()) { 00091 ThingMO* te = &moList_.pop(); 00092 O3dSchema::thingMOManager.release(te); 00093 } 00094 size_ = 0; 00095 00096 if(O3dSchema::sceneManager) { 00097 node_->removeAndDestroyAllChildren(); 00098 O3dSchema::sceneManager->destroySceneNode(node_->getName()); 00099 } 00100 node_ = 0; 00101 00102 } 00103 00104 void O3dThingComponent 00105 ::perform() { 00106 if(!isActive() || isDead()) 00107 return; 00108 init(); 00109 if(parentNode_ != 0) 00110 setVisible(true); 00111 } 00112 00113 00114 void O3dThingComponent 00115 ::setActive(bool state) { 00116 if(state) { 00117 if(ClientSchema::player->nextPos().area() == PosComponent::get(*this)->nextPos().area()) { 00118 this->setPriority(1); 00119 this->setWeight(0); 00120 } 00121 else { 00122 this->setPriority(5); 00123 this->setWeight(2); 00124 } 00125 O3dSchema::taskList.add(*this); 00126 } 00127 else { 00128 O3dSchema::taskList.remove(*this); 00129 setVisible(false); 00130 clear(); 00131 } 00132 } 00133 00134 00135 void O3dThingComponent 00136 ::setVisible(bool state) { 00137 if(isVisible_ == state) 00138 return; 00139 00140 isVisible_ = state; 00141 if(isVisible_) { 00142 O3dNodeComponent* c = static_cast<O3dNodeComponent*>(parent_); 00143 setParentNode(c->node()); 00144 parentNode_->addChild(node_); 00145 } 00146 else { 00147 parentNode_->removeChild(node_); 00148 resetParentNode(); 00149 } 00150 } 00151 00152 00153 void O3dThingComponent 00154 ::move(long when, float stepDelta, float timeSinceLastFrame) { 00155 // Are interpolations meaningful at all? 00156 if(owner() == 0) 00157 return; 00158 00159 if(!isInitialized_) 00160 return; 00161 00162 PosComponent::Ptr tPos(*this); 00163 /* 00164 if(isDead() || !isActive() || !tPos->pos().isKeyFramePath(tPos->nextPos())) { 00165 // If not skip it 00166 setVisible(false); 00167 return; 00168 } 00169 */ 00170 00171 setVisible(true); 00172 ViewPoint next; 00173 const scale_t alpha = ScaleT::fromFloat(stepDelta); 00174 tPos->worldViewPoint(alpha, next); 00175 00176 if(!next.viewPointEquals(last_)) { 00177 last_.setViewPoint(next); 00178 Ogre::Vector3 pos( 00179 CoorT::toFloat(last_.coor_.x_), 00180 CoorT::toFloat(last_.coor_.y_), 00181 CoorT::toFloat(last_.coor_.z_) 00182 ); 00183 00184 // Translate from Euler3 if necessary 00185 Quat4 face(next.face_); 00186 Ogre::Quaternion rot( 00187 QuatT::toFloat(face.w_), 00188 QuatT::toFloat(face.x_), 00189 QuatT::toFloat(face.y_), 00190 QuatT::toFloat(face.z_) 00191 ); 00192 00193 00194 // Set the new position 00195 node_->setPosition(pos - parentNode_->getPosition()); 00196 00197 // Set new orientation 00198 node_->setOrientation(rot); 00199 00200 } 00201 // Move children 00202 ThingMOList::Iterator it(moList_); 00203 while(it.hasNext()) { 00204 ThingMO* te = &it.next(); 00205 te->move(when, stepDelta, timeSinceLastFrame); 00206 te->resetPos(); 00207 } 00208 } 00209 00210 00211 void O3dThingComponent 00212 ::add(ThingMO& tmo) { 00213 //LogDetail(tmo.name()); 00214 int s = moList_.size(); 00215 moList_.add(tmo); 00216 ++size_; 00217 Assert(moList_.size() == size_); 00218 Assert(size_ == s + 1); 00219 tmo.setParentNode(node_); 00220 } 00221 00222 00223 void O3dThingComponent 00224 ::remove(ThingMO& tmo) { 00225 moList_.remove(tmo); 00226 --size_; 00227 } 00228 00229 00230 void O3dThingComponent 00231 ::setParentNode(Ogre::SceneNode* sn) { 00232 if(sn == parentNode_) 00233 return; 00234 if(!isInitialized_) 00235 return; 00236 00237 if(parentNode_) { 00238 if(isVisible_) 00239 parentNode_->removeChild(node_); 00240 node_->setPosition(node_->getPosition() + parentNode_->getPosition()); 00241 } 00242 parentNode_ = sn; 00243 node_->setPosition(node_->getPosition() - parentNode_->getPosition()); 00244 00245 if(isVisible_) 00246 parentNode_->addChild(node_); 00247 } 00248 00249 00250 void O3dThingComponent 00251 ::resetParentNode() { 00252 if(0 == parentNode_) 00253 return; 00254 if(!isInitialized_) 00255 return; 00256 00257 if(isVisible_) 00258 parentNode_->removeChild(node_); 00259 node_->setPosition(node_->getPosition() + parentNode_->getPosition()); 00260 00261 parentNode_ = 0; 00262 last_.setIdentity(); 00263 } 00264 00265 00266 void O3dThingComponent 00267 ::zoneChanged(int zoneType, Composite* newArea, Composite* oldArea) { 00268 if(zoneType != st_AREA) 00269 return; 00270 00271 if(newArea) { 00272 O3dNodeComponent* c = static_cast<O3dNodeComponent*>(newArea->component(type())); 00273 setParent(*c); 00274 setParentNode(c->node()); 00275 } 00276 else { 00277 setVisible(false); 00278 resetParent(); 00279 resetParentNode(); 00280 } 00281 } 00282 00283 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:08 2007 by Doxygen version 1.3.9.1.