瀏覽代碼

Fixes up various parts of the entity and component classes.

Areloch 8 年之前
父節點
當前提交
1fdbc6594e

+ 78 - 7
Engine/source/T3D/components/component.cpp

@@ -42,13 +42,13 @@
 
 
 Component::Component()
 Component::Component()
 {
 {
-   mFriendlyName = StringTable->lookup("");
-   mFromResource = StringTable->lookup("");
-   mComponentType = StringTable->lookup("");
-   mComponentGroup = StringTable->lookup("");
-   mNetworkType = StringTable->lookup("");
-   mTemplateName = StringTable->lookup("");
-   //mDependency = StringTable->lookup("");
+   mFriendlyName = StringTable->EmptyString();
+   mFromResource = StringTable->EmptyString();
+   mComponentType = StringTable->EmptyString();
+   mComponentGroup = StringTable->EmptyString();
+   mNetworkType = StringTable->EmptyString();
+   mTemplateName = StringTable->EmptyString();
+   //mDependency = StringTable->EmptyString();
 
 
    mNetworked = false;
    mNetworked = false;
 
 
@@ -64,6 +64,8 @@ Component::Component()
 
 
    mCanSaveFieldDictionary = false;
    mCanSaveFieldDictionary = false;
 
 
+   mOriginatingAssetId = StringTable->EmptyString();
+
    mNetFlags.set(Ghostable);
    mNetFlags.set(Ghostable);
 }
 }
 
 
@@ -97,6 +99,10 @@ void Component::initPersistFields()
 
 
       //addField("hidden", TypeBool, Offset(mHidden, Component), "Flags if this behavior is shown in the editor or not", AbstractClassRep::FieldFlags::FIELD_HideInInspectors);
       //addField("hidden", TypeBool, Offset(mHidden, Component), "Flags if this behavior is shown in the editor or not", AbstractClassRep::FieldFlags::FIELD_HideInInspectors);
       addProtectedField("enabled", TypeBool, Offset(mEnabled, Component), &_setEnabled, &defaultProtectedGetFn, "");
       addProtectedField("enabled", TypeBool, Offset(mEnabled, Component), &_setEnabled, &defaultProtectedGetFn, "");
+
+      addField("originatingAsset", TypeComponentAssetPtr, Offset(mOriginatingAsset, Component),
+         "Asset that spawned this component, used for tracking/housekeeping", AbstractClassRep::FieldFlags::FIELD_HideInInspectors);
+
    endGroup("Component");
    endGroup("Component");
 
 
    Parent::initPersistFields();
    Parent::initPersistFields();
@@ -149,6 +155,7 @@ bool Component::onAdd()
       return false;
       return false;
 
 
    setMaskBits(UpdateMask);
    setMaskBits(UpdateMask);
+   setMaskBits(NamespaceMask);
 
 
    return true;
    return true;
 }
 }
@@ -274,6 +281,19 @@ U32 Component::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
       stream->writeFlag(mEnabled);
       stream->writeFlag(mEnabled);
    }
    }
 
 
+   /*if (stream->writeFlag(mask & NamespaceMask))
+   {
+      const char* name = getName();
+      if (stream->writeFlag(name && name[0]))
+         stream->writeString(String(name));
+
+      if (stream->writeFlag(mSuperClassName && mSuperClassName[0]))
+         stream->writeString(String(mSuperClassName));
+
+      if (stream->writeFlag(mClassName && mClassName[0]))
+         stream->writeString(String(mClassName));
+   }*/
+
    return retMask;
    return retMask;
 }
 }
 
 
@@ -303,6 +323,32 @@ void Component::unpackUpdate(NetConnection *con, BitStream *stream)
    {
    {
       mEnabled = stream->readFlag();
       mEnabled = stream->readFlag();
    }
    }
+
+   /*if (stream->readFlag())
+   {
+      if (stream->readFlag())
+      {
+         char name[256];
+         stream->readString(name);
+         assignName(name);
+      }
+
+      if (stream->readFlag())
+      {
+         char superClassname[256];
+         stream->readString(superClassname);
+       mSuperClassName = superClassname;
+      }
+
+      if (stream->readFlag())
+      {
+         char classname[256];
+         stream->readString(classname);
+         mClassName = classname;
+      }
+
+      linkNamespaces();
+   }*/
 }
 }
 
 
 void Component::packToStream(Stream &stream, U32 tabStop, S32 behaviorID, U32 flags /* = 0  */)
 void Component::packToStream(Stream &stream, U32 tabStop, S32 behaviorID, U32 flags /* = 0  */)
@@ -346,6 +392,10 @@ void Component::setDataField(StringTableEntry slotName, const char *array, const
    onDataSet.trigger(this, slotName, value);
    onDataSet.trigger(this, slotName, value);
 }
 }
 
 
