diff --git a/Engine/source/T3D/components/component.cpp b/Engine/source/T3D/components/component.cpp index 47784d4b2..cbb2305c1 100644 --- a/Engine/source/T3D/components/component.cpp +++ b/Engine/source/T3D/components/component.cpp @@ -42,13 +42,13 @@ 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; @@ -64,6 +64,8 @@ Component::Component() mCanSaveFieldDictionary = false; + mOriginatingAssetId = StringTable->EmptyString(); + 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); 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"); Parent::initPersistFields(); @@ -149,6 +155,7 @@ bool Component::onAdd() return false; setMaskBits(UpdateMask); + setMaskBits(NamespaceMask); return true; } @@ -274,6 +281,19 @@ U32 Component::packUpdate(NetConnection *con, U32 mask, BitStream *stream) 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; } @@ -303,6 +323,32 @@ void Component::unpackUpdate(NetConnection *con, BitStream *stream) { 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 */) @@ -346,6 +392,10 @@ void Component::setDataField(StringTableEntry slotName, const char *array, const onDataSet.trigger(this, slotName, value); } +StringTableEntry Component::getComponentName() +{ + return getNamespace()->getName(); +} //catch any behavior field updates 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; else if (fieldType == StringTable->insert("object")) 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 fieldTypeMask = TypeString; @@ -603,6 +663,17 @@ ConsoleMethod(Component, setComponentield, const char *, 3, 3, "(int index) - Ge 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" "@param index The index of the behavior\n" "@return Returns a string representing the user data of this field\n") diff --git a/Engine/source/T3D/components/component.h b/Engine/source/T3D/components/component.h index 0259bacd0..4f84de17f 100644 --- a/Engine/source/T3D/components/component.h +++ b/Engine/source/T3D/components/component.h @@ -32,14 +32,22 @@ #ifndef CORE_INTERFACES_H #include "T3D/components/coreInterfaces.h" #endif +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif +#ifndef COMPONENT_ASSET_H +#include "T3D/assets/ComponentAsset.h" +#endif class Entity; +class Namespace; struct ComponentField { StringTableEntry mFieldName; StringTableEntry mFieldDescription; + StringTableEntry mFieldTypeName; S32 mFieldType; StringTableEntry mUserData; @@ -81,6 +89,9 @@ protected: bool mHidden; bool mEnabled; + StringTableEntry mOriginatingAssetId; + AssetPtr mOriginatingAsset; + public: Component(); virtual ~Component(); @@ -175,7 +186,8 @@ public: OwnerMask = BIT(1), UpdateMask = BIT(2), EnableMask = BIT(3), - NextFreeMask = BIT(4) + NamespaceMask = BIT(4), + NextFreeMask = BIT(5) }; virtual U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream); @@ -192,6 +204,8 @@ public: void checkComponentFieldModified(const char* slotName, const char* newValue); virtual void checkDependencies(){} + + StringTableEntry getComponentName(); }; #endif // COMPONENT_H diff --git a/Engine/source/T3D/components/render/meshComponent.cpp b/Engine/source/T3D/components/render/meshComponent.cpp index 708a48ae1..c9eeee3c3 100644 --- a/Engine/source/T3D/components/render/meshComponent.cpp +++ b/Engine/source/T3D/components/render/meshComponent.cpp @@ -34,7 +34,6 @@ #include "lighting/lightQuery.h" #include "scene/sceneManager.h" #include "gfx/bitmap/ddsFile.h" -#include "gfx/bitmap/ddsUtils.h" #include "gfx/gfxTextureManager.h" #include "materials/materialFeatureTypes.h" #include "renderInstance/renderImposterMgr.h" diff --git a/Engine/source/T3D/entity.cpp b/Engine/source/T3D/entity.cpp index 00ecedad0..b81974cfe 100644 --- a/Engine/source/T3D/entity.cpp +++ b/Engine/source/T3D/entity.cpp @@ -51,6 +51,7 @@ // #include "gfx/sim/debugDraw.h" // +#include "T3D/sfx/sfx3DWorld.h" extern bool gEditingMission; @@ -117,6 +118,8 @@ Entity::Entity() mInitialized = false; + mGameObjectAssetId = StringTable->insert(""); + } 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 )."); 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()) 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(); setObjectBox(mObjBox); @@ -224,6 +232,7 @@ bool Entity::onAdd() //Make sure we get positioned setMaskBits(TransformMask); + setMaskBits(NamespaceMask); return true; } @@ -253,6 +262,16 @@ void Entity::onPostAdd() Con::executef(this, "onAdd"); } +bool Entity::_setGameObject(void *object, const char *index, const char *data) +{ + Entity *e = static_cast(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) { 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"); + + // 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)) { - //mathWrite( *stream, getScale() ); - //stream->writeAffineTransform(mObjToWorld); - //mathWrite(*stream, getPosition()); - //mathWrite(*stream, mPos); - stream->writeCompressedPoint(mPos); mathWrite(*stream, getRotation()); @@ -415,12 +441,6 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream) stream->writeFlag(!(mask & NoWarpMask)); } - /*if (stream->writeFlag(mask & MountedMask)) - { - mathWrite(*stream, mMount.xfm.getPosition()); - mathWrite(*stream, mMount.xfm.toEuler()); - }*/ - if (stream->writeFlag(mask & BoundsMask)) { mathWrite(*stream, mObjBox); @@ -483,6 +503,19 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream) else 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; } @@ -492,20 +525,10 @@ void Entity::unpackUpdate(NetConnection *con, BitStream *stream) if (stream->readFlag()) { - /*Point3F scale; - mathRead( *stream, &scale ); - setScale( scale);*/ - - //MatrixF objToWorld; - //stream->readAffineTransform(&objToWorld); - Point3F pos; - stream->readCompressedPoint(&pos); - //mathRead(*stream, &pos); RotationF rot; - mathRead(*stream, &rot); 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 // 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; 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()) { 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 void Entity::setTransform(const MatrixF &mat) { - //setMaskBits(TransformMask); - setMaskBits(TransformMask | NoWarpMask); + MatrixF oldTransform = getTransform(); if (isMounted()) { @@ -687,25 +655,20 @@ void Entity::setTransform(const MatrixF &mat) if (!newOffset.isZero()) { - //setMountOffset(newOffset); mPos = newOffset; } Point3F matEul = mat.toEuler(); - //mRot = Point3F(mRadToDeg(matEul.x), mRadToDeg(matEul.y), mRadToDeg(matEul.z)); - if (matEul != Point3F(0, 0, 0)) { Point3F mountEul = mMount.object->getTransform().toEuler(); Point3F diff = matEul - mountEul; - //setMountRotation(Point3F(mRadToDeg(diff.x), mRadToDeg(diff.y), mRadToDeg(diff.z))); mRot = diff; } else { - //setMountRotation(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()); Parent::setTransform(transf); + + if (transf != oldTransform) + setMaskBits(TransformMask); } else { @@ -744,6 +710,8 @@ void Entity::setTransform(const MatrixF &mat) void Entity::setTransform(Point3F position, RotationF rotation) { + MatrixF oldTransform = getTransform(); + if (isMounted()) { mPos = position; @@ -755,7 +723,8 @@ void Entity::setTransform(Point3F position, RotationF rotation) Parent::setTransform(transf); - setMaskBits(TransformMask); + if (transf != oldTransform) + setMaskBits(TransformMask); } else { @@ -774,7 +743,6 @@ void Entity::setTransform(Point3F position, RotationF rotation) mPos = position; mRot = rotation; - setMaskBits(TransformMask); //if (isServerObject()) // setMaskBits(TransformMask); @@ -788,19 +756,18 @@ void Entity::setTransform(Point3F position, RotationF rotation) //PROFILE_SCOPE(Entity_setTransform); // Update the transforms. - Parent::setTransform(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()); mMount.xfm = temp; - //mRot = RotationF(temp); + setMaskBits(MountedMask); } } @@ -964,63 +931,6 @@ void Entity::getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, M 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 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 void Entity::addObject(SimObject* object) { @@ -1261,9 +1193,8 @@ bool Entity::removeComponent(Component *comp, bool deleteComponent) onComponentRemoved.trigger(comp); - comp->setOwner(NULL); - comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner + comp->setOwner(NULL); if (deleteComponent) comp->safeDeleteObject(); @@ -1364,72 +1295,6 @@ void Entity::onInspect() { (*it)->onInspect(); } - - GuiTreeViewCtrl *editorTree = dynamic_cast(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(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(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() @@ -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() { if (mToLoadComponents.empty()) @@ -1833,7 +1713,6 @@ DefineConsoleMethod(Entity, getComponent, S32, (String componentName), (""), Component *comp = object->getComponent(componentName); return (comp != NULL) ? comp->getId() : 0; - return 0; } /*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; } +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)), "Get the number of static fields on the object.\n" "@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.") { //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); } \ No newline at end of file diff --git a/Engine/source/T3D/entity.h b/Engine/source/T3D/entity.h index 52818f6f9..1f160e5a9 100644 --- a/Engine/source/T3D/entity.h +++ b/Engine/source/T3D/entity.h @@ -35,6 +35,12 @@ #ifndef _CONTAINERQUERY_H_ #include "T3D/containerQuery.h" #endif +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif +#ifndef GAME_OBJECT_ASSET_H +#include "T3D/assets/GameObjectAsset.h" +#endif class Component; @@ -56,6 +62,9 @@ private: bool mStartComponentUpdate; + StringTableEntry mGameObjectAssetId; + AssetPtr mGameObjectAsset; + ContainerQueryInfo containerInfo; bool mInitialized; @@ -98,7 +107,8 @@ public: BoundsMask = Parent::NextFreeMask << 1, ComponentsMask = Parent::NextFreeMask << 2, NoWarpMask = Parent::NextFreeMask << 3, - NextFreeMask = Parent::NextFreeMask << 4 + NamespaceMask = Parent::NextFreeMask << 4, + NextFreeMask = Parent::NextFreeMask << 5 }; StateDelta mDelta; @@ -123,16 +133,14 @@ public: virtual MatrixF getTransform(); virtual Point3F getPosition() const { return mPos; } - //void setTransform(Point3F position, RotationF rot); - - //void setRotation(RotationF rotation); - void setRotation(RotationF rotation) { mRot = rotation; setMaskBits(TransformMask); }; RotationF getRotation() { return mRot; } + static bool _setGameObject(void *object, const char *index, const char *data); + void setMountOffset(Point3F posOffset); void setMountRotation(EulerF rotOffset); @@ -146,13 +154,15 @@ public: virtual void getMountTransform(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); void mountObject(SceneObject* objB, MatrixF txfm); void onMount(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 U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream); void unpackUpdate(NetConnection *conn, BitStream *stream); @@ -163,6 +173,8 @@ public: //Components virtual bool deferAddingComponents() const { return true; } + void notifyComponents(String signalFunction, String argA, String argB, String argC, String argD, String argE); + template T* getComponent(); template