2 fegdk: FE Game Development Kit
3 Copyright (C) 2001-2008 Alexey "waker" Yakovenko
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 waker@users.sourceforge.net
24 #include "f_sceneobject.h"
25 #include "f_animation.h"
32 sceneObject::sceneObject (sceneObject
*parent
)
33 : mRelativeMatrix (true)
35 , mInitPosInverseMatrix (true)
37 mpParentObject
= parent
;
39 mpAnimatedChildren
= NULL
;
42 sceneObject::~sceneObject ()
44 if (mpAnimatedChildren
)
45 delete[] mpAnimatedChildren
;
48 matrix4
sceneObject::getWorldMatrix (void) const
53 matrix4
sceneObject::getRelativeMatrix (void) const
55 return mRelativeMatrix
;
58 matrix4
sceneObject::getSkinnedBoneRelativeMatrix (void) const
60 return mInitPosInverseMatrix
* mRelativeMatrix
;
63 matrix4
sceneObject::getSkinnedBoneWorldMatrix (void) const
65 return mInitPosInverseMatrix
* mWorldMatrix
;
68 void sceneObject::setWorldMatrix (const matrix4
&m
)
70 mFlags
|= (invalidate_children_tm
| recalc_aab
);
74 void sceneObject::setRelativeMatrix (const matrix4
&m
)
76 mFlags
|= invalidate_children_tm
;
79 mWorldMatrix
= mRelativeMatrix
* mpParentObject
->getWorldMatrix ();
81 mWorldMatrix
= mRelativeMatrix
;
84 void sceneObject::update (ulong updateFlags
)
86 if (updateFlags
& F_RECALC_MATRIX
)
89 mWorldMatrix
= mRelativeMatrix
* mpParentObject
->getWorldMatrix ();
91 mWorldMatrix
= mRelativeMatrix
;
94 if (mFlags
& invalidate_children_tm
)
96 updateFlags
|= F_RECALC_MATRIX
;
97 mFlags
&= ~invalidate_children_tm
;
100 for (sceneObject
*c
= mpChildren
; c
; c
= c
->mpNextChild
)
101 c
->update (updateFlags
);
104 sceneObject
*sceneObject::getNewInstance (sceneObject
*parent
)
106 sceneObject
*obj
= new sceneObject (parent
);
109 obj
->mpRenderable
= mpRenderable
->copy ();
110 // set new sceneobject to all drawsurfs
111 int sz
= obj
->mpRenderable
->numDrawSurfs ();
112 for (int i
= 0; i
< sz
; i
++)
113 obj
->mpRenderable
->getDrawSurf (i
)->obj
= obj
;
116 obj
->mWorldMatrix
= mWorldMatrix
;
117 obj
->mRelativeMatrix
= mRelativeMatrix
;
118 obj
->mInitPosInverseMatrix
= mInitPosInverseMatrix
;
119 for (sceneObject
*c
= mpChildren
; c
; c
= c
->mpNextChild
)
121 obj
->addChild (c
->getNewInstance (obj
));
126 sceneObject
* sceneObject::getChildren (void) const
131 void sceneObject::addChild (sceneObject
*child
)
133 child
->mpNextChild
= mpChildren
;
137 void sceneObject::removeChild (sceneObject
*child
)
143 if (mpChildren
== child
)
145 mpChildren
= child
->mpNextChild
;
146 child
->mpNextChild
= NULL
;
150 sceneObject
*c
= mpChildren
;
154 if (c
->mpNextChild
== child
)
156 c
->mpNextChild
= child
->mpNextChild
;
157 child
->mpNextChild
= NULL
;
164 sceneObject
* sceneObject::getNextChild (void) const
169 static void fillAnimData (sceneObject
*obj
, sceneObject
**lst
, animContainer
*cont
)
171 int nbones
= cont
->getNumBones ();
172 for (int i
= 0; i
< nbones
; i
++)
174 const char *n
= cont
->getBoneName (i
);
175 if (!strcmp (obj
->name (), n
))
181 for (sceneObject
*c
= obj
->getChildren (); c
; c
= c
->getNextChild ())
183 fillAnimData (c
, lst
, cont
);
187 void sceneObject::initAnimData (animContainer
*cont
)
189 if (mpAnimatedChildren
)
190 delete[] mpAnimatedChildren
;
191 int nbones
= cont
->getNumBones ();
192 mpAnimatedChildren
= new sceneObject
*[nbones
];
193 fillAnimData (this, mpAnimatedChildren
, cont
);
196 sceneObject
**sceneObject::getAnimatedChildren (void)
198 return mpAnimatedChildren
;
201 void sceneObject::calcAAB (void)
203 // for now it's just AAB, which is suitable to init physx obj
204 vector3
mins(1.0e+5f
, 1.0e+5f
, 1.0e+5f
);
205 vector3
maxs(-1.0e+5f
, -1.0e+5f
, -1.0e+5f
);
207 const matrix4
& mtx
= getWorldMatrix ();
208 fprintf (stderr
, "mtx: %f %f %f\n", mtx
.m
[3][0], mtx
.m
[3][1], mtx
.m
[3][2]);
209 int nds
= mpRenderable
->numDrawSurfs ();
210 for (int i
= 0; i
< nds
; i
++) {
211 drawSurf_t
*ds
= mpRenderable
->getDrawSurf (i
);
212 meshData_t
*md
= ds
->mesh
;
213 uchar
*vx
= md
->verts
;
214 for (int v
= 0; v
< md
->numVerts
; v
++, vx
+= md
->vertexSize
) {
215 const vector3 pos
= *((vector3
*)vx
) * mtx
;
216 for (int k
= 0; k
< 3; k
++) {
217 if (pos
[k
] < mins
[k
])
219 if (pos
[k
] > maxs
[k
])
227 for (sceneObject
*c
= mpChildren
; c
; c
= c
->mpNextChild
) {
228 const aab3
&b
= c
->getBoundingBox (true);
229 for (int k
= 0; k
< 3; k
++) {
230 if (b
.mins
[k
] < mins
[k
])
232 if (b
.maxs
[k
] > maxs
[k
])
236 mBBoxWithChildren
.mins
= mins
;
237 mBBoxWithChildren
.maxs
= maxs
;
240 const aab3
&sceneObject::getBoundingBox (bool withChildren
)
242 if (mFlags
& recalc_aab
) {
243 mFlags
&= ~recalc_aab
;
246 return withChildren
? mBBoxWithChildren
: mBBox
;