+StringTableEntry Component::getComponentName()
+{
+   return getNamespace()->getName();
+}
 
 
 //catch any behavior field updates
 //catch any behavior field updates
 void Component::onStaticModified(const char* slotName, const char* newValue)
 void Component::onStaticModified(const char* slotName, const char* newValue)
@@ -426,6 +476,16 @@ void Component::addComponentField(const char *fieldName, const char *desc, const
       fieldTypeMask = TypeBool;
       fieldTypeMask = TypeBool;
    else if (fieldType == StringTable->insert("object"))
    else if (fieldType == StringTable->insert("object"))
       fieldTypeMask = TypeSimObjectPtr;
       fieldTypeMask = TypeSimObjectPtr;
+   else if (fieldType == StringTable->insert("string"))
+      fieldTypeMask = TypeString;
+   else if (fieldType == StringTable->insert("colorI"))
+      fieldTypeMask = TypeColorI;
+   else if (fieldType == StringTable->insert("colorF"))
+      fieldTypeMask = TypeColorF;
+   else if (fieldType == StringTable->insert("ease"))
+      fieldTypeMask = TypeEaseF;
+   else if (fieldType == StringTable->insert("gameObject"))
+      fieldTypeMask = TypeGameObjectAssetPtr;
    else
    else
       fieldTypeMask = TypeString;
       fieldTypeMask = TypeString;
 
 
@@ -603,6 +663,17 @@ ConsoleMethod(Component, setComponentield, const char *, 3, 3, "(int index) - Ge
    return buf;
    return buf;
 }
 }
 
 
+DefineConsoleMethod(Component, getComponentFieldType, const char *, (String fieldName), ,
+   "Get the number of static fields on the object.\n"
+   "@return The number of static fields defined on the object.")
+{
+   ComponentField *field = object->getComponentField(fieldName);
+   if (field == NULL)
+      return "";
+
+   return field->mFieldTypeName;;
+}
+
 ConsoleMethod(Component, getBehaviorFieldUserData, const char *, 3, 3, "(int index) - Gets the UserData associated with a field by index in the field list\n"
 ConsoleMethod(Component, getBehaviorFieldUserData, const char *, 3, 3, "(int index) - Gets the UserData associated with a field by index in the field list\n"
    "@param index The index of the behavior\n"
    "@param index The index of the behavior\n"
    "@return Returns a string representing the user data of this field\n")
    "@return Returns a string representing the user data of this field\n")

+ 15 - 1
Engine/source/T3D/components/component.h

@@ -32,14 +32,22 @@
 #ifndef CORE_INTERFACES_H
 #ifndef CORE_INTERFACES_H
 #include "T3D/components/coreInterfaces.h"
 #include "T3D/components/coreInterfaces.h"
 #endif
 #endif
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif 
+#ifndef COMPONENT_ASSET_H
+#include "T3D/assets/ComponentAsset.h"
+#endif
 
 
 class Entity;
 class Entity;
+class Namespace;
 
 
 struct ComponentField
 struct ComponentField
 {
 {
    StringTableEntry mFieldName;
    StringTableEntry mFieldName;
    StringTableEntry mFieldDescription;
    StringTableEntry mFieldDescription;
 
 
+   StringTableEntry mFieldTypeName;
    S32 mFieldType;
    S32 mFieldType;
    StringTableEntry mUserData;
    StringTableEntry mUserData;
 
 
@@ -81,6 +89,9 @@ protected:
    bool					   mHidden;
    bool					   mHidden;
    bool					   mEnabled;
    bool					   mEnabled;
 
 
+   StringTableEntry		      mOriginatingAssetId;
+   AssetPtr<ComponentAsset>  mOriginatingAsset;
+
 public:
 public:
    Component();
    Component();
    virtual ~Component();
    virtual ~Component();
@@ -175,7 +186,8 @@ public:
       OwnerMask = BIT(1),
       OwnerMask = BIT(1),
       UpdateMask = BIT(2),
       UpdateMask = BIT(2),
       EnableMask = BIT(3),
       EnableMask = BIT(3),
-      NextFreeMask = BIT(4)
+      NamespaceMask = BIT(4),
+      NextFreeMask = BIT(5)
    };
    };
 
 
    virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream);
    virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream);
@@ -192,6 +204,8 @@ public:
    void checkComponentFieldModified(const char* slotName, const char* newValue);
    void checkComponentFieldModified(const char* slotName, const char* newValue);
 
 
    virtual void checkDependencies(){}
    virtual void checkDependencies(){}
+
+   StringTableEntry getComponentName();
 };
 };
 
 
 #endif // COMPONENT_H
 #endif // COMPONENT_H

+ 0 - 1
Engine/source/T3D/components/render/meshComponent.cpp

@@ -34,7 +34,6 @@
 #include "lighting/lightQuery.h"
 #include "lighting/lightQuery.h"
 #include "scene/sceneManager.h"
 #include "scene/sceneManager.h"
 #include "gfx/bitmap/ddsFile.h"
 #include "gfx/bitmap/ddsFile.h"
