Blender  V2.59
SG_Spatial.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: SG_Spatial.cpp 35175 2011-02-25 13:39:04Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #include "SG_Node.h"
00036 #include "SG_Spatial.h"
00037 #include "SG_Controller.h"
00038 #include "SG_ParentRelation.h"
00039 
00040 SG_Spatial::
00041 SG_Spatial(
00042         void* clientobj,
00043         void* clientinfo,
00044         SG_Callbacks& callbacks
00045 ): 
00046 
00047         SG_IObject(clientobj,clientinfo,callbacks),
00048         m_localPosition(0.0,0.0,0.0),
00049         m_localRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0),
00050         m_localScaling(1.f,1.f,1.f),
00051         
00052         m_worldPosition(0.0,0.0,0.0),
00053         m_worldRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0),
00054         m_worldScaling(1.f,1.f,1.f),
00055 
00056         m_parent_relation (NULL),
00057         
00058         m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)),
00059         m_radius(1.0),
00060         m_modified(false),
00061         m_ogldirty(false)
00062 {
00063 }
00064 
00065 SG_Spatial::
00066 SG_Spatial(
00067         const SG_Spatial& other
00068 ) : 
00069         SG_IObject(other),
00070         m_localPosition(other.m_localPosition),
00071         m_localRotation(other.m_localRotation),
00072         m_localScaling(other.m_localScaling),
00073         
00074         m_worldPosition(other.m_worldPosition),
00075         m_worldRotation(other.m_worldRotation),
00076         m_worldScaling(other.m_worldScaling),
00077         
00078         m_parent_relation(NULL),
00079         
00080         m_bbox(other.m_bbox),
00081         m_radius(other.m_radius),
00082         m_modified(false),
00083         m_ogldirty(false)
00084 {
00085         // duplicate the parent relation for this object
00086         m_parent_relation = other.m_parent_relation->NewCopy();
00087 }
00088         
00089 SG_Spatial::
00090 ~SG_Spatial()
00091 {
00092         delete (m_parent_relation);
00093 }
00094 
00095         void
00096 SG_Spatial::
00097 SetParentRelation(
00098         SG_ParentRelation *relation
00099 ){
00100         delete (m_parent_relation);
00101         m_parent_relation = relation;
00102         SetModified();
00103 }
00104 
00105 
00112         bool 
00113 SG_Spatial::
00114 UpdateSpatialData(
00115         const SG_Spatial *parent,
00116         double time,
00117         bool& parentUpdated
00118 ){
00119 
00120     bool bComputesWorldTransform = false;
00121 
00122         // update spatial controllers
00123         
00124         SGControllerList::iterator cit = GetSGControllerList().begin();
00125         SGControllerList::const_iterator c_end = GetSGControllerList().end();
00126 
00127         for (;cit!=c_end;++cit)
00128         {
00129                 if ((*cit)->Update(time))
00130                         bComputesWorldTransform = true;
00131         }
00132 
00133         // If none of the objects updated our values then we ask the
00134         // parent_relation object owned by this class to update 
00135         // our world coordinates.
00136 
00137         if (!bComputesWorldTransform)
00138                 bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated);
00139 
00140         return bComputesWorldTransform;
00141 }
00142 
00148         void 
00149 SG_Spatial::
00150 RelativeTranslate(
00151         const MT_Vector3& trans,
00152         const SG_Spatial *parent,
00153         bool local
00154 ){
00155         if (local) {
00156                         m_localPosition += m_localRotation * trans;
00157         } else {
00158                 if (parent) {
00159                         m_localPosition += trans * parent->GetWorldOrientation();
00160                 } else {
00161                         m_localPosition += trans;
00162                 }
00163         }
00164         SetModified();
00165 }       
00166         
00167 
00178         void 
00179 SG_Spatial::
00180 RelativeRotate(
00181         const MT_Matrix3x3& rot,
00182         bool local
00183 ){
00184         m_localRotation = m_localRotation * (
00185         local ? 
00186                 rot 
00187         :
00188         (GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
00189         SetModified();
00190 }
00191 
00192 
00193 
00194 MT_Transform SG_Spatial::GetWorldTransform() const
00195 {
00196         return MT_Transform(m_worldPosition, 
00197                 m_worldRotation.scaled(
00198                 m_worldScaling[0], m_worldScaling[1], m_worldScaling[2]));
00199 }
00200 
00201 bool SG_Spatial::inside(const MT_Point3 &point) const
00202 {
00203         MT_Scalar radius = m_worldScaling[m_worldScaling.closestAxis()]*m_radius;
00204         return (m_worldPosition.distance2(point) <= radius*radius) ?
00205                 m_bbox.transform(GetWorldTransform()).inside(point) :
00206                 false;
00207 }
00208 
00209 void SG_Spatial::getBBox(MT_Point3 *box) const
00210 {
00211         m_bbox.get(box, GetWorldTransform());
00212 }
00213 
00214 void SG_Spatial::getAABBox(MT_Point3 *box) const
00215 {
00216         m_bbox.getaa(box, GetWorldTransform());
00217 }
00218