mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-09 23:40:42 +00:00
truly a community project, this has been kicking around since 2003 in various forms. adds a path following shape that can be ridden.
This commit is contained in:
parent
f007700646
commit
f7f8faf47e
14 changed files with 1399 additions and 8 deletions
|
|
@ -149,6 +149,13 @@ SceneObject::SceneObject()
|
|||
mSceneObjectLinks = NULL;
|
||||
|
||||
mObjectFlags.set( RenderEnabledFlag | SelectionEnabledFlag );
|
||||
// PATHSHAPE
|
||||
// init the scenegraph relationships to indicate no parent, no children, and no siblings
|
||||
mGraph.parent = NULL;
|
||||
mGraph.nextSibling = NULL;
|
||||
mGraph.firstChild = NULL;
|
||||
mGraph.objToParent.identity();
|
||||
// PATHSHAPE END
|
||||
mIsScopeAlways = false;
|
||||
|
||||
mAccuTex = NULL;
|
||||
|
|
@ -330,6 +337,9 @@ void SceneObject::onRemove()
|
|||
plUnlink();
|
||||
|
||||
Parent::onRemove();
|
||||
// PATHSHAPE
|
||||
if ( getParent() != NULL) attachToParent( NULL);
|
||||
// PATHSHAPE END
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -402,6 +412,9 @@ void SceneObject::setTransform( const MatrixF& mat )
|
|||
#endif
|
||||
|
||||
PROFILE_SCOPE( SceneObject_setTransform );
|
||||
// PATHSHAPE
|
||||
PerformUpdatesForChildren(mat);
|
||||
// PATHSHAPE END
|
||||
|
||||
// Update the transforms.
|
||||
|
||||
|
|
@ -876,6 +889,36 @@ U32 SceneObject::packUpdate( NetConnection* conn, U32 mask, BitStream* stream )
|
|||
if ( stream->writeFlag( mask & FlagMask ) )
|
||||
stream->writeRangedU32( (U32)mObjectFlags, 0, getObjectFlagMax() );
|
||||
|
||||
// PATHSHAPE
|
||||
//Begin attachment
|
||||
retMask = 0; //retry mask
|
||||
|
||||
if (stream->writeFlag(getParent() != NULL)) {
|
||||
stream->writeAffineTransform(mGraph.objToParent);
|
||||
}
|
||||
if (stream->writeFlag(mask & MountedMask))
|
||||
{
|
||||
// Check to see if we need to write an object ID
|
||||
if (stream->writeFlag(mGraph.parent)) {
|
||||
S32 t = conn->getGhostIndex(mGraph.parent);
|
||||
// Check to see if we can actually ghost this...
|
||||
if (t == -1) {
|
||||
// Cant, try again later
|
||||
retMask |= MountedMask;
|
||||
stream->writeFlag(false);
|
||||
}
|
||||
else {
|
||||
// Can, write it.
|
||||
stream->writeFlag(true);
|
||||
stream->writeRangedU32(U32(t), 0, NetConnection::MaxGhostCount);
|
||||
stream->writeAffineTransform(mGraph.objToParent);
|
||||
//Con::errorf("%d: sent mounted on %d", getId(), mGraph.parent->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of Attachment
|
||||
// PATHSHAPE END
|
||||
|
||||
if ( mask & MountedMask )
|
||||
{
|
||||
if ( mMount.object )
|
||||
|
|
@ -915,6 +958,44 @@ void SceneObject::unpackUpdate( NetConnection* conn, BitStream* stream )
|
|||
if ( stream->readFlag() )
|
||||
mObjectFlags = stream->readRangedU32( 0, getObjectFlagMax() );
|
||||
|
||||
// PATHSHAPE
|
||||
// begin of attachment
|
||||
if (stream->readFlag())
|
||||
{
|
||||
MatrixF m;
|
||||
stream->readAffineTransform(&m);
|
||||
mGraph.objToParent = m;
|
||||
}
|
||||
if (stream->readFlag())
|
||||
{
|
||||
// Check to see if we need to read an object ID
|
||||
if (stream->readFlag())
|
||||
{
|
||||
// Check to see if we can actually ghost this...
|
||||
if (stream->readFlag())
|
||||
{
|
||||
GameBase *newParent = static_cast<GameBase*>(conn->resolveGhost(stream->readRangedU32(0, NetConnection::MaxGhostCount)));
|
||||
MatrixF m;
|
||||
stream->readAffineTransform(&m);
|
||||
|
||||
if (getParent() != newParent)
|
||||
{
|
||||
clearProcessAfter();
|
||||
processAfter(newParent);
|
||||
}
|
||||
|
||||
attachToParent(newParent, &m);
|
||||
//Con::errorf("%d: got mounted on %d", getId(), mParentObject->getId());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attachToParent(NULL);
|
||||
}
|
||||
}
|
||||
// End of attachment
|
||||
// PATHSHAPE END
|
||||
|
||||
// MountedMask
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
|
|
@ -1479,6 +1560,9 @@ DefineEngineMethod( SceneObject, setTransform, void, ( TransformF txfm ),,
|
|||
"Set the object's transform (orientation and position)."
|
||||
"@param txfm object transform to set" )
|
||||
{
|
||||
// PATHSHAPE
|
||||
object->PerformUpdatesForChildren(txfm.getMatrix());
|
||||
// PATHSHAPE END
|
||||
if ( !txfm.hasRotation() )
|
||||
object->setPosition( txfm.getPosition() );
|
||||
else
|
||||
|
|
@ -1552,3 +1636,356 @@ DefineEngineMethod(SceneObject, setForwardVector, void, (VectorF newForward, Vec
|
|||
{
|
||||
object->setForwardVector(newForward, upVector);
|
||||
}
|
||||
|
||||
// PATHSHAPE
|
||||
// Move RenderTransform by set amount
|
||||
// no longer used
|
||||
|
||||
void SceneObject::moveRender(const Point3F &delta)
|
||||
{
|
||||
Point3F pos;
|
||||
|
||||
const MatrixF& tmat = getRenderTransform();
|
||||
tmat.getColumn(3,&pos);
|
||||
AngAxisF aa(tmat);
|
||||
pos += delta;
|
||||
|
||||
MatrixF mat;
|
||||
aa.setMatrix(&mat);
|
||||
mat.setColumn(3,pos);
|
||||
setRenderTransform(mat);
|
||||
}
|
||||
|
||||
void SceneObject::PerformUpdatesForChildren(MatrixF mat){
|
||||
UpdateXformChange(mat);
|
||||
for (U32 i=0; i < getNumChildren(); i++) {
|
||||
SceneObject *o = getChild(i);
|
||||
o->updateChildTransform(); //update the position of the child object
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// This function will move the players based on how much it's
|
||||
// parent have moved
|
||||
void SceneObject::updateChildTransform(){
|
||||
if (getParent() != NULL){
|
||||
MatrixF one;
|
||||
MatrixF two;
|
||||
MatrixF three;
|
||||
MatrixF four;
|
||||
MatrixF mat;
|
||||
one= getTransform();
|
||||
two = getParent()->getTransform();
|
||||
one.affineInverse();
|
||||
four.mul(two,one);
|
||||
mat.mul(getParent()->mLastXform,getTransform());
|
||||
setTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
// This function will move the rendered image based on how much it's
|
||||
// parent have moved since the processtick.
|
||||
// For some reason the player object must be updated via it's GetRenderTransform seen below,
|
||||
// Other objects seem to require getTransform() only
|
||||
void SceneObject::updateRenderChangesByParent(){
|
||||
if (getParent() != NULL){
|
||||
MatrixF renderXform = getParent()->getRenderTransform();
|
||||
MatrixF xform = getParent()->getTransform();
|
||||
xform.affineInverse();
|
||||
|
||||
MatrixF offset;
|
||||
offset.mul(renderXform, xform);
|
||||
|
||||
MatrixF mat;
|
||||
|
||||
//add the "offset" caused by the parents change, and add it to it's own
|
||||
// This is needed by objects that update their own render transform thru interpolate tick
|
||||
// Mostly for stationary objects.
|
||||
|
||||
if (getClassName() == "Player")
|
||||
mat.mul(offset,getRenderTransform());
|
||||
else
|
||||
mat.mul(offset,getTransform());
|
||||
setRenderTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Ramen - Move Transform by set amount
|
||||
//written by Anthony Lovell
|
||||
void SceneObject::move(F32 x, F32 y, F32 z)
|
||||
{
|
||||
Point3F delta;
|
||||
delta.x = x;
|
||||
delta.y = y;
|
||||
delta.z = z;
|
||||
move(delta);
|
||||
}
|
||||
// move by a specified delta in root coordinate space
|
||||
void SceneObject::move(const Point3F &delta)
|
||||
{
|
||||
Point3F pos;
|
||||
|
||||
const MatrixF& tmat = getTransform();
|
||||
tmat.getColumn(3,&pos);
|
||||
AngAxisF aa(tmat);
|
||||
|
||||
pos += delta;
|
||||
|
||||
MatrixF mat;
|
||||
aa.setMatrix(&mat);
|
||||
mat.setColumn(3,pos);
|
||||
setTransform(mat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//written by Anthony Lovell ----------------------------------------------------------
|
||||
U32
|
||||
SceneObject::getNumChildren() const
|
||||
{
|
||||
U32 num = 0;
|
||||
for (SceneObject *cur = mGraph.firstChild; cur; cur = cur->mGraph.nextSibling)
|
||||
num++;
|
||||
return num;
|
||||
}
|
||||
//written by Anthony Lovell ----------------------------------------------------------
|
||||
SceneObject *
|
||||
SceneObject::getChild(U32 index) const
|
||||
{
|
||||
SceneObject *cur = mGraph.firstChild;
|
||||
for (U32 i = 0;
|
||||
cur && i < index;
|
||||
i++)
|
||||
cur = cur->mGraph.nextSibling;
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SceneObject::UpdateXformChange(const MatrixF &mat){
|
||||
// This function gets the difference between the Transform and current Render transform
|
||||
// Used for Interpolation matching with the child objects who rely on this data.
|
||||
|
||||
MatrixF oldxform = getTransform();
|
||||
|
||||
oldxform.affineInverse();
|
||||
mLastXform.mul(mat,oldxform);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
bool
|
||||
SceneObject::attachChildAt(SceneObject *subObject, MatrixF atThisOffset, S32 node)
|
||||
{
|
||||
AssertFatal(subObject, "attaching a null subObject");
|
||||
AssertFatal(!isChildOf(subObject), "cyclic attachChild()");
|
||||
bool b = subObject->attachToParent(this, &atThisOffset, node);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
bool
|
||||
SceneObject::attachChildAt(SceneObject *subObject, Point3F atThisPosition)
|
||||
{
|
||||
AssertFatal(subObject, "attaching a null subObject");
|
||||
AssertFatal(!isChildOf(subObject), "cyclic attachChild()");
|
||||
bool b = subObject->attachToParent(this);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
subObject->mGraph.objToParent.setColumn(3, atThisPosition);
|
||||
// calcTransformFromLocalTransform();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
bool
|
||||
SceneObject::attachChild(SceneObject *child)
|
||||
{
|
||||
AssertFatal(child, "attaching a null subObject");
|
||||
AssertFatal(!isChildOf(child), "cyclic attachChild()");
|
||||
|
||||
return child->attachToParent(this);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
/// returns a count of children plus their children, recursively
|
||||
U32
|
||||
SceneObject::getNumProgeny() const
|
||||
{
|
||||
U32 num = 0;
|
||||
for (SceneObject *cur = mGraph.firstChild; cur; cur = cur->mGraph.nextSibling) {
|
||||
num += 1 + cur->getNumProgeny();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, getNumChildren, S32, (),, "returns number of direct child objects")
|
||||
{
|
||||
return object->getNumChildren();
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, getNumProgeny, S32, (),, "returns number of recursively-nested child objects")
|
||||
{
|
||||
return object->getNumProgeny();
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, getChild, S32, (S32 _index), (0), "getChild(S32 index) -- returns child SceneObject at given index")
|
||||
{
|
||||
SceneObject *s = object->getChild(_index);
|
||||
return s ? s->getId() : 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, attachChildAt, bool, (SceneObject* _subObject, MatrixF _offset, S32 _node), (nullAsType<SceneObject*>(), MatrixF::Identity, 0), "(SceneObject subObject, MatrixF offset, S32 offset)"
|
||||
"Mount object to this one with the specified offset expressed in our coordinate space.")
|
||||
{
|
||||
if (_subObject != nullptr)
|
||||
{
|
||||
return object->attachChildAt(_subObject, _offset, _node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf("Couldn't addObject()!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, attachToParent, bool, (const char*_sceneObject), ,"attachToParent(SceneObject)"
|
||||
"specify a null or non-null parent")
|
||||
{
|
||||
SceneObject * t;
|
||||
|
||||
if(Sim::findObject(_sceneObject, t))
|
||||
{
|
||||
return object->attachToParent(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((!dStrcmp("0", _sceneObject))|| (!dStrcmp("", _sceneObject)))
|
||||
return object->attachToParent(NULL);
|
||||
else
|
||||
{
|
||||
Con::errorf("Couldn't setParent()!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, getParent, S32, (),, "returns ID of parent SceneObject")
|
||||
{
|
||||
SceneObject *p = object->getParent();
|
||||
return p ? p->getId() : -1;
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, attachChild, bool, (const char*_subObject),, "(SceneObject subObject)"
|
||||
"attach an object to this one, preserving its present transform.")
|
||||
{
|
||||
SceneObject * t;
|
||||
MatrixF m;
|
||||
if(Sim::findObject(_subObject, t))
|
||||
return object->attachChild(t);
|
||||
|
||||
Con::errorf("Couldn't addObject()!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SceneObject::isChildOf(SceneObject *so)
|
||||
{
|
||||
SceneObject *p = mGraph.parent;
|
||||
if (p) {
|
||||
if (p == so)
|
||||
return true;
|
||||
else
|
||||
return p->isChildOf(so);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SceneObject::attachToParent(SceneObject *newParent, MatrixF *atThisOffset/* = NULL */, S32 node )
|
||||
{
|
||||
SceneObject *oldParent = mGraph.parent;
|
||||
|
||||
if (oldParent == newParent)
|
||||
return true;
|
||||
|
||||
// cycles in the scene hierarchy are forbidden!
|
||||
// that is: a SceneObject cannot be a child of its progeny
|
||||
if (newParent && newParent->isChildOf(this))
|
||||
return false;
|
||||
|
||||
mGraph.parent = newParent;
|
||||
|
||||
if (oldParent) {
|
||||
|
||||
clearNotify(oldParent);
|
||||
|
||||
// remove this SceneObject from the list of children of oldParent
|
||||
SceneObject *cur = oldParent->mGraph.firstChild;
|
||||
if (cur == this) { // if we are the first child, this is easy
|
||||
oldParent->mGraph.firstChild = mGraph.nextSibling;
|
||||
} else {
|
||||
while (cur->mGraph.nextSibling != this) {
|
||||
cur = cur->mGraph.nextSibling;
|
||||
// ASSERT cur != NULL;
|
||||
}
|
||||
cur->mGraph.nextSibling = mGraph.nextSibling;
|
||||
}
|
||||
oldParent->onLostChild(this);
|
||||
}
|
||||
|
||||
if (newParent) {
|
||||
|
||||
deleteNotify(newParent); // if we are deleted, inform our parent
|
||||
|
||||
// add this SceneObject to the list of children of oldParent
|
||||
mGraph.nextSibling = newParent->mGraph.firstChild;
|
||||
newParent->mGraph.firstChild = this;
|
||||
mGraph.parent = newParent;
|
||||
|
||||
newParent->onNewChild(this);
|
||||
|
||||
if (atThisOffset)
|
||||
mGraph.objToParent = *atThisOffset;
|
||||
} else {
|
||||
mGraph.parent = NULL;
|
||||
mGraph.nextSibling = NULL;
|
||||
mGraph.objToParent = mObjToWorld;
|
||||
}
|
||||
|
||||
onLostParent(oldParent);
|
||||
onNewParent(newParent);
|
||||
|
||||
setMaskBits(MountedMask);
|
||||
return true;
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, detachChild, bool, (const char*_subObject),, "SceneObject subObject")
|
||||
{
|
||||
SceneObject * t;
|
||||
if(Sim::findObject(_subObject, t)) {
|
||||
return t->attachToParent(NULL);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// subclasses can do something with these if they care to
|
||||
void SceneObject::onNewParent(SceneObject *newParent) {}
|
||||
void SceneObject::onLostParent(SceneObject *oldParent){}
|
||||
void SceneObject::onNewChild(SceneObject *newKid){}
|
||||
void SceneObject::onLostChild(SceneObject *lostKid){}
|
||||
|
|
|
|||
|
|
@ -293,6 +293,10 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
|
|||
/// @name Transform and Collision Members
|
||||
/// @{
|
||||
|
||||
// PATHSHAPE
|
||||
MatrixF mLastXform;
|
||||
// PATHSHAPE END
|
||||
|
||||
/// Transform from object space to world space.
|
||||
MatrixF mObjToWorld;
|
||||
|
||||
|
|
@ -819,6 +823,27 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
|
|||
static bool _setAccuEnabled( void *object, const char *index, const char *data );
|
||||
|
||||
/// @}
|
||||
// PATHSHAPE
|
||||
/// @}
|
||||
//Anthony's Original Code, still used so i keep it here
|
||||
/// TGE uses the term "mount" in a quirky, staticky way relating to its limited use to have
|
||||
/// riders and guns mounted on a vehicle (and similar)
|
||||
/// I did not alter that code at all (yet) and did not want to keep its terminology for other reasons
|
||||
/// I decided to support a hierarchy of scene objects and dubbed the operations
|
||||
/// attaching and removing child SceneObjects
|
||||
protected:
|
||||
|
||||
// this member struct tracks the relationship to parent and children
|
||||
// sceneObjects in a hierarchical scene graph whose root is the entire Scene
|
||||
struct AttachInfo {
|
||||
SceneObject* firstChild; ///< Objects mounted on this object
|
||||
SimObjectPtr<SceneObject> parent; ///< Object this object is mounted on.
|
||||
SceneObject* nextSibling; ///< Link to next child object of this object's parent
|
||||
MatrixF objToParent; ///< this obects transformation in the parent object's space
|
||||
MatrixF RenderobjToParent; ///< this obects Render Offset transformation to the parent object
|
||||
} mGraph;
|
||||
// PATHSHAPE END
|
||||
|
||||
|
||||
// Accumulation Texture
|
||||
// Note: This was placed in SceneObject to both ShapeBase and TSStatic could support it.
|
||||
|
|
@ -841,6 +866,83 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
|
|||
// as opposed to something like a Player that has a built-in camera that requires
|
||||
// special calculations to determine the view transform.
|
||||
virtual bool isCamera() const { return false; }
|
||||
// AFX CODE BLOCK (is-camera) >>
|
||||
// PATHSHAPE
|
||||
// Added for dynamic attaching
|
||||
void UpdateXformChange(const MatrixF &mat);
|
||||
/// this is useful for setting NULL parent (making SceneObject a root object)
|
||||
virtual bool attachToParent(SceneObject *parent, MatrixF *atThisOffset = NULL, S32 node=0);
|
||||
SceneObject *getParent() { return mGraph.parent; };
|
||||
|
||||
|
||||
/// attach a subobject, but do not alter the subObject's present absolute position or orientation
|
||||
bool attachChild(SceneObject* subObject);
|
||||
/// attach a subobject, at the specified offset expressed in our local coordinate space
|
||||
bool attachChildAt(SceneObject* subObject, MatrixF atThisTransform, S32 node);
|
||||
|
||||
/// attach a subobject, at the specified position expressed in our local coordinate space
|
||||
bool attachChildAt(SceneObject* subObject, Point3F atThisPosition);
|
||||
|
||||
/// how many child SceneObjects are (directly) attached to this one?
|
||||
U32 getNumChildren() const;
|
||||
|
||||
/// how many child objects does this SceneObject have when we count them recursively?
|
||||
U32 getNumProgeny() const;
|
||||
|
||||
/// returns the (direct) child SceneObject at the given index (0 <= index <= getNumChildren() - 1)
|
||||
SceneObject *getChild(U32 index) const;
|
||||
|
||||
/// is this SceneObject a child (directly or indirectly) of the given object?
|
||||
bool isChildOf(SceneObject *);
|
||||
|
||||
/// set position in parent SceneObject's coordinate space (or in world space if no parent)
|
||||
//void setLocalPosition(const Point3F &pos);
|
||||
|
||||
/// move the object in parent SceneObject's coordinate space (or in world space if no parent)
|
||||
//void localMove(const Point3F &delta);
|
||||
/// as localMove(const Point3F &delta), with different signature
|
||||
//void localMove(F32 x, F32 y, F32 z);
|
||||
|
||||
/// move the object in world space, without altering place in scene hierarchy
|
||||
void move(const Point3F &delta);
|
||||
|
||||
// Does checks for children objects and updates their positions
|
||||
void PerformUpdatesForChildren(MatrixF mat);
|
||||
|
||||
// Move the RenderTransform
|
||||
void moveRender(const Point3F &delta);
|
||||
//Calculate how much to adjust the render transform - Called by the child objects
|
||||
void updateRenderChangesByParent();
|
||||
//Calculate how much to adjust the transform - Called by the parent object
|
||||
void updateChildTransform();
|
||||
/// as move(const Point3F &delta), with different signature
|
||||
void move(F32 x, F32 y, F32 z);
|
||||
|
||||
/// returns the transform relative to parent SceneObject transform (or world transform if no parent)
|
||||
//const MatrixF& getLocalTransform() const;
|
||||
/// returns the position within parent SceneObject space (or world space if no parent)
|
||||
//Point3F getLocalPosition() const;
|
||||
|
||||
|
||||
// virtual void onParentScaleChanged();
|
||||
// virtual void onParentTransformChanged();
|
||||
|
||||
/// Sets the Object -> Parent transform. If no parent SceneObject, this is equivalent to
|
||||
/// setTransform()
|
||||
///
|
||||
/// @param mat New transform matrix
|
||||
//virtual void setLocalTransform(const MatrixF & mat);
|
||||
|
||||
|
||||
/// Called to let instance specific code happen
|
||||
virtual void onLostParent(SceneObject *oldParent);
|
||||
/// Called to let instance specific code happen
|
||||
virtual void onNewParent(SceneObject *newParent);
|
||||
/// notification that a direct child object has been attached
|
||||
virtual void onNewChild(SceneObject *subObject);
|
||||
/// notification that a direct child object has been detached
|
||||
virtual void onLostChild(SceneObject *subObject);
|
||||
// PATHSHAPE END
|
||||
};
|
||||
|
||||
#endif // _SCENEOBJECT_H_
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/stream/bitStream.h"
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "T3D/pathShape.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
|
|
@ -155,6 +156,11 @@ Path::Path()
|
|||
{
|
||||
mPathIndex = NoPathIndex;
|
||||
mIsLooping = true;
|
||||
mPathSpeed = 1.0f;
|
||||
mDataBlock = NULL;
|
||||
mSpawnCount = 1;
|
||||
mMinDelay = 0;
|
||||
mMaxDelay = 0;
|
||||
}
|
||||
|
||||
Path::~Path()
|
||||
|
|
@ -166,6 +172,13 @@ Path::~Path()
|
|||
void Path::initPersistFields()
|
||||
{
|
||||
addField("isLooping", TypeBool, Offset(mIsLooping, Path), "If this is true, the loop is closed, otherwise it is open.\n");
|
||||
addField("Speed", TypeF32, Offset(mPathSpeed, Path), "Speed.\n");
|
||||
addProtectedField("mPathShape", TYPEID< PathShapeData >(), Offset(mDataBlock, Path),
|
||||
&setDataBlockProperty, &defaultProtectedGetFn,
|
||||
"@brief Spawned PathShape.\n\n");
|
||||
addField("spawnCount", TypeS32, Offset(mSpawnCount, Path), "Spawn Count.\n");
|
||||
addField("minDelay", TypeS32, Offset(mMinDelay, Path), "Spawn Delay (min).\n");
|
||||
addField("maxDelay", TypeS32, Offset(mMaxDelay, Path), "Spawn Delay (max).\n");
|
||||
|
||||
Parent::initPersistFields();
|
||||
//
|
||||
|
|
@ -179,9 +192,14 @@ bool Path::onAdd()
|
|||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
onAdd_callback(getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
IMPLEMENT_CALLBACK(Path, onAdd, void, (SimObjectId ID), (ID),
|
||||
"Called when this ScriptGroup is added to the system.\n"
|
||||
"@param ID Unique object ID assigned when created (%this in script).\n"
|
||||
);
|
||||
|
||||
void Path::onRemove()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,17 +36,21 @@
|
|||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
class BaseMatInstance;
|
||||
#ifndef _STATICSHAPE_H_
|
||||
#include "T3D/staticShape.h"
|
||||
#endif
|
||||
|
||||
class BaseMatInstance;
|
||||
struct PathShapeData;
|
||||
|
||||
namespace SimPath
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/// A path!
|
||||
class Path : public SimGroup
|
||||
class Path : public GameBase
|
||||
{
|
||||
typedef SimGroup Parent;
|
||||
typedef GameBase Parent;
|
||||
|
||||
public:
|
||||
enum : U32
|
||||
|
|
@ -57,8 +61,12 @@ class Path : public SimGroup
|
|||
|
||||
private:
|
||||
U32 mPathIndex;
|
||||
F32 mPathSpeed;
|
||||
bool mIsLooping;
|
||||
|
||||
PathShapeData* mDataBlock;
|
||||
S32 mSpawnCount;
|
||||
S32 mMinDelay;
|
||||
S32 mMaxDelay;
|
||||
protected:
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
|
@ -77,6 +85,7 @@ class Path : public SimGroup
|
|||
|
||||
DECLARE_CONOBJECT(Path);
|
||||
static void initPersistFields();
|
||||
DECLARE_CALLBACK(void, onAdd, (SimObjectId ID));
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue