T3DSceneComponent.cpp
Engine/source/T3D/sceneComponent/T3DSceneComponent.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "T3DSceneComponent.h" 25#include "T3DSceneClient.h" 26 27void T3DSceneComponent::setSceneGroup(const char * sceneGroup) 28{ 29 AssertFatal(getOwner()==<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>, "Changing scene group name after registration will have no effect."); 30 if (sceneGroup == NULL) 31 sceneGroup = StringTable->insert(""); 32 _sceneGroup = StringTable->insert(sceneGroup); 33} 34 35void T3DSceneComponent::setParentTransformName(const char * name) 36{ 37 _parentTransformName = StringTable->insert(name); 38 if (getOwner() != NULL) 39 { 40 Transform3D * old = _transform->getParentTransform(); 41 ValueWrapperInterface<Transform3D*> * iface = NULL; 42 if (_parentTransformName != NULL) 43 iface = getInterface<ValueWrapperInterface<Transform3D*> >("transform3D", _parentTransformName); 44 _transform->setParentTransform(iface == NULL ? NULL : iface->get()); 45 if (_transform->getParentTransform() != old) 46 setDirtyWorldBox(true); 47 } 48} 49 50void T3DSceneComponent::setObjectType(U32 objectTypeMask) 51{ 52 _objectType = objectTypeMask; 53 setUseOwnerObjectType(true); 54} 55 56void T3DSceneComponent::setDirtyObjectBox(bool val) 57{ 58 _SetFlag(T3DSceneComponent::DirtyObjectBox, val); 59 if (val && !isObjectBoxLocked()) 60 _ComputeObjectBox(); 61} 62 63void T3DSceneComponent::setDirtyWorldBox(bool val) 64{ 65 _SetFlag(T3DSceneComponent::DirtyWorldBox, val); 66 if (val && !isWorldBoxLocked()) 67 _UpdateWorldBox(); 68} 69 70void T3DSceneComponent::setObjectBoxLocked(bool val) 71{ 72 _SetFlag(T3DSceneComponent::LockObjectBox, val); 73 if (!val && isDirtyObjectBox()) 74 _ComputeObjectBox(); 75} 76 77void T3DSceneComponent::setWorldBoxLocked(bool val) 78{ 79 _SetFlag(T3DSceneComponent::LockWorldBox, val); 80 if (!val && isDirtyWorldBox()) 81 _UpdateWorldBox(); 82} 83 84void T3DSceneComponent::setPosition(const Point3F & pos) 85{ 86 _transform->setPosition(pos); 87 setDirtyWorldBox(true); 88} 89 90void T3DSceneComponent::setRotation(const QuatF & rotation) 91{ 92 _transform->setRotation(rotation); 93 setDirtyWorldBox(true); 94} 95 96void T3DSceneComponent::setScale(const Point3F & scale) 97{ 98 _transform->setScale (scale); 99 Parent::setScale(scale); 100 setDirtyWorldBox(true); 101} 102 103void T3DSceneComponent::setTransform3D(Transform3D * transform) 104{ 105 if (transform == NULL) 106 // never let it be null 107 return; 108 if (_transform != NULL) 109 delete _transform; 110 _transform = transform; 111 _transform->setDirtyListener(this); 112} 113 114void T3DSceneComponent::setTransform(const MatrixF & mat) 115{ 116 _transform->setLocalMatrix(mat); 117 Parent::setTransform(mat); 118 setDirtyWorldBox(true); 119} 120 121Box3F T3DSceneComponent::getObjectBox() 122{ 123 if (DirtyObjectBox && !LockObjectBox) 124 _ComputeObjectBox(); 125 126 return _objectBox->get(); 127} 128 129Box3F T3DSceneComponent::getWorldBox() 130{ 131 if (DirtyWorldBox && !LockWorldBox) 132 _UpdateWorldBox(); 133 134 MatrixF mat = getTransform3D()->getWorldMatrix(); 135 Box3F box = getObjectBox(); 136 137 mat.mul(box); 138 return box; 139} 140 141void T3DSceneComponent::Render() 142{ 143 if (_sceneClientList == NULL) 144 return; 145 146 PROFILE_SCOPE(T3DSceneComponent_Render); 147 148 GFX->multWorld(_transform->getWorldMatrix()); 149 150 if (doRenderObjectBounds()) 151 { 152 // TODO 153 } 154 if (doRenderWorldBounds()) 155 { 156 // TODO 157 } 158 159 for (T3DSceneClient * walk = _sceneClientList; walk != NULL; walk = walk->getNextSceneClient()) 160 { 161 IRenderable3D * render = dynamic_cast<IRenderable3D*>(walk); 162 if (render != NULL) 163 render->Render(); 164 } 165 166 GFX->popWorldMatrix(); 167} 168 169void T3DSceneComponent::AddSceneClient(T3DSceneClient * sceneClient) 170{ 171 AssertFatal(sceneClient,"Cannot add a NULL scene client"); 172 173 // add to the front of the list 174 sceneClient->setNextSceneClient(_sceneClientList); 175 _sceneClientList = sceneClient; 176 177 // extend object box 178 ISolid3D * solid = dynamic_cast<ISolid3D*>(sceneClient); 179 if (solid != NULL) 180 { 181 if (isObjectBoxLocked()) 182 setDirtyObjectBox(true); 183 else 184 { 185 Box3F box = solid->getObjectBox(); 186 if (solid->getTransform3D() != NULL) 187 { 188 MatrixF mat; 189 solid->getTransform3D()->getObjectMatrix(mat, true); 190 mat.mul(box); 191 } 192 box.extend(_objectBox->get().min); 193 box.extend(_objectBox->get().max); 194 _objectBox->set(box); 195 } 196 197 // policy is that we become parent transform 198 if (solid->getTransform3D() != NULL && solid->getTransform3D()->isChildOf(_transform, true)) 199 solid->getTransform3D()->setParentTransform(_transform); 200 } 201} 202 203void T3DSceneComponent::RemoveClientObject(T3DSceneClient * sceneClient) 204{ 205 AssertFatal(sceneClient != NULL, "Removing null scene client"); 206 if (sceneClient == NULL) 207 return; 208 if (_sceneClientList == sceneClient) 209 _sceneClientList = _sceneClientList->getNextSceneClient(); 210 else 211 { 212 T3DSceneClient * walk = _sceneClientList; 213 while (walk->getNextSceneClient() != sceneClient && walk != NULL) 214 walk = walk->getNextSceneClient(); 215 if (walk != NULL) 216 walk->setNextSceneClient(sceneClient->getNextSceneClient()); 217 } 218 219 if (dynamic_cast<ISolid3D*>(sceneClient)) 220 setDirtyObjectBox(true); 221} 222 223bool T3DSceneComponent::onComponentRegister(SimComponent * owner) 224{ 225 if (!Parent::onComponentRegister(owner) || !registerObject()) 226 return false; 227 228 // Note: was added to scene graph in register object 229 230 setTransform3D(_transform); 231 setParentTransformName(_parentTransformName); 232 233 return true; 234} 235 236void T3DSceneComponent::onComponentUnRegister() 237{ 238 _sceneClientList = NULL; 239 Parent::onComponentUnRegister(); 240} 241 242void T3DSceneComponent::registerInterfaces(SimComponent * owner) 243{ 244 Parent::registerInterfaces(owner); 245 246 // TODO: need to figure out the best way to wrap these 247 // we don't need to track these interfaces ourselves -- just create them here 248 ComponentInterface * sceneComponent = new ComponentInterface(); 249 ValueWrapperInterface<Transform3D*> * transform = new ValueWrapperInterface<Transform3D*>(_transform); 250 251 registerCachedInterface("sceneComponent", _sceneGroup, owner, sceneComponent); 252 registerCachedInterface("transform3D", _sceneGroup, owner, transform); 253 registerCachedInterface("box", _sceneGroup, this, _objectBox); 254} 255 256void T3DSceneComponent::_ComputeObjectBox() 257{ 258 _objectBox->set(Box3F(10E30f, 10E30f, 10E30f, -10E30f, -10E30f, -10E30f)); 259 bool gotone = false; 260 for (T3DSceneClient * walk = _sceneClientList; walk != NULL; walk = walk->getNextSceneClient()) 261 { 262 ISolid3D * solid = dynamic_cast<ISolid3D*>(walk); 263 if (solid == NULL) 264 continue; 265 266 Box3F box = solid->getObjectBox(); 267 if (solid->getTransform3D() != NULL) 268 { 269 MatrixF mat; 270 solid->getTransform3D()->getObjectMatrix(mat, true); 271 mat.mul(box); 272 } 273 box.extend(_objectBox->get().min); 274 box.extend(_objectBox->get().max); 275 _objectBox->set(box); 276 gotone = true; 277 } 278 if (!gotone) 279 _objectBox->set(Box3F()); 280 281 setDirtyObjectBox(false); 282 setDirtyWorldBox(true); 283} 284 285void T3DSceneComponent::_UpdateWorldBox() 286{ 287 setDirtyWorldBox(false); 288 // TODO: 289 // T3DSceneGraph.Instance.UpdateObject(this); 290} 291