-#include "gfx/bitmap/ddsUtils.h"
 #include "gfx/gfxTextureManager.h"
 #include "gfx/gfxTextureManager.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "renderInstance/renderImposterMgr.h"
 #include "renderInstance/renderImposterMgr.h"

+ 147 - 249
Engine/source/T3D/entity.cpp

@@ -51,6 +51,7 @@
 //
 //
 #include "gfx/sim/debugDraw.h"
 #include "gfx/sim/debugDraw.h"
 //
 //
+#include "T3D/sfx/sfx3DWorld.h"
 
 
 extern bool gEditingMission;
 extern bool gEditingMission;
 
 
@@ -117,6 +118,8 @@ Entity::Entity()
 
 
    mInitialized = false;
    mInitialized = false;
 
 
+   mGameObjectAssetId = StringTable->insert("");
+
 }
 }
 
 
 Entity::~Entity()
 Entity::~Entity()
@@ -143,6 +146,11 @@ void Entity::initPersistFields()
    addField("LocalRotation", TypeMatrixRotation, Offset(mMount.xfm, Entity), "Rotation we are mounted at ( object space of our mount object ).");
    addField("LocalRotation", TypeMatrixRotation, Offset(mMount.xfm, Entity), "Rotation we are mounted at ( object space of our mount object ).");
 
 
    endGroup("Transform");
    endGroup("Transform");
+
+   addGroup("GameObject");
+   addProtectedField("gameObjectName", TypeGameObjectAssetPtr, Offset(mGameObjectAsset, Entity), &_setGameObject, &defaultProtectedGetFn,
+      "The asset Id used for the game object this entity is based on.");
+   endGroup("GameObject");
 }
 }
 
 
 //
 //
@@ -215,8 +223,8 @@ bool Entity::onAdd()
    if (!Parent::onAdd())
    if (!Parent::onAdd())
       return false;
       return false;
 
 
-   mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
-
+   mObjBox = Box3F(Point3F(-0.5, -0.5, -0.5), Point3F(0.5, 0.5, 0.5));
+   
    resetWorldBox();
    resetWorldBox();
    setObjectBox(mObjBox);
    setObjectBox(mObjBox);
 
 
@@ -224,6 +232,7 @@ bool Entity::onAdd()
 
 
    //Make sure we get positioned
    //Make sure we get positioned
    setMaskBits(TransformMask);
    setMaskBits(TransformMask);
+   setMaskBits(NamespaceMask);
 
 
    return true;
    return true;
 }
 }
@@ -253,6 +262,16 @@ void Entity::onPostAdd()
       Con::executef(this, "onAdd");
       Con::executef(this, "onAdd");
 }
 }
 
 
+bool Entity::_setGameObject(void *object, const char *index, const char *data)
+{
+   Entity *e = static_cast<Entity*>(object);
+
+   // Sanity!
+   AssertFatal(data != NULL, "Cannot use a NULL asset Id.");
+
+   return true; //rbI->setMeshAsset(data);
+}
+
 void Entity::setDataField(StringTableEntry slotName, const char *array, const char *value)
 void Entity::setDataField(StringTableEntry slotName, const char *array, const char *value)
 {
 {
    Parent::setDataField(slotName, array, value);
    Parent::setDataField(slotName, array, value);
@@ -363,8 +382,20 @@ void Entity::processTick(const Move* move)
          }
          }
       }
       }
 
 
-      if (isMethod("processTick"))
+      // Save current rigid state interpolation
+      mDelta.posVec = getPosition();
+      mDelta.rot[0] = mRot.asQuatF();
+
+      //Handle any script updates, which can include physics stuff
+      if (isServerObject() && isMethod("processTick"))
          Con::executef(this, "processTick");
          Con::executef(this, "processTick");
+
+      // Wrap up interpolation info
+      mDelta.pos = getPosition();
+      mDelta.posVec -= getPosition();
+      mDelta.rot[1] = mRot.asQuatF();
+
+      setTransform(getPosition(), mRot);
    }
    }
 }
 }
 
 
@@ -402,11 +433,6 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
 
 
    if (stream->writeFlag(mask & TransformMask))
    if (stream->writeFlag(mask & TransformMask))
    {
    {
-      //mathWrite( *stream, getScale() );
-      //stream->writeAffineTransform(mObjToWorld);
-      //mathWrite(*stream, getPosition());
-      //mathWrite(*stream, mPos);
-
       stream->writeCompressedPoint(mPos);
       stream->writeCompressedPoint(mPos);
       mathWrite(*stream, getRotation());
       mathWrite(*stream, getRotation());
 
 
@@ -415,12 +441,6 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
       stream->writeFlag(!(mask & NoWarpMask));
       stream->writeFlag(!(mask & NoWarpMask));
    }
    }
 
 
