diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/gameengine/SceneGraph |
Initial revisionv2.25
Diffstat (limited to 'source/gameengine/SceneGraph')
-rw-r--r-- | source/gameengine/SceneGraph/Makefile | 41 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Controller.cpp | 49 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Controller.h | 116 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_IObject.cpp | 153 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_IObject.h | 220 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.cpp | 231 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.h | 208 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_ParentRelation.h | 116 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Spatial.cpp | 283 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Spatial.h | 205 |
10 files changed, 1622 insertions, 0 deletions
diff --git a/source/gameengine/SceneGraph/Makefile b/source/gameengine/SceneGraph/Makefile new file mode 100644 index 00000000000..bc184c8faba --- /dev/null +++ b/source/gameengine/SceneGraph/Makefile @@ -0,0 +1,41 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL 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. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# 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/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = scenegraph +DIR = $(OCGDIR)/gameengine/$(LIBNAME) + +include nan_compile.mk + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/SceneGraph/SG_Controller.cpp b/source/gameengine/SceneGraph/SG_Controller.cpp new file mode 100644 index 00000000000..4a5735bb4c0 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Controller.cpp @@ -0,0 +1,49 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include "SG_Controller.h" + + + void +SG_Controller:: +SetObject(SG_IObject* obj) +{ + m_pObject = obj; // no checks yet ? +} + + void +SG_Controller:: +ClearObject( +){ + m_pObject = NULL; +} + + diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h new file mode 100644 index 00000000000..9753af45a99 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Controller.h @@ -0,0 +1,116 @@ +/** + * Implementationclass to derive controllers from + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef __SG_CONTROLLER_H +#define __SG_CONTROLLER_H + + +#include "SG_IObject.h" +class SG_Controller +{ +public: + SG_Controller( + ) : + m_pObject(NULL) { + } + + virtual + ~SG_Controller( + ) {}; + + virtual + bool + Update( + double time + )=0; + + virtual + void + SetObject ( + SG_IObject* object + ); + + void + ClearObject( + ); + + virtual + void + SetSimulatedTime( + double time + )=0; + + virtual + SG_Controller* + GetReplica( + class SG_Node* destnode + )=0; + + /** + * Hacky way of passing options to specific controllers + * @param option An integer identifying the option. + * @param value The value of this option. + * @attention This has been placed here to give sca-elements + * @attention some control over the controllers. This is + * @attention necessary because the identity of the controller + * @attention is lost on the way here. + */ + virtual + void + SetOption( + int option, + int value + )=0; + + /** + * Option-identifiers: SG_CONTR_<controller-type>_<option>. + * Options only apply to a specific controller type. The + * semantics are defined by whoever uses the setting. + */ + enum SG_Controller_option { + SG_CONTR_NODEF = 0, + SG_CONTR_IPO_IPO_AS_FORCE, + SG_CONTR_IPO_FORCES_ACT_LOCAL, + SG_CONTR_CAMIPO_LENS, + SG_CONTR_CAMIPO_CLIPEND, + SG_CONTR_CAMIPO_CLIPSTART, + SG_CONTR_MAX + }; + +protected: + SG_IObject* m_pObject; + +}; + +#endif //__SG_CONTROLLER_H diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp new file mode 100644 index 00000000000..2561bd0c672 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_IObject.cpp @@ -0,0 +1,153 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include "SG_IObject.h" + +#include "SG_Controller.h" + +SG_IObject:: +SG_IObject( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks +): + m_SGclientObject(clientobj), + m_SGclientInfo(clientinfo), + m_callbacks(callbacks) +{ + //nothing to do +} + +SG_IObject:: +SG_IObject( + const SG_IObject &other +) : + m_SGclientObject(other.m_SGclientObject), + m_SGclientInfo(other.m_SGclientInfo), + m_callbacks(other.m_callbacks) +{ + //nothing to do +} + + void +SG_IObject:: +AddSGController( + SG_Controller* cont +){ + m_SGcontrollers.push_back(cont); +} + + void +SG_IObject:: +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; +} + + + void +SG_IObject:: +ActivateReplicationCallback( + SG_IObject *replica +){ + if (m_callbacks.m_replicafunc) + { + // Call client provided replication func + m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo); + } +}; + + 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); + } +} + + void +SG_IObject:: +SetControllerTime( + double time +){ + SGControllerList::iterator contit; + + for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit) + { + (*contit)->SetSimulatedTime(time); + } +} + + +SG_IObject:: +~SG_IObject() +{ + SGControllerList::iterator contit; + + for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit) + { + delete (*contit); + } +} diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h new file mode 100644 index 00000000000..f9066a9b340 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -0,0 +1,220 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __SG_IOBJECT +#define __SG_IOBJECT +/** +base object that can be part of the scenegraph. +*/ +#include <vector> + + +class SG_Controller; +class SG_IObject; + +typedef std::vector<SG_Controller*> SGControllerList; + +typedef void* (*SG_ReplicationNewCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + +typedef void* (*SG_DestructionNewCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + + +/** + * SG_Callbacks hold 2 call backs to the outside world. + * The first is meant to be called when objects are replicated. + * And allows the outside world to syncronise external objects + * with replicated nodes and their children. + * The second is called when a node is detroyed and again + * is their for synconisation purposes + * These callbacks may both be NULL. + * The efficacy of this approach has not been proved some + * alternatives might be to perform all replication and destruction + * externally. + * To define a class interface rather than a simple function + * call back so that replication information can be transmitted from + * parent->child. + */ +struct SG_Callbacks +{ + SG_Callbacks( + ): + m_replicafunc(NULL), + m_destructionfunc(NULL) + { + }; + + SG_Callbacks( + SG_ReplicationNewCallback repfunc, + SG_DestructionNewCallback destructfunc + ): + m_replicafunc(repfunc), + m_destructionfunc(destructfunc) + { + }; + + SG_ReplicationNewCallback m_replicafunc; + SG_DestructionNewCallback m_destructionfunc; +}; + +class SG_IObject +{ +private : + + void* m_SGclientObject; + void* m_SGclientInfo; + SG_Callbacks m_callbacks; + SGControllerList m_SGcontrollers; + +public: + + + virtual ~SG_IObject(); + + + /** + * Add a pointer to a controller allocated on the heap, to + * this node. This memory for this controller becomes the + * responsibility of this class. It will be deleted when + * this object is deleted. + */ + + void + AddSGController( + SG_Controller* cont + ); + + /** + * Clear the array of pointers to controllers associated with + * this node. This does not delete the controllers themselves! + * This should be used very carefully to avoid memory + * leaks. + */ + + void + RemoveAllControllers( + ); + + /// Needed for replication + + /** + * Return a reference to this node's controller list. + * Whilst we don't wish to expose full control of the container + * to the user we do allow them to call non_const methods + * on pointers in the container. C++ topic: how to do this in + * using STL? + */ + + SGControllerList& + GetSGControllerList( + ); + + + /** + * Get the client object associated with this + * node. This interface allows you to associate + * arbitray external objects with this node. They are + * passed to the callback functions when they are + * activated so you can syncronise these external objects + * upon replication and destruction + * This may be NULL. + */ + + void* + GetSGClientObject( + ); + + const + void* + GetSGClientObject( + ) const ; + + + /** + * Set the client object for this node. This is just a + * pointer to an object allocated that should exist for + * the duration of the lifetime of this object, or untill + * this function is called again. + */ + + void + SetSGClientObject( + void* clientObject + ); + + /** + * Set the current simulation time for this node. + * The implementation of this function runs through + * the nodes list of controllers and calls their SetSimulatedTime methods + */ + + void + SetControllerTime( + double time + ); + + virtual + void + Destruct( + ) = 0; + +protected : + + void + ActivateReplicationCallback( + SG_IObject *replica + ); + + void + ActivateDestructionCallback( + ); + + SG_IObject( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks + ); + + SG_IObject( + const SG_IObject &other + ); + + +}; + +#endif //__SG_IOBJECT diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp new file mode 100644 index 00000000000..d40cdca0c76 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -0,0 +1,231 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include "SG_Node.h" + +#include "SG_ParentRelation.h" + +#include <algorithm> + +using namespace std; + + +SG_Node::SG_Node( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks + +) + : SG_Spatial(clientobj,clientinfo,callbacks), + m_SGparent(NULL) +{ +} + +SG_Node::SG_Node( + const SG_Node & other +) : + SG_Spatial(other), + m_SGparent(other.m_SGparent), + m_children(other.m_children) +{ + // nothing to do +} + +SG_Node::~SG_Node() +{ +} + + +SG_Node* SG_Node::GetSGReplica() +{ + SG_Node* replica = new SG_Node(*this); + if (replica == NULL) return NULL; + + ProcessSGReplica(replica); + + return replica; +} + + void +SG_Node:: +ProcessSGReplica( + SG_Node* replica +){ + // Apply the replication call back function. + ActivateReplicationCallback(replica); + + // clear the replica node of it's parent. + static_cast<SG_Node*>(replica)->m_SGparent = NULL; + + if (m_children.begin() != m_children.end()) + { + // if this node has children, the replica has too, so clear and clone children + replica->ClearSGChildren(); + + NodeList::iterator childit; + for (childit = m_children.begin();childit!=m_children.end();++childit) + { + replica->AddChild((*childit)->GetSGReplica()); + } + } +} + + + void +SG_Node:: +Destruct() +{ + // Not entirely sure what Destruct() expects to happen. + // I think it probably means just to call the DestructionCallback + // in the right order on all the children - rather than free any memory + + // We'll delete m_parent_relation now anyway. + + delete(m_parent_relation); + m_parent_relation = NULL; + + if (m_children.begin() != m_children.end()) + { + NodeList::iterator childit; + for (childit = m_children.begin();childit!=m_children.end();++childit) + { + // call the SG_Node destruct method on each of our children }-) + (*childit)->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:: +GetRootSGParent( +) const { + return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); +} + + + void +SG_Node:: +DisconnectFromParent( +){ + if (m_SGparent) + { + m_SGparent->RemoveChild(this); + m_SGparent = NULL; + } + +} + + + +void SG_Node::AddChild(SG_Node* child) +{ + m_children.push_back(child); + child->SetSGParent(this); // this way ? +} + +void SG_Node::RemoveChild(SG_Node* child) +{ + NodeList::iterator childfound = find(m_children.begin(),m_children.end(),child); + + if (childfound != m_children.end()) + { + m_children.erase(childfound); + } +} + + + +void SG_Node::UpdateWorldData(double time) +{ + UpdateSpatialData(GetSGParent(),time); + + // update children's worlddata + for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it) + { + (*it)->UpdateWorldData(time); + } +} + + +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) +{ + + // update the controllers of this node. + SetControllerTime(time); + + // update children's simulate time. + if (recurse) + { + for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it) + { + (*it)->SetSimulatedTime(time,recurse); + } + } +} + diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h new file mode 100644 index 00000000000..a42afefcf1e --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -0,0 +1,208 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __SG_NODE_H +#define __SG_NODE_H + +#include "SG_Spatial.h" + +#include <vector> + +typedef std::vector<SG_Node*> NodeList; + +class SG_Node : public SG_Spatial +{ + +public: + + SG_Node( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks + ); + + SG_Node( + const SG_Node & other + ); + + virtual ~SG_Node(); + + + /** + * Add a child to this object. This also informs the child of + * it's parent. + * This just stores a pointer to the child and does not + * make a deep copy. + */ + + void + AddChild( + SG_Node* child + ); + + /** + * Remove a child node from this object. This just removes the child + * pointer from the list of children - it does not destroy the child. + * This does not inform the child that this node is no longer it's parent. + * If the node was not a child of this object no action is performed. + */ + + void + RemoveChild( + SG_Node* child + ); + + /** + * Get the current list of children. Do not use this interface for + * adding or removing children please use the methods of this class for + * that. + * @return a reference to the list of children of this node. + */ + + NodeList& + GetSGChildren( + ); + + /** + * Get the current list of children. + * @return a const reference to the current list of children of this node. + */ + + const + NodeList& + GetSGChildren( + ) const; + + /** + * Clear the list of children associated with this node + */ + + void + ClearSGChildren( + ); + + /** + * return the parent of this node if it exists. + */ + + SG_Node* + GetSGParent( + ) const ; + + + /** + * Set the parent of this node. + */ + + void + SetSGParent( + SG_Node* parent + ); + + /** + * Return the top node in this node's Scene graph hierarchy + */ + + const + SG_Node* + GetRootSGParent( + ) const; + + /** + * Disconnect this node from it's parent + */ + + void + DisconnectFromParent( + ); + + /** + * Tell this node to treat it's parent as a vertex parent. + */ + + void + SetVertexParent( + bool isvertexparent + ) ; + + + /** + * Update the spatial data of this node. Iterate through + * the children of this node and update their world data. + */ + + void + UpdateWorldData( + double time + ); + + /** + * Update the simulation time of this node. Iterate through + * the children nodes and update their simulated time. + */ + + void + SetSimulatedTime( + double time, + bool resurse + ); + + /** + * Node replication functions. + */ + + SG_Node* + GetSGReplica( + ); + + void + Destruct( + ); + +private: + + void + ProcessSGReplica( + SG_Node* replica + ); + + /** + * The list of children of this node. + */ + NodeList m_children; + + /** + * The parent of this node may be NULL + */ + SG_Node* m_SGparent; + +}; +#endif //__SG_NODE_H diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h new file mode 100644 index 00000000000..5df8efe7027 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_ParentRelation.h @@ -0,0 +1,116 @@ +/** + * @mainpage SG_ParentRelation + + * @section + * + * This is an abstract interface class to the Scene Graph library. + * It allows you to specify how child nodes react to parent nodes. + * Normally a child will use it's parent's transforms to compute + * it's own global transforms. How this is performed depends on + * the type of relation. For example if the parent is a vertex + * parent to this child then the child should not inherit any + * rotation information from the parent. Or if the parent is a + * 'slow parent' to this child then the child should react + * slowly to changes in the parent's position. The exact relation + * is left for you to implement by filling out this interface + * with concrete examples. + * + * There is exactly one SG_ParentRelation per SG_Node. Subclasses + * should not be value types and should be allocated on the heap. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + */ + +#ifndef __SG_ParentRelation_h +#define __SG_ParentRelation_h + +class SG_Spatial; + +class SG_ParentRelation { + +public : + + /** + * Update the childs local and global coordinates + * based upon the parents global coordinates. + * You must also handle the case when this node has no + * parent (parent == NULL). Usually you should just + * copy the local coordinates of the child to the + * world coordinates. + */ + + virtual + void + UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent + ) = 0; + + virtual + ~SG_ParentRelation( + ){ + }; + + /** + * You must provide a way of duplicating an + * instance of an SG_ParentRelation. This should + * return a pointer to a new duplicate allocated + * on the heap. Responsibilty for deleting the + * duplicate resides with the caller of this method. + */ + + virtual + SG_ParentRelation * + NewCopy( + ) = 0; + +protected : + + /** + * Protected constructors + * this class is not meant to be instantiated. + */ + + SG_ParentRelation( + ) { + }; + + /** + * Copy construction should not be implemented + */ + + SG_ParentRelation( + const SG_ParentRelation & + ); +}; + +#endif diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp new file mode 100644 index 00000000000..96370f28ef3 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -0,0 +1,283 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include "SG_Node.h" +#include "SG_Spatial.h" +#include "SG_Controller.h" +#include "SG_ParentRelation.h" + +SG_Spatial:: +SG_Spatial( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks +): + + SG_IObject(clientobj,clientinfo,callbacks), + m_localPosition(MT_Point3(0,0,0)), + m_localScaling(MT_Vector3(1.f,1.f,1.f)), + m_localRotation(1,0,0,0,1,0,0,0,1), + m_parent_relation (NULL), + + m_worldPosition(MT_Point3(0,0,0)), + m_worldScaling(MT_Vector3(1.f,1.f,1.f)), + m_worldRotation(0,0,0,0,0,0,0,0,0) + +{ +} + +SG_Spatial:: +SG_Spatial( + const SG_Spatial& other +) : + SG_IObject(other), + m_localPosition(other.m_localPosition), + m_localScaling(other.m_localScaling), + m_localRotation(other.m_localRotation), + m_parent_relation(NULL), + m_worldPosition(other.m_worldPosition), + m_worldScaling(other.m_worldScaling), + m_worldRotation(other.m_worldRotation) +{ + // duplicate the parent relation for this object + m_parent_relation = other.m_parent_relation->NewCopy(); +} + +SG_Spatial:: +~SG_Spatial() +{ + delete (m_parent_relation); +} + + void +SG_Spatial:: +SetParentRelation( + SG_ParentRelation *relation +){ + delete (m_parent_relation); + m_parent_relation = relation; +} + + +/** + * Update Spatial Data. + * Calculates WorldTransform., (either doing itsself or using the linked SGControllers) + */ + + + void +SG_Spatial:: +UpdateSpatialData( + const SG_Spatial *parent, + double time +){ + + bool bComputesWorldTransform = false; + + // update spatial controllers + + SGControllerList::iterator cit = GetSGControllerList().begin(); + SGControllerList::const_iterator c_end = GetSGControllerList().end(); + + for (;cit!=c_end;++cit) + { + bComputesWorldTransform = bComputesWorldTransform || (*cit)->Update(time); + } + + // If none of the objects updated our values then we ask the + // parent_relation object owned by this class to update + // our world coordinates. + + if (!bComputesWorldTransform) + { + ComputeWorldTransforms(parent); + } +} + +void SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent) +{ + m_parent_relation->UpdateChildCoordinates(this,parent); +} + + +/** + * Position and translation methods + */ + + + void +SG_Spatial:: +RelativeTranslate( + const MT_Vector3& trans, + const SG_Spatial *parent, + bool local +){ + if (local) { + m_localPosition += m_localRotation * trans; + } else { + if (parent) { + m_localPosition += trans * parent->GetWorldOrientation(); + } else { + m_localPosition += trans; + } + } +} + + void +SG_Spatial:: +SetLocalPosition( + const MT_Point3& trans +){ + m_localPosition = trans; +} + + 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; +} + + void +SG_Spatial:: +SetLocalScale( + const MT_Vector3& scale +){ + m_localScaling = scale; +} + + + void +SG_Spatial:: +SetWorldScale( + const MT_Vector3& scale +){ + m_worldScaling = scale; +} + +/** + * Orientation and rotation methods. + */ + + + void +SG_Spatial:: +RelativeRotate( + const MT_Matrix3x3& rot, + bool local +){ + m_localRotation = m_localRotation * ( + local ? + rot + : + (GetWorldOrientation().inverse() * rot * GetWorldOrientation())); +} + + void +SG_Spatial:: +SetLocalOrientation(const MT_Matrix3x3& rot) +{ + m_localRotation = rot; +} + + + + 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; +} + diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h new file mode 100644 index 00000000000..ff54c4055be --- /dev/null +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -0,0 +1,205 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef __SG_SPATIAL_H +#define __SG_SPATIAL_H + +#include <MT_Vector3.h> +#include <MT_Point3.h> +#include <MT_Matrix3x3.h> // or Quaternion later ? + +#include "SG_IObject.h" + +class SG_Node; +class SG_ParentRelation; + +class SG_Spatial : public SG_IObject +{ + +protected: + MT_Point3 m_localPosition; + MT_Matrix3x3 m_localRotation; + MT_Vector3 m_localScaling; + + MT_Point3 m_worldPosition; + MT_Matrix3x3 m_worldRotation; + MT_Vector3 m_worldScaling; + + SG_ParentRelation * m_parent_relation; + +public: + + /** + * Define the realtionship this node has with it's parent + * node. You should pass an unshared instance of an SG_ParentRelation + * allocated on the heap to this method. Ownership of this + * instance is assumed by this class. + * You may call this function several times in the lifetime + * of a node to change the relationship dynamically. + * You must call this method before the first call to UpdateSpatialData(). + * An assertion willl be fired at run-time in debug if this is not + * the case. + * The relation is activated only if no controllers of this object + * updated the coordinates of the child. + */ + + void + SetParentRelation( + SG_ParentRelation *relation + ); + + + /** + * Apply a translation relative to the current position. + * if local then the translation is assumed to be in the + * local coordinates of this object. If not then the translation + * is assumed to be in global coordinates. In this case + * you must provide a pointer to the parent of this object if it + * exists otherwise if there is no parent set it to NULL + */ + + void + RelativeTranslate( + const MT_Vector3& trans, + const SG_Spatial *parent, + bool local + ); + + void + SetLocalPosition( + const MT_Point3& trans + ); + + void + SetWorldPosition( + const MT_Point3& trans + ); + + void + RelativeRotate( + const MT_Matrix3x3& rot, + bool local + ); + + void + SetLocalOrientation( + const MT_Matrix3x3& rot + ); + + 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 ComputeWorldTransforms( const SG_Spatial *parent); + + +protected: + friend SG_Controller; + + /** + * Protected constructor this class is not + * designed for direct instantiation + */ + + SG_Spatial( + void* clientobj, + void* clientinfo, + SG_Callbacks callbacks + ); + + SG_Spatial( + const SG_Spatial& other + ); + + + virtual ~SG_Spatial(); + + /** + * Update the world coordinates of this spatial node. This also informs + * any controllers to update this object. + */ + + void + UpdateSpatialData( + const SG_Spatial *parent, + double time + ); + +}; +#endif //__SG_SPATIAL_H |