changed copyright years in source files
[fegdk.git] / core / code / system / f_sceneobject.cpp
blob48746668efb0065c6f78bf56c1a66947927c1384
1 /*
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
19 Alexey Yakovenko
20 waker@users.sourceforge.net
23 #include "pch.h"
24 #include "f_sceneobject.h"
25 #include "f_animation.h"
26 #include "f_engine.h"
27 #include "f_timer.h"
29 namespace fe
32 sceneObject::sceneObject (sceneObject *parent)
33 : mRelativeMatrix (true)
34 , mWorldMatrix (true)
35 , mInitPosInverseMatrix (true)
37 mpParentObject = parent;
38 mFlags = recalc_aab;
39 mpAnimatedChildren = NULL;
42 sceneObject::~sceneObject ()
44 if (mpAnimatedChildren)
45 delete[] mpAnimatedChildren;
48 matrix4 sceneObject::getWorldMatrix (void) const
50 return mWorldMatrix;
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);
71 mWorldMatrix = m;
74 void sceneObject::setRelativeMatrix (const matrix4 &m)
76 mFlags |= invalidate_children_tm;
77 mRelativeMatrix = m;
78 if (mpParentObject)
79 mWorldMatrix = mRelativeMatrix * mpParentObject->getWorldMatrix ();
80 else
81 mWorldMatrix = mRelativeMatrix;
84 void sceneObject::update (ulong updateFlags)
86 if (updateFlags & F_RECALC_MATRIX)
88 if (mpParentObject)
89 mWorldMatrix = mRelativeMatrix * mpParentObject->getWorldMatrix ();
90 else
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);
107 if (mpRenderable)
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;
115 obj->mName = mName;
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));
123 return obj;
126 sceneObject* sceneObject::getChildren (void) const
128 return mpChildren;
131 void sceneObject::addChild (sceneObject *child)
133 child->mpNextChild = mpChildren;
134 mpChildren = child;
137 void sceneObject::removeChild (sceneObject *child)
139 assert (mpChildren);
140 if (!mpChildren)
141 return;
143 if (mpChildren == child)
145 mpChildren = child->mpNextChild;
146 child->mpNextChild = NULL;
148 else
150 sceneObject *c = mpChildren;
152 while (c)
154 if (c->mpNextChild == child)
156 c->mpNextChild = child->mpNextChild;
157 child->mpNextChild = NULL;
158 break;
164 sceneObject* sceneObject::getNextChild (void) const
166 return mpNextChild;
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))
177 lst[i] = obj;
178 break;
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);
206 if (mpRenderable) {
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])
218 mins[k] = pos[k];
219 if (pos[k] > maxs[k])
220 maxs[k] = pos[k];
225 mBBox.mins = mins;
226 mBBox.maxs = maxs;
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])
231 mins[k] = b.mins[k];
232 if (b.maxs[k] > maxs[k])
233 maxs[k] = b.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;
244 calcAAB ();
246 return withChildren ? mBBoxWithChildren : mBBox;