-   /*if (stream->writeFlag(mask & MountedMask))
-   {
-      mathWrite(*stream, mMount.xfm.getPosition());
-      mathWrite(*stream, mMount.xfm.toEuler());
-   }*/
-
    if (stream->writeFlag(mask & BoundsMask))
    if (stream->writeFlag(mask & BoundsMask))
    {
    {
       mathWrite(*stream, mObjBox);
       mathWrite(*stream, mObjBox);
@@ -483,6 +503,19 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
    else
    else
       stream->writeFlag(false);
       stream->writeFlag(false);
 
 
+   /*if (stream->writeFlag(mask & NamespaceMask))
+   {
+      const char* name = getName();
+      if (stream->writeFlag(name && name[0]))
+         stream->writeString(String(name));
+
+      if (stream->writeFlag(mSuperClassName && mSuperClassName[0]))
+         stream->writeString(String(mSuperClassName));
+
+      if (stream->writeFlag(mClassName && mClassName[0]))
+         stream->writeString(String(mClassName));
+   }*/
+
    return retMask;
    return retMask;
 }
 }
 
 
@@ -492,20 +525,10 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream)
 
 
    if (stream->readFlag())
    if (stream->readFlag())
    {
    {
-      /*Point3F scale;
-      mathRead( *stream, &scale );
-      setScale( scale);*/
-
-      //MatrixF objToWorld;
-      //stream->readAffineTransform(&objToWorld);
-
       Point3F pos;
       Point3F pos;
-
       stream->readCompressedPoint(&pos);
       stream->readCompressedPoint(&pos);
-      //mathRead(*stream, &pos);
 
 
       RotationF rot;
       RotationF rot;
-
       mathRead(*stream, &rot);
       mathRead(*stream, &rot);
 
 
       mDelta.move.unpack(stream);
       mDelta.move.unpack(stream);
@@ -514,72 +537,6 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream)
       {
       {
          // Determine number of ticks to warp based on the average
          // Determine number of ticks to warp based on the average
          // of the client and server velocities.
          // of the client and server velocities.
-         /*mDelta.warpOffset = pos - mDelta.pos;
-
-         F32 dt = mDelta.warpOffset.len() / (0.5f * TickSec);
-
-         mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
-
-         //F32 as = (speed + mVelocity.len()) * 0.5f * TickSec;
-         //F32 dt = (as > 0.00001f) ? mDelta.warpOffset.len() / as : sMaxWarpTicks;
-         //mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
-
-         //mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
-
-         //mDelta.warpTicks = sMaxWarpTicks;
-
-         mDelta.warpTicks = 0;
-
-         if (mDelta.warpTicks)
-         {
-            // Setup the warp to start on the next tick.
-            if (mDelta.warpTicks > sMaxWarpTicks)
-               mDelta.warpTicks = sMaxWarpTicks;
-            mDelta.warpOffset /= (F32)mDelta.warpTicks;
-
-            mDelta.rot[0] = rot.asQuatF();
-            mDelta.rot[1] = rot.asQuatF();
-
-            mDelta.rotOffset = rot.asEulerF() - mDelta.rot.asEulerF();
-
-            // Ignore small rotation differences
-            if (mFabs(mDelta.rotOffset.x) < 0.001f)
-               mDelta.rotOffset.x = 0;
-
-            if (mFabs(mDelta.rotOffset.y) < 0.001f)
-               mDelta.rotOffset.y = 0;
-
-            if (mFabs(mDelta.rotOffset.z) < 0.001f)
-               mDelta.rotOffset.z = 0;
-
-            mDelta.rotOffset /= (F32)mDelta.warpTicks;
-         }
-         else
-         {
-            // Going to skip the warp, server and client are real close.
-            // Adjust the frame interpolation to move smoothly to the
-            // new position within the current tick.
-            Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt;
-            if (mDelta.dt == 0)
-            {
-               mDelta.posVec.set(0.0f, 0.0f, 0.0f);
-               mDelta.rotVec.set(0.0f, 0.0f, 0.0f);
-            }
-            else
-            {
-               F32 dti = 1.0f / mDelta.dt;
-               mDelta.posVec = (cp - pos) * dti;
-               mDelta.rotVec.z = mRot.z - rot.z;
-
-               mDelta.rotVec.z *= dti;
-            }
-
-            mDelta.pos = pos;
-            mDelta.rot = rot;
-
-            setTransform(pos, rot);
-         }*/
-
          Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt;
          Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt;
          mDelta.warpOffset = pos - cp;
          mDelta.warpOffset = pos - cp;
 
 
@@ -631,20 +588,6 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream)
       }
       }
    }
    }
 
 
-   /*if (stream->readFlag())
-   {
-      Point3F mountOffset;
-      EulerF mountRot;
-      mathRead(*stream, &mountOffset);
-      mathRead(*stream, &mountRot);
-
-      RotationF rot = RotationF(mountRot);
-      mountRot = rot.asEulerF(RotationF::Degrees);
-
-      setMountOffset(mountOffset);
-      setMountRotation(mountRot);
-   }*/
-
    if (stream->readFlag())
    if (stream->readFlag())
    {
    {
       mathRead(*stream, &mObjBox);
       mathRead(*stream, &mObjBox);
@@ -669,13 +612,38 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream)
          }
          }
       }
       }
    }
    }
