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