BGE Scenegraph clean up: double-promotion warnings
[blender.git] / source / gameengine / SceneGraph / SG_Spatial.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/SceneGraph/SG_Spatial.cpp
29  *  \ingroup bgesg
30  */
31
32
33 #include "SG_Node.h"
34 #include "SG_Spatial.h"
35 #include "SG_Controller.h"
36 #include "SG_ParentRelation.h"
37
38 SG_Spatial::
39 SG_Spatial(
40         void* clientobj,
41         void* clientinfo,
42         SG_Callbacks& callbacks
43 ): 
44
45         SG_IObject(clientobj,clientinfo,callbacks),
46         m_localPosition(0.0f,0.0f,0.0f),
47         m_localRotation(1.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,1.0f),
48         m_localScaling(1.0f,1.0f,1.0f),
49         
50         m_worldPosition(0.0f,0.0f,0.0f),
51         m_worldRotation(1.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,1.0f),
52         m_worldScaling(1.0f,1.0f,1.0f),
53
54         m_parent_relation (NULL),
55         
56         m_bbox(MT_Point3(-1.0f, -1.0f, -1.0f), MT_Point3(1.0f, 1.0f, 1.0f)),
57         m_radius(1.0f),
58         m_modified(false),
59         m_ogldirty(false)
60 {
61 }
62
63 SG_Spatial::
64 SG_Spatial(
65         const SG_Spatial& other
66 ) : 
67         SG_IObject(other),
68         m_localPosition(other.m_localPosition),
69         m_localRotation(other.m_localRotation),
70         m_localScaling(other.m_localScaling),
71         
72         m_worldPosition(other.m_worldPosition),
73         m_worldRotation(other.m_worldRotation),
74         m_worldScaling(other.m_worldScaling),
75         
76         m_parent_relation(NULL),
77         
78         m_bbox(other.m_bbox),
79         m_radius(other.m_radius),
80         m_modified(false),
81         m_ogldirty(false)
82 {
83         // duplicate the parent relation for this object
84         m_parent_relation = other.m_parent_relation->NewCopy();
85 }
86         
87 SG_Spatial::
88 ~SG_Spatial()
89 {
90         delete (m_parent_relation);
91 }
92
93         void
94 SG_Spatial::
95 SetParentRelation(
96         SG_ParentRelation *relation
97 ) {
98         delete (m_parent_relation);
99         m_parent_relation = relation;
100         SetModified();
101 }
102
103
104 /**
105  * Update Spatial Data.
106  * Calculates WorldTransform., (either doing its self or using the linked SGControllers)
107  */
108
109
110         bool
111 SG_Spatial::
112 UpdateSpatialData(
113                 const SG_Spatial *parent,
114                 double time,
115                 bool& parentUpdated)
116 {
117         bool bComputesWorldTransform = false;
118
119         // update spatial controllers
120
121         SGControllerList::iterator cit = GetSGControllerList().begin();
122         SGControllerList::const_iterator c_end = GetSGControllerList().end();
123
124         for (;cit!=c_end;++cit)
125         {
126                 if ((*cit)->Update(time))
127                         bComputesWorldTransform = true;
128         }
129
130         // If none of the objects updated our values then we ask the
131         // parent_relation object owned by this class to update
132         // our world coordinates.
133
134         if (!bComputesWorldTransform)
135                 bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated);
136
137         return bComputesWorldTransform;
138 }
139
140 /**
141  * Position and translation methods
142  */
143
144
145         void 
146 SG_Spatial::
147 RelativeTranslate(
148         const MT_Vector3& trans,
149         const SG_Spatial *parent,
150         bool local
151 ) {
152         if (local) {
153                         m_localPosition += m_localRotation * trans;
154         }
155         else {
156                 if (parent) {
157                         m_localPosition += trans * parent->GetWorldOrientation();
158                 }
159                 else {
160                         m_localPosition += trans;
161                 }
162         }
163         SetModified();
164 }
165
166
167 /**
168  * Scaling methods.
169  */ 
170
171
172 /**
173  * Orientation and rotation methods.
174  */
175
176
177         void 
178 SG_Spatial::
179 RelativeRotate(
180         const MT_Matrix3x3& rot,
181         bool local
182 ) {
183         m_localRotation = m_localRotation * (
184         local ? 
185                 rot 
186         :
187         (GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
188         SetModified();
189 }
190
191
192
193 MT_Transform SG_Spatial::GetWorldTransform() const
194 {
195         return MT_Transform(m_worldPosition, 
196                 m_worldRotation.scaled(
197                 m_worldScaling[0], m_worldScaling[1], m_worldScaling[2]));
198 }
199
200 bool SG_Spatial::inside(const MT_Point3 &point) const
201 {
202         MT_Scalar radius = m_worldScaling[m_worldScaling.closestAxis()]*m_radius;
203         return (m_worldPosition.distance2(point) <= radius*radius) ?
204                 m_bbox.transform(GetWorldTransform()).inside(point) :
205                 false;
206 }
207
208 void SG_Spatial::getBBox(MT_Point3 *box) const
209 {
210         m_bbox.get(box, GetWorldTransform());
211 }
212
213 void SG_Spatial::getAABBox(MT_Point3 *box) const
214 {
215         m_bbox.getaa(box, GetWorldTransform());
216 }
217