+
+   /*if (stream->readFlag())
+   {
+      if (stream->readFlag())
+      {
+         char name[256];
+         stream->readString(name);
+         assignName(name);
+      }
+
+      if (stream->readFlag())
+      {
+         char superClassname[256];
+         stream->readString(superClassname);
+         mSuperClassName = superClassname;
+      }
+
+      if (stream->readFlag())
+      {
+         char classname[256];
+         stream->readString(classname);
+         mClassName = classname;
+      }
+
+      linkNamespaces();
+   }*/
 }
 }
 
 
 //Manipulation
 //Manipulation
 void Entity::setTransform(const MatrixF &mat)
 void Entity::setTransform(const MatrixF &mat)
 {
 {
-   //setMaskBits(TransformMask);
-   setMaskBits(TransformMask | NoWarpMask);
+   MatrixF oldTransform = getTransform();
 
 
    if (isMounted())
    if (isMounted())
    {
    {
@@ -687,25 +655,20 @@ void Entity::setTransform(const MatrixF &mat)
 
 
       if (!newOffset.isZero())
       if (!newOffset.isZero())
       {
       {
-         //setMountOffset(newOffset);
          mPos = newOffset;
          mPos = newOffset;
       }
       }
 
 
       Point3F matEul = mat.toEuler();
       Point3F matEul = mat.toEuler();
 
 
-      //mRot = Point3F(mRadToDeg(matEul.x), mRadToDeg(matEul.y), mRadToDeg(matEul.z));
-
       if (matEul != Point3F(0, 0, 0))
       if (matEul != Point3F(0, 0, 0))
       {
       {
          Point3F mountEul = mMount.object->getTransform().toEuler();
          Point3F mountEul = mMount.object->getTransform().toEuler();
          Point3F diff = matEul - mountEul;
          Point3F diff = matEul - mountEul;
 
 
-         //setMountRotation(Point3F(mRadToDeg(diff.x), mRadToDeg(diff.y), mRadToDeg(diff.z)));
          mRot = diff;
          mRot = diff;
       }
       }
       else
       else
       {
       {
-         //setMountRotation(Point3F(0, 0, 0));
          mRot = Point3F(0, 0, 0);
          mRot = Point3F(0, 0, 0);
       }
       }
 
 
@@ -714,6 +677,9 @@ void Entity::setTransform(const MatrixF &mat)
       transf.setPosition(mPos + mMount.object->getPosition());
       transf.setPosition(mPos + mMount.object->getPosition());
 
 
       Parent::setTransform(transf);
       Parent::setTransform(transf);
+
+      if (transf != oldTransform)
+         setMaskBits(TransformMask);
    }
    }
    else
    else
    {
    {
@@ -744,6 +710,8 @@ void Entity::setTransform(const MatrixF &mat)
 
 
 void Entity::setTransform(Point3F position, RotationF rotation)
 void Entity::setTransform(Point3F position, RotationF rotation)
 {
 {
+   MatrixF oldTransform = getTransform();
+
    if (isMounted())
    if (isMounted())
    {
    {
       mPos = position;
       mPos = position;
@@ -755,7 +723,8 @@ void Entity::setTransform(Point3F position, RotationF rotation)
 
 
       Parent::setTransform(transf);
       Parent::setTransform(transf);
 
 
-      setMaskBits(TransformMask);
+      if (transf != oldTransform)
+         setMaskBits(TransformMask);
    }
    }
    else
    else
    {
    {
@@ -774,7 +743,6 @@ void Entity::setTransform(Point3F position, RotationF rotation)
       mPos = position;
       mPos = position;
       mRot = rotation;
       mRot = rotation;
 
 
-      setMaskBits(TransformMask);
       //if (isServerObject())
       //if (isServerObject())
       //   setMaskBits(TransformMask);
       //   setMaskBits(TransformMask);
 
 
@@ -788,19 +756,18 @@ void Entity::setTransform(Point3F position, RotationF rotation)
       //PROFILE_SCOPE(Entity_setTransform);
       //PROFILE_SCOPE(Entity_setTransform);
 
 
       // Update the transforms.
       // Update the transforms.
-
       Parent::setTransform(newMat);
       Parent::setTransform(newMat);
 
 
       onTransformSet.trigger(&newMat);
       onTransformSet.trigger(&newMat);
 
 
-      /*mObjToWorld = mWorldToObj = newMat;
-      mWorldToObj.affineInverse();
-      // Update the world-space AABB.
-      resetWorldBox();
-      // If we're in a SceneManager, sync our scene state.
-      if (mSceneManager != NULL)
-      mSceneManager->notifyObjectDirty(this);
-      setRenderTransform(newMat);*/
+      Point3F newPos = newMat.getPosition();
+      RotationF newRot = newMat;
+
+      Point3F oldPos = oldTransform.getPosition();
+      RotationF oldRot = oldTransform;
+
+      if (newPos != oldPos || newRot != oldRot)
+         setMaskBits(TransformMask);
    }
    }
 }
 }
 
 
@@ -887,7 +854,7 @@ void Entity::setMountRotation(EulerF rotOffset)
       temp.setColumn(3, mMount.xfm.getPosition());
       temp.setColumn(3, mMount.xfm.getPosition());
 
 
       mMount.xfm = temp;
       mMount.xfm = temp;
-      //mRot = RotationF(temp);
+
       setMaskBits(MountedMask);
       setMaskBits(MountedMask);
    }
    }
 }
 }
