|
Blender
V2.59
|
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