diff options
Diffstat (limited to 'source/gameengine/SceneGraph')
-rw-r--r-- | source/gameengine/SceneGraph/SG_DList.h | 161 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_IObject.cpp | 92 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_IObject.h | 136 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.cpp | 66 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.h | 113 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_QList.h | 157 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Spatial.cpp | 151 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Spatial.h | 191 |
8 files changed, 649 insertions, 418 deletions
diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h new file mode 100644 index 00000000000..7bef13cc9e3 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -0,0 +1,161 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_DLIST +#define __SG_DLIST + +#include <stdlib.h> + +/** + * Double circular linked list + */ +class SG_DList +{ +protected : + SG_DList* m_flink; + SG_DList* m_blink; + +public: + template<typename T> class iterator + { + private: + SG_DList& m_head; + T* m_current; + public: + typedef iterator<T> _myT; + iterator(SG_DList& head) : m_head(head), m_current(NULL) {} + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.Peek(); + } + void back() + { + m_current = (T*)m_head.Back(); + } + bool end() + { + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->AddBack(item); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + // no check of NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->Peek(); + return *this; + } + _myT& operator--() + { + // no check of NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->Back(); + return *this; + } + }; + + SG_DList() + { + m_flink = m_blink = this; + } + SG_DList(const SG_DList& other) + { + m_flink = m_blink = this; + } + virtual ~SG_DList() + { + Delink(); + } + + inline bool Empty() // Check for empty queue + { + return ( m_flink == this ); + } + bool AddBack( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_blink = m_blink; + item->m_flink = this; + m_blink->m_flink = item; + m_blink = item; + return true; + } + bool AddFront( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_flink = m_flink; + item->m_blink = this; + m_flink->m_blink = item; + m_flink = item; + return true; + } + SG_DList *Remove() // Remove from the front + { + if (Empty()) + { + return NULL; + } + SG_DList* item = m_flink; + m_flink = item->m_flink; + m_flink->m_blink = this; + item->m_flink = item->m_blink = item; + return item; + } + bool Delink() // Remove from the middle + { + if (Empty()) + return false; + m_blink->m_flink = m_flink; + m_flink->m_blink = m_blink; + m_flink = m_blink = this; + return true; + } + inline SG_DList *Peek() // Look at front without removing + { + return m_flink; + } + inline SG_DList *Back() // Look at front without removing + { + return m_blink; + } + inline SG_DList *Self() + { + return this; + } +}; + +#endif //__SG_DLIST + diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp index fbab4032a10..5795ca57113 100644 --- a/source/gameengine/SceneGraph/SG_IObject.cpp +++ b/source/gameengine/SceneGraph/SG_IObject.cpp @@ -39,19 +39,20 @@ SG_IObject:: SG_IObject( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ): + SG_QList(), m_SGclientObject(clientobj), - m_SGclientInfo(clientinfo), - m_callbacks(callbacks) + m_SGclientInfo(clientinfo) { - //nothing to do + m_callbacks = callbacks; } SG_IObject:: SG_IObject( const SG_IObject &other ) : + SG_QList(), m_SGclientObject(other.m_SGclientObject), m_SGclientInfo(other.m_SGclientInfo), m_callbacks(other.m_callbacks) @@ -74,92 +75,17 @@ RemoveAllControllers( m_SGcontrollers.clear(); } -/// Needed for replication - SGControllerList& -SG_IObject:: -GetSGControllerList( -){ - return m_SGcontrollers; -} - - void* -SG_IObject:: -GetSGClientObject( -){ - return m_SGclientObject; -} - -const - void* -SG_IObject:: -GetSGClientObject( -) const { - return m_SGclientObject; -} - - void -SG_IObject:: -SetSGClientObject( - void* clientObject -){ - m_SGclientObject = clientObject; -} - - - bool -SG_IObject:: -ActivateReplicationCallback( - SG_IObject *replica -){ - if (m_callbacks.m_replicafunc) - { - // Call client provided replication func - if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL) - return false; - } - return true; -}; - - void -SG_IObject:: -ActivateDestructionCallback( -){ - if (m_callbacks.m_destructionfunc) - { - // Call client provided destruction function on this! - m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo); - } - else - { - // no callback but must still destroy the node to avoid memory leak - delete this; - } -} - - void -SG_IObject:: -ActivateUpdateTransformCallback( -){ - if (m_callbacks.m_updatefunc) - { - // Call client provided update func. - m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo); - } -} - - void -SG_IObject:: -SetControllerTime( - double time -){ +void SG_IObject::SetControllerTime(double time) +{ SGControllerList::iterator contit; - for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit) { (*contit)->SetSimulatedTime(time); } } +/// Needed for replication + SG_IObject:: ~SG_IObject() diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 9012b532059..8f448a0e890 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -29,6 +29,7 @@ #ifndef __SG_IOBJECT #define __SG_IOBJECT +#include "SG_QList.h" #include <vector> // used for debugging: stage of the game engine main loop at which a Scenegraph modification is done @@ -84,6 +85,18 @@ typedef void (*SG_UpdateTransformCallback)( void* clientinfo ); +typedef bool (*SG_ScheduleUpdateCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + +typedef bool (*SG_RescheduleUpdateCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + /** * SG_Callbacks hold 2 call backs to the outside world. @@ -106,30 +119,38 @@ struct SG_Callbacks ): m_replicafunc(NULL), m_destructionfunc(NULL), - m_updatefunc(NULL) + m_updatefunc(NULL), + m_schedulefunc(NULL), + m_reschedulefunc(NULL) { }; SG_Callbacks( SG_ReplicationNewCallback repfunc, SG_DestructionNewCallback destructfunc, - SG_UpdateTransformCallback updatefunc + SG_UpdateTransformCallback updatefunc, + SG_ScheduleUpdateCallback schedulefunc, + SG_RescheduleUpdateCallback reschedulefunc ): m_replicafunc(repfunc), m_destructionfunc(destructfunc), - m_updatefunc(updatefunc) + m_updatefunc(updatefunc), + m_schedulefunc(schedulefunc), + m_reschedulefunc(reschedulefunc) { }; SG_ReplicationNewCallback m_replicafunc; SG_DestructionNewCallback m_destructionfunc; SG_UpdateTransformCallback m_updatefunc; + SG_ScheduleUpdateCallback m_schedulefunc; + SG_RescheduleUpdateCallback m_reschedulefunc; }; /** base object that can be part of the scenegraph. */ -class SG_IObject +class SG_IObject : public SG_QList { private : @@ -177,10 +198,18 @@ public: * using STL? */ - SGControllerList& - GetSGControllerList( - ); + SGControllerList& GetSGControllerList() + { + return m_SGcontrollers; + } + /** + * + */ + SG_Callbacks& GetCallBackFunctions() + { + return m_callbacks; + } /** * Get the client object associated with this @@ -192,16 +221,16 @@ public: * This may be NULL. */ - void* - GetSGClientObject( - ); + inline const void* GetSGClientObject() const + { + return m_SGclientObject; + } - const - void* - GetSGClientObject( - ) const ; + inline void* GetSGClientObject() + { + return m_SGclientObject; + } - /** * Set the client object for this node. This is just a * pointer to an object allocated that should exist for @@ -209,10 +238,10 @@ public: * this function is called again. */ - void - SetSGClientObject( - void* clientObject - ); + void SetSGClientObject(void* clientObject) + { + m_SGclientObject = clientObject; + } /** * Set the current simulation time for this node. @@ -220,10 +249,7 @@ public: * the nodes list of controllers and calls their SetSimulatedTime methods */ - void - SetControllerTime( - double time - ); + void SetControllerTime(double time); virtual void @@ -235,20 +261,76 @@ protected : bool ActivateReplicationCallback( SG_IObject *replica - ); + ) + { + if (m_callbacks.m_replicafunc) + { + // Call client provided replication func + if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL) + return false; + } + return true; + } + void ActivateDestructionCallback( - ); + ) + { + if (m_callbacks.m_destructionfunc) + { + // Call client provided destruction function on this! + m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo); + } + else + { + // no callback but must still destroy the node to avoid memory leak + delete this; + } + } void ActivateUpdateTransformCallback( - ); + ) + { + if (m_callbacks.m_updatefunc) + { + // Call client provided update func. + m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo); + } + } + + bool + ActivateScheduleUpdateCallback( + ) + { + // HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h) + // The early check on Empty() allows up to avoid calling the callback function + // when the node is already scheduled for update. + if (Empty() && m_callbacks.m_schedulefunc) + { + // Call client provided update func. + return m_callbacks.m_schedulefunc(this, m_SGclientObject, m_SGclientInfo); + } + return false; + } + + void + ActivateRecheduleUpdateCallback( + ) + { + if (m_callbacks.m_reschedulefunc) + { + // Call client provided update func. + m_callbacks.m_reschedulefunc(this, m_SGclientObject, m_SGclientInfo); + } + } + SG_IObject( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_IObject( diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index 64d9019c86a..4cd43e852b8 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -40,12 +40,13 @@ using namespace std; SG_Node::SG_Node( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ) : SG_Spatial(clientobj,clientinfo,callbacks), m_SGparent(NULL) { + m_modified = true; } SG_Node::SG_Node( @@ -55,7 +56,7 @@ SG_Node::SG_Node( m_children(other.m_children), m_SGparent(other.m_SGparent) { - // nothing to do + m_modified = true; } SG_Node::~SG_Node() @@ -141,22 +142,6 @@ Destruct() ActivateDestructionCallback(); } - - SG_Node* -SG_Node:: -GetSGParent( -) const { - return m_SGparent; -} - - void -SG_Node:: -SetSGParent( - SG_Node* parent -){ - m_SGparent = parent; -} - const SG_Node* SG_Node:: @@ -165,28 +150,6 @@ GetRootSGParent( return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); } - bool -SG_Node:: -IsVertexParent() -{ - if (m_parent_relation) - { - return m_parent_relation->IsVertexRelation(); - } - return false; -} - - bool -SG_Node:: -IsSlowParent() -{ - if (m_parent_relation) - { - return m_parent_relation->IsSlowRelation(); - } - return false; -} - void SG_Node:: DisconnectFromParent( @@ -199,8 +162,6 @@ DisconnectFromParent( } - - void SG_Node::AddChild(SG_Node* child) { m_children.push_back(child); @@ -228,6 +189,9 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated) // to update the ActivateUpdateTransformCallback(); + // The node is updated, remove it from the update list + Delink(); + // update children's worlddata for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it) { @@ -236,24 +200,6 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated) } -NodeList& SG_Node::GetSGChildren() -{ - return this->m_children; -} - - -const NodeList& SG_Node::GetSGChildren() const -{ - return this->m_children; -} - - -void SG_Node::ClearSGChildren() -{ - m_children.clear(); -} - - void SG_Node::SetSimulatedTime(double time,bool recurse) { diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 29943653a81..7c6ef92f670 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -44,7 +44,7 @@ public: SG_Node( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_Node( @@ -85,45 +85,47 @@ public: * @return a reference to the list of children of this node. */ - NodeList& - GetSGChildren( - ); + NodeList& GetSGChildren() + { + return this->m_children; + } /** * Get the current list of children. * @return a const reference to the current list of children of this node. */ - const - NodeList& - GetSGChildren( - ) const; + const NodeList& GetSGChildren() const + { + return this->m_children; + } /** * Clear the list of children associated with this node */ - void - ClearSGChildren( - ); + void ClearSGChildren() + { + m_children.clear(); + } /** * return the parent of this node if it exists. */ - SG_Node* - GetSGParent( - ) const ; - + SG_Node* GetSGParent() const + { + return m_SGparent; + } /** * Set the parent of this node. */ - void - SetSGParent( - SG_Node* parent - ); + void SetSGParent(SG_Node* parent) + { + m_SGparent = parent; + } /** * Return the top node in this node's Scene graph hierarchy @@ -143,30 +145,33 @@ public: ); /** - * Tell this node to treat it's parent as a vertex parent. - */ - - void - SetVertexParent( - bool isvertexparent - ) ; - - - /** * Return vertex parent status. */ + bool IsVertexParent() + { + if (m_parent_relation) + { + return m_parent_relation->IsVertexRelation(); + } + return false; + } + - bool - IsVertexParent( - ) ; - /** * Return slow parent status. */ - bool - IsSlowParent( - ) ; + bool IsSlowParent() + { + if (m_parent_relation) + { + return m_parent_relation->IsSlowRelation(); + } + return false; + } + + + /** * Update the spatial data of this node. Iterate through @@ -191,6 +196,42 @@ public: ); /** + * Schedule this node for update by placing it in head queue + */ + bool Schedule(SG_QList& head) + { + // Put top parent in front of list to make sure they are updated before their + // children => the children will be udpated and removed from the list before + // we get to them, should they be in the list too. + return (m_SGparent)?head.AddBack(this):head.AddFront(this); + } + + /** + * Used during Scenegraph update + */ + static SG_Node* GetNextScheduled(SG_QList& head) + { + return static_cast<SG_Node*>(head.Remove()); + } + + /** + * Make this node ready for schedule on next update. This is needed for nodes + * that must always be updated (slow parent, bone parent) + */ + bool Reschedule(SG_QList& head) + { + return head.QAddBack(this); + } + + /** + * Used during Scenegraph update + */ + static SG_Node* GetNextRescheduled(SG_QList& head) + { + return static_cast<SG_Node*>(head.QRemove()); + } + + /** * Node replication functions. */ diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h new file mode 100644 index 00000000000..d8afc33ea4f --- /dev/null +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -0,0 +1,157 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_QLIST +#define __SG_QLIST + +#include "SG_DList.h" + +/** + * Double-Double circular linked list + * For storing an object is two lists simultaneously + */ +class SG_QList : public SG_DList +{ +protected : + SG_QList* m_fqlink; + SG_QList* m_bqlink; + +public: + template<typename T> class iterator + { + private: + SG_QList& m_head; + T* m_current; + public: + typedef iterator<T> _myT; + iterator(SG_QList& head, SG_QList* current=NULL) : m_head(head) { m_current = (T*)current; } + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.QPeek(); + } + void back() + { + m_current = (T*)m_head.QBack(); + } + bool end() + { + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->QAddBack(item); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + m_current = (T*)m_current->QPeek(); + return *this; + } + _myT& operator--() + { + // no check on NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->QBack(); + return *this; + } + }; + + SG_QList() : SG_DList() + { + m_fqlink = m_bqlink = this; + } + SG_QList(const SG_QList& other) : SG_DList() + { + m_fqlink = m_bqlink = this; + } + virtual ~SG_QList() + { + QDelink(); + } + + inline bool QEmpty() // Check for empty queue + { + return ( m_fqlink == this ); + } + bool QAddBack( SG_QList *item ) // Add to the back + { + if (!item->QEmpty()) + return false; + item->m_bqlink = m_bqlink; + item->m_fqlink = this; + m_bqlink->m_fqlink = item; + m_bqlink = item; + return true; + } + bool QAddFront( SG_QList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_fqlink = m_fqlink; + item->m_bqlink = this; + m_fqlink->m_bqlink = item; + m_fqlink = item; + return true; + } + SG_QList *QRemove() // Remove from the front + { + if (QEmpty()) + { + return NULL; + } + SG_QList* item = m_fqlink; + m_fqlink = item->m_fqlink; + m_fqlink->m_bqlink = this; + item->m_fqlink = item->m_bqlink = item; + return item; + } + bool QDelink() // Remove from the middle + { + if (QEmpty()) + return false; + m_bqlink->m_fqlink = m_fqlink; + m_fqlink->m_bqlink = m_bqlink; + m_fqlink = m_bqlink = this; + return true; + } + inline SG_QList *QPeek() // Look at front without removing + { + return m_fqlink; + } + inline SG_QList *QBack() // Look at front without removing + { + return m_bqlink; + } +}; + +#endif //__SG_QLIST + diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index 2f3176816c6..5a47f07f573 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -40,7 +40,7 @@ SG_Spatial:: SG_Spatial( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ): SG_IObject(clientobj,clientinfo,callbacks), @@ -56,7 +56,8 @@ SG_Spatial( m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)), m_radius(1.0), - m_modified(true) + m_modified(false), + m_ogldirty(false) { } @@ -76,7 +77,9 @@ SG_Spatial( m_parent_relation(NULL), m_bbox(other.m_bbox), - m_radius(other.m_radius) + m_radius(other.m_radius), + m_modified(false), + m_ogldirty(false) { // duplicate the parent relation for this object m_parent_relation = other.m_parent_relation->NewCopy(); @@ -88,13 +91,6 @@ SG_Spatial:: delete (m_parent_relation); } - SG_ParentRelation * -SG_Spatial:: -GetParentRelation( -){ - return m_parent_relation; -} - void SG_Spatial:: SetParentRelation( @@ -102,7 +98,7 @@ SetParentRelation( ){ delete (m_parent_relation); m_parent_relation = relation; - m_modified = true; + SetModified(); } @@ -143,11 +139,6 @@ UpdateSpatialData( return bComputesWorldTransform; } -bool SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated) -{ - return m_parent_relation->UpdateChildCoordinates(this,parent,parentUpdated); -} - /** * Position and translation methods */ @@ -169,56 +160,14 @@ RelativeTranslate( m_localPosition += trans; } } - m_modified = true; + SetModified(); } - void -SG_Spatial:: -SetLocalPosition( - const MT_Point3& trans -){ - m_localPosition = trans; - m_modified = true; -} - - void -SG_Spatial:: -SetWorldPosition( - const MT_Point3& trans -) { - m_worldPosition = trans; -} /** * Scaling methods. */ - void -SG_Spatial:: -RelativeScale( - const MT_Vector3& scale -){ - m_localScaling = m_localScaling * scale; - m_modified = true; -} - - void -SG_Spatial:: -SetLocalScale( - const MT_Vector3& scale -){ - m_localScaling = scale; - m_modified = true; -} - - - void -SG_Spatial:: -SetWorldScale( - const MT_Vector3& scale -){ - m_worldScaling = scale; -} /** * Orientation and rotation methods. @@ -236,93 +185,11 @@ RelativeRotate( rot : (GetWorldOrientation().inverse() * rot * GetWorldOrientation())); - m_modified = true; -} - - void -SG_Spatial:: -SetLocalOrientation(const MT_Matrix3x3& rot) -{ - m_localRotation = rot; - m_modified = true; + SetModified(); } - void -SG_Spatial:: -SetWorldOrientation( - const MT_Matrix3x3& rot -) { - m_worldRotation = rot; -} - -const - MT_Point3& -SG_Spatial:: -GetLocalPosition( -) const { - return m_localPosition; -} - -const - MT_Matrix3x3& -SG_Spatial:: -GetLocalOrientation( -) const { - return m_localRotation; -} - -const - MT_Vector3& -SG_Spatial:: -GetLocalScale( -) const{ - return m_localScaling; -} - - -const - MT_Point3& -SG_Spatial:: -GetWorldPosition( -) const { - return m_worldPosition; -} - -const - MT_Matrix3x3& -SG_Spatial:: -GetWorldOrientation( -) const { - return m_worldRotation; -} - -const - MT_Vector3& -SG_Spatial:: -GetWorldScaling( -) const { - return m_worldScaling; -} - -void SG_Spatial::SetWorldFromLocalTransform() -{ - m_worldPosition= m_localPosition; - m_worldScaling= m_localScaling; - m_worldRotation= m_localRotation; -} - -SG_BBox& SG_Spatial::BBox() -{ - return m_bbox; -} - -void SG_Spatial::SetBBox(SG_BBox& bbox) -{ - m_bbox = bbox; -} - MT_Transform SG_Spatial::GetWorldTransform() const { return MT_Transform(m_worldPosition, diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index c2ed80d21b2..6e274487c9d 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -35,6 +35,7 @@ #include <MT_Matrix3x3.h> // or Quaternion later ? #include "SG_IObject.h" #include "SG_BBox.h" +#include "SG_ParentRelation.h" class SG_Node; @@ -62,9 +63,24 @@ protected: SG_BBox m_bbox; MT_Scalar m_radius; bool m_modified; + bool m_ogldirty; // true if the openGL matrix for this object must be recomputed public: + inline void ClearModified() + { + m_modified = false; + m_ogldirty = true; + } + inline void SetModified() + { + m_modified = true; + ActivateScheduleUpdateCallback(); + } + inline void ClearDirty() + { + m_ogldirty = false; + } /** * Define the realtionship this node has with it's parent * node. You should pass an unshared instance of an SG_ParentRelation @@ -84,9 +100,12 @@ public: SG_ParentRelation *relation ); - SG_ParentRelation * - GetParentRelation( - ); + SG_ParentRelation * GetParentRelation() + { + return m_parent_relation; + } + + /** @@ -105,15 +124,17 @@ public: bool local ); - void - SetLocalPosition( - const MT_Point3& trans - ); + void SetLocalPosition(const MT_Point3& trans) + { + m_localPosition = trans; + SetModified(); + } + + void SetWorldPosition(const MT_Point3& trans) + { + m_worldPosition = trans; + } - void - SetWorldPosition( - const MT_Point3& trans - ); void RelativeRotate( @@ -121,72 +142,102 @@ public: bool local ); - void - SetLocalOrientation( - const MT_Matrix3x3& rot - ); + void SetLocalOrientation(const MT_Matrix3x3& rot) + { + m_localRotation = rot; + SetModified(); + } + + // rot is arrange like openGL matrix + void SetLocalOrientation(const float* rot) + { + m_localRotation.setValue(rot); + SetModified(); + } + + void SetWorldOrientation(const MT_Matrix3x3& rot) + { + m_worldRotation = rot; + } + + void RelativeScale(const MT_Vector3& scale) + { + m_localScaling = m_localScaling * scale; + SetModified(); + } + + void SetLocalScale(const MT_Vector3& scale) + { + m_localScaling = scale; + SetModified(); + } + + void SetWorldScale(const MT_Vector3& scale) + { + m_worldScaling = scale; + } + + const MT_Point3& GetLocalPosition() const + { + return m_localPosition; + } + + const MT_Matrix3x3& GetLocalOrientation() const + { + return m_localRotation; + } + + const MT_Vector3& GetLocalScale() const + { + return m_localScaling; + } + + const MT_Point3& GetWorldPosition() const + { + return m_worldPosition; + } + + const MT_Matrix3x3& GetWorldOrientation() const + { + return m_worldRotation; + } + + const MT_Vector3& GetWorldScaling() const + { + return m_worldScaling; + } + + void SetWorldFromLocalTransform() + { + m_worldPosition= m_localPosition; + m_worldScaling= m_localScaling; + m_worldRotation= m_localRotation; + } - void - SetWorldOrientation( - const MT_Matrix3x3& rot - ); - void - RelativeScale( - const MT_Vector3& scale - ); - - void - SetLocalScale( - const MT_Vector3& scale - ); - - void - SetWorldScale( - const MT_Vector3& scale - ); - - const - MT_Point3& - GetLocalPosition( - ) const ; - - const - MT_Matrix3x3& - GetLocalOrientation( - ) const ; - - const - MT_Vector3& - GetLocalScale( - ) const; - - const - MT_Point3& - GetWorldPosition( - ) const ; - - const - MT_Matrix3x3& - GetWorldOrientation( - ) const ; - - const - MT_Vector3& - GetWorldScaling( - ) const ; - - void SetWorldFromLocalTransform(); MT_Transform GetWorldTransform() const; - bool ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated); + bool ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated) + { + return m_parent_relation->UpdateChildCoordinates(this,parent,parentUpdated); + } + /** * Bounding box functions. */ - SG_BBox& BBox(); - void SetBBox(SG_BBox & bbox); + SG_BBox& BBox() + { + return m_bbox; + } + + void SetBBox(SG_BBox& bbox) + { + m_bbox = bbox; + } + + bool inside(const MT_Point3 &point) const; void getBBox(MT_Point3 *box) const; void getAABBox(MT_Point3 *box) const; @@ -194,6 +245,7 @@ public: MT_Scalar Radius() const { return m_radius; } void SetRadius(MT_Scalar radius) { m_radius = radius; } bool IsModified() { return m_modified; } + bool IsDirty() { return m_ogldirty; } protected: friend class SG_Controller; @@ -210,7 +262,7 @@ protected: SG_Spatial( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_Spatial( @@ -231,7 +283,6 @@ protected: double time, bool& parentUpdated ); - void SetModified(bool modified) { m_modified = modified; } }; |