@@ -964,63 +931,6 @@ void Entity::getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, M
    Parent::getMountTransform(index, xfm, outMat);
    Parent::getMountTransform(index, xfm, outMat);
 }
 }
 
 
-void Entity::setForwardVector(VectorF newForward, VectorF upVector)
-{
-   MatrixF mat = getTransform();
-
-   VectorF up(0.0f, 0.0f, 1.0f);
-   VectorF axisX;
-   VectorF axisY = newForward;
-   VectorF axisZ;
-
-   if (upVector != VectorF::Zero)
-      up = upVector;
-
-   // Validate and normalize input:  
-   F32 lenSq;
-   lenSq = axisY.lenSquared();
-   if (lenSq < 0.000001f)
-   {
-      axisY.set(0.0f, 1.0f, 0.0f);
-      Con::errorf("Entity::setForwardVector() - degenerate forward vector");
-   }
-   else
-   {
-      axisY /= mSqrt(lenSq);
-   }
-
-
-   lenSq = up.lenSquared();
-   if (lenSq < 0.000001f)
-   {
-      up.set(0.0f, 0.0f, 1.0f);
-      Con::errorf("SceneObject::setForwardVector() - degenerate up vector - too small");
-   }
-   else
-   {
-      up /= mSqrt(lenSq);
-   }
-
-   if (fabsf(mDot(up, axisY)) > 0.9999f)
-   {
-      Con::errorf("SceneObject::setForwardVector() - degenerate up vector - same as forward");
-      // i haven't really tested this, but i think it generates something which should be not parallel to the previous vector:  
-      F32 tmp = up.x;
-      up.x = -up.y;
-      up.y = up.z;
-      up.z = tmp;
-   }
-
-   // construct the remaining axes:  
-   mCross(axisY, up, &axisX);
-   mCross(axisX, axisY, &axisZ);
-
-   mat.setColumn(0, axisX);
-   mat.setColumn(1, axisY);
-   mat.setColumn(2, axisZ);
-
-   setTransform(mat);
-}
 //
 //
 //These basically just redirect to any collision behaviors we have
 //These basically just redirect to any collision behaviors we have
 bool Entity::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
 bool Entity::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
@@ -1117,6 +1027,28 @@ void Entity::onUnmount(SceneObject *obj, S32 node)
    }
    }
 }
 }
 
 
