Torque3D Documentation / _generateds / T3DSceneComponent.cpp

T3DSceneComponent.cpp

Engine/source/T3D/sceneComponent/T3DSceneComponent.cpp

More...

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