+void Entity::setControllingClient(GameConnection* client)
+{
+   if (isGhost() && gSFX3DWorld)
+   {
+      if (gSFX3DWorld->getListener() == this && !client && getControllingClient() && getControllingClient()->isConnectionToServer())
+      {
+         // We are the current listener and are no longer a controller object on the
+         // connection, so clear our listener status.
+
+         gSFX3DWorld->setListener(NULL);
+      }
+      else if (client && client->isConnectionToServer() && !getControllingObject())
+      {
+         // We're on the local client and not controlled by another object, so make
+         // us the current SFX listener.
+
+         gSFX3DWorld->setListener(this);
+      }
+   }
+   Parent::setControllingClient(client);
+}
+
 //Heirarchy stuff
 //Heirarchy stuff
 void Entity::addObject(SimObject* object)
 void Entity::addObject(SimObject* object)
 {
 {
@@ -1261,9 +1193,8 @@ bool Entity::removeComponent(Component *comp, bool deleteComponent)
 
 
       onComponentRemoved.trigger(comp);
       onComponentRemoved.trigger(comp);
 
 
-      comp->setOwner(NULL);
-
       comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
       comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
+      comp->setOwner(NULL);
 
 
       if (deleteComponent)
       if (deleteComponent)
          comp->safeDeleteObject();
          comp->safeDeleteObject();
@@ -1364,72 +1295,6 @@ void Entity::onInspect()
    {
    {
       (*it)->onInspect();
       (*it)->onInspect();
    }
    }
-
-   GuiTreeViewCtrl *editorTree = dynamic_cast<GuiTreeViewCtrl*>(Sim::findObject("EditorTree"));
-   if (!editorTree)
-      return;
-
-   GuiTreeViewCtrl::Item *newItem, *parentItem;
-
-   parentItem = editorTree->getItem(editorTree->findItemByObjectId(getId()));
-
-   S32 componentID = editorTree->insertItem(parentItem->getID(), "Components");
-
-   newItem = editorTree->getItem(componentID);
-   newItem->mState.set(GuiTreeViewCtrl::Item::VirtualParent);
-   newItem->mState.set(GuiTreeViewCtrl::Item::DenyDrag);
-   //newItem->mState.set(GuiTreeViewCtrl::Item::InspectorData);
-   newItem->mState.set(GuiTreeViewCtrl::Item::ForceItemName);
-   //newItem->mInspectorInfo.mObject = this;
-
-   AssetManager *assetDB = dynamic_cast<AssetManager*>(Sim::findObject("AssetDatabase"));
-   if (!assetDB)
-      return;
-
-   //This is used in the event of script-created assets, which likely only have
-   //the name and other 'friendly' properties stored in a ComponentAsset.
-   //So we'll do a query for those assets and find the asset based on the component's
-   //class name
-   AssetQuery* qry = new AssetQuery();
-   qry->registerObject();
-
-   assetDB->findAssetType(qry, "ComponentAsset");
-
-   for (U32 i = 0; i < mComponents.size(); ++i)
-   {
-      String compName = mComponents[i]->getFriendlyName();
-
-      if (compName == String(""))
-      {
-         String componentClass = mComponents[i]->getClassNamespace();
-
-         //Means that it's a script-derived component and we should consult the asset to try
-         //to get the info for it
-         S32 compAssetCount = qry->mAssetList.size();
-         for (U32 c = 0; c < compAssetCount; ++c)
-         {
-            StringTableEntry assetID = qry->mAssetList[c];
-
-            ComponentAsset* compAsset = assetDB->acquireAsset<ComponentAsset>(assetID);
-
-            String compAssetClass = compAsset->getComponentName();
-            if (componentClass == compAssetClass)
-            {
-               compName = compAsset->getFriendlyName();
-               break;
-            }
-         }
-      }
-
-      S32 compID = editorTree->insertItem(componentID, compName);
-      newItem = editorTree->getItem(compID);
-      newItem->mInspectorInfo.mObject = mComponents[i];
-      newItem->mState.set(GuiTreeViewCtrl::Item::ForceItemName);
-      newItem->mState.set(GuiTreeViewCtrl::Item::DenyDrag);
-      newItem->mState.set(GuiTreeViewCtrl::Item::InspectorData);
-   }
-
-   editorTree->buildVisibleTree(true);
 }
 }
 
 
 void Entity::onEndInspect()
 void Entity::onEndInspect()
@@ -1615,6 +1480,21 @@ void Entity::updateContainer()
 }
 }
 //
 //
 
 
+void Entity::notifyComponents(String signalFunction, String argA, String argB, String argC, String argD, String argE)
+{
+   for (U32 i = 0; i < mComponents.size(); i++)
+   {
+      // We can do this because both are in the string table
+      Component *comp = mComponents[i];
+
+      if (comp->isActive())
+      {
+         if (comp->isMethod(signalFunction))
+            Con::executef(comp, signalFunction, argA, argB, argC, argD, argE);
+      }
+   }
+}
+
 void Entity::setComponentsDirty()
 void Entity::setComponentsDirty()
 {
 {
    if (mToLoadComponents.empty())
    if (mToLoadComponents.empty())
@@ -1833,7 +1713,6 @@ DefineConsoleMethod(Entity, getComponent, S32, (String componentName), (""),
    Component *comp = object->getComponent(componentName);
    Component *comp = object->getComponent(componentName);
 
 
    return (comp != NULL) ? comp->getId() : 0;
    return (comp != NULL) ? comp->getId() : 0;
-   return 0;
 }
 }
 
 
 /*ConsoleMethod(Entity, getBehaviorByType, S32, 3, 3, "(string BehaviorTemplateName) - gets a behavior\n"
 /*ConsoleMethod(Entity, getBehaviorByType, S32, 3, 3, "(string BehaviorTemplateName) - gets a behavior\n"
@@ -1917,6 +1796,15 @@ DefineConsoleMethod(Entity, getMoveTrigger, bool, (S32 triggerNum), (0),
    return false;
    return false;
 }
 }
 
 
+DefineEngineMethod(Entity, getForwardVector, VectorF, (), ,
+   "Get the direction this object is facing.\n"
+   "@return a vector indicating the direction this object is facing.\n"
+   "@note This is the object's y axis.")
+{
+   VectorF forVec = object->getTransform().getForwardVector();
+   return forVec;
+}
+
 DefineConsoleMethod(Entity, setForwardVector, void, (VectorF newForward), (VectorF(0,0,0)),
 DefineConsoleMethod(Entity, setForwardVector, void, (VectorF newForward), (VectorF(0,0,0)),
    "Get the number of static fields on the object.\n"
    "Get the number of static fields on the object.\n"
    "@return The number of static fields defined on the object.")
    "@return The number of static fields defined on the object.")
@@ -1936,4 +1824,14 @@ DefineConsoleMethod(Entity, rotateTo, void, (Point3F lookPosition, F32 degreePer
    "@return The number of static fields defined on the object.")
    "@return The number of static fields defined on the object.")
 {
 {
    //object->setForwardVector(newForward);
    //object->setForwardVector(newForward);
+}
+
+DefineConsoleMethod(Entity, notify, void, (String signalFunction, String argA, String argB, String argC, String argD, String argE),
+("", "", "", "", "", ""),
+"Triggers a signal call to all components for a certain function.")
+{
+   if (signalFunction == String(""))
+      return;
+
+   object->notifyComponents(signalFunction, argA, argB, argC, argD, argE);
 }
 }

+ 19 - 7
Engine/source/T3D/entity.h

@@ -35,6 +35,12 @@
 #ifndef _CONTAINERQUERY_H_
 #ifndef _CONTAINERQUERY_H_
 #include "T3D/containerQuery.h"
 #include "T3D/containerQuery.h"
 #endif
 #endif
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif 
+#ifndef GAME_OBJECT_ASSET_H
+#include "T3D/assets/GameObjectAsset.h"
+#endif
 
 
 class Component;
 class Component;
 
 
@@ -56,6 +62,9 @@ private:
 
 
    bool                       mStartComponentUpdate;
    bool                       mStartComponentUpdate;
 
 
+   StringTableEntry		      mGameObjectAssetId;
+   AssetPtr<GameObjectAsset>  mGameObjectAsset;
+
    ContainerQueryInfo containerInfo;
    ContainerQueryInfo containerInfo;
 
 
    bool mInitialized;
    bool mInitialized;
@@ -98,7 +107,8 @@ public:
       BoundsMask = Parent::NextFreeMask << 1,
       BoundsMask = Parent::NextFreeMask << 1,
       ComponentsMask = Parent::NextFreeMask << 2,
       ComponentsMask = Parent::NextFreeMask << 2,
       NoWarpMask = Parent::NextFreeMask << 3,
       NoWarpMask = Parent::NextFreeMask << 3,
-      NextFreeMask = Parent::NextFreeMask << 4
+      NamespaceMask = Parent::NextFreeMask << 4,
+      NextFreeMask = Parent::NextFreeMask << 5
    };
    };
 
 
    StateDelta mDelta;
    StateDelta mDelta;
@@ -123,16 +133,14 @@ public:
    virtual MatrixF getTransform();
    virtual MatrixF getTransform();
    virtual Point3F getPosition() const { return mPos; }
    virtual Point3F getPosition() const { return mPos; }
 
 
-   //void setTransform(Point3F position, RotationF rot);
-
-   //void setRotation(RotationF rotation);
-
    void setRotation(RotationF rotation) {
    void setRotation(RotationF rotation) {
       mRot = rotation;
       mRot = rotation;
       setMaskBits(TransformMask);
       setMaskBits(TransformMask);
    };
    };
    RotationF getRotation() { return mRot; }
    RotationF getRotation() { return mRot; }
 
 
+   static bool _setGameObject(void *object, const char *index, const char *data);
+
    void setMountOffset(Point3F posOffset);
    void setMountOffset(Point3F posOffset);
    void setMountRotation(EulerF rotOffset);
    void setMountRotation(EulerF rotOffset);
 
 
@@ -146,13 +154,15 @@ public:
    virtual void getMountTransform(S32 index, const MatrixF &xfm, MatrixF *outMat);
    virtual void getMountTransform(S32 index, const MatrixF &xfm, MatrixF *outMat);
    virtual void getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat);
    virtual void getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat);
 
 
-   void setForwardVector(VectorF newForward, VectorF upVector = VectorF::Zero);
-
    virtual void mountObject(SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity);
    virtual void mountObject(SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity);
    void mountObject(SceneObject* objB, MatrixF txfm);
    void mountObject(SceneObject* objB, MatrixF txfm);
    void onMount(SceneObject *obj, S32 node);
    void onMount(SceneObject *obj, S32 node);
    void onUnmount(SceneObject *obj, S32 node);
    void onUnmount(SceneObject *obj, S32 node);
 
 
+   /// Sets the client controlling this object
+   /// @param  client   Client that is now controlling this object
+   virtual void setControllingClient(GameConnection *client);
+
    // NetObject
    // NetObject
    U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
    U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
    void unpackUpdate(NetConnection *conn, BitStream *stream);
    void unpackUpdate(NetConnection *conn, BitStream *stream);
@@ -163,6 +173,8 @@ public:
    //Components
    //Components
    virtual bool deferAddingComponents() const { return true; }
    virtual bool deferAddingComponents() const { return true; }
 
 
+   void notifyComponents(String signalFunction, String argA, String argB, String argC, String argD, String argE);
+
    template <class T>
    template <class T>
    T* getComponent();
    T* getComponent();
    template <class T>
    template <class T>