Răsfoiți Sursa

enhanced-physical-zone -- PhysicalZone object enhanced to allow orientation add radial forces.
pz-opt -- PhysicalZone network optimizations.

Marc Chapman 8 ani în urmă
părinte
comite
a7c7b67c85

+ 8 - 1
Engine/source/T3D/containerQuery.cpp

@@ -20,6 +20,11 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
+// Copyright (C) 2015 Faust Logic, Inc.
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+
 #include "platform/platform.h"
 #include "T3D/containerQuery.h"
 
@@ -91,7 +96,9 @@ void physicalZoneFind(SceneObject* obj, void *key)
 
    if (pz->isActive()) {
       info->gravityScale *= pz->getGravityMod();
-      info->appliedForce += pz->getForce();
+      Point3F center; 
+      info->box.getCenter(&center);
+      info->appliedForce += pz->getForce(&center);
    }
 }
 

+ 201 - 23
Engine/source/T3D/physicalZone.cpp

@@ -20,6 +20,11 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
+// Copyright (C) 2015 Faust Logic, Inc.
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+
 #include "T3D/physicalZone.h"
 #include "core/stream/bitStream.h"
 #include "collision/boxConvex.h"
@@ -33,6 +38,8 @@
 #include "gfx/gfxDrawUtil.h"
 #include "console/engineAPI.h"
 
+//#include "console/engineTypes.h"
+#include "sim/netConnection.h"
 IMPLEMENT_CO_NETOBJECT_V1(PhysicalZone);
 
 ConsoleDocClass( PhysicalZone,
@@ -103,6 +110,10 @@ PhysicalZone::PhysicalZone()
 
    mConvexList = new Convex;
    mActive = true;
+   force_type = VECTOR;
+   force_mag = 0.0f;
+   orient_force = false;
+   fade_amt = 1.0f;
 }
 
 PhysicalZone::~PhysicalZone()
@@ -111,6 +122,16 @@ PhysicalZone::~PhysicalZone()
    mConvexList = NULL;
 }
 
+
+ImplementEnumType( PhysicalZone_ForceType, "Possible physical zone force types.\n" "@ingroup PhysicalZone\n\n" )
+   { PhysicalZone::VECTOR,          "vector",        "..." },
+   { PhysicalZone::SPHERICAL,       "spherical",     "..." },
+   { PhysicalZone::CYLINDRICAL,     "cylindrical",   "..." },
+   // aliases
+   { PhysicalZone::SPHERICAL,       "sphere",        "..." },
+   { PhysicalZone::CYLINDRICAL,     "cylinder",      "..." },
+EndImplementEnumType;
+
 //--------------------------------------------------------------------------
 void PhysicalZone::consoleInit()
 {
@@ -129,6 +150,10 @@ void PhysicalZone::initPersistFields()
       "point followed by three vectors representing the edges extending from the corner." );
    endGroup("Misc");
 
+   addGroup("AFX");
+   addField("forceType", TYPEID<PhysicalZone::ForceType>(), Offset(force_type, PhysicalZone));
+   addField("orientForce", TypeBool, Offset(orient_force, PhysicalZone));
+   endGroup("AFX");
    Parent::initPersistFields();
 }
 
@@ -158,6 +183,19 @@ bool PhysicalZone::onAdd()
    Polyhedron temp = mPolyhedron;
    setPolyhedron(temp);
 
+   switch (force_type)
+   {
+   case SPHERICAL:
+      force_mag = mAppliedForce.magnitudeSafe();
+      break;
+   case CYLINDRICAL:
+      {
+         Point3F force_vec = mAppliedForce;
+         force_vec.z = 0.0;
+         force_mag = force_vec.magnitudeSafe();
+      }
+      break;
+   }
    addToScene();
 
    return true;
@@ -191,7 +229,7 @@ void PhysicalZone::setTransform(const MatrixF & mat)
       mClippedList.setBaseTransform(base);
 
    if (isServerObject())
-      setMaskBits(InitialUpdateMask);
+      setMaskBits(MoveMask);
 }
 
 
@@ -242,12 +280,8 @@ U32 PhysicalZone::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
    U32 i;
    U32 retMask = Parent::packUpdate(con, mask, stream);
 
-   if (stream->writeFlag((mask & InitialUpdateMask) != 0)) {
-      // Note that we don't really care about efficiency here, since this is an
-      //  edit-only ghost...
-      mathWrite(*stream, mObjToWorld);
-      mathWrite(*stream, mObjScale);
-
+   if (stream->writeFlag(mask & PolyhedronMask)) 
+   {
       // Write the polyhedron
       stream->write(mPolyhedron.pointList.size());
       for (i = 0; i < mPolyhedron.pointList.size(); i++)
@@ -266,15 +300,33 @@ U32 PhysicalZone::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
          stream->write(rEdge.vertex[0]);
          stream->write(rEdge.vertex[1]);
       }
+   }
+
+   if (stream->writeFlag(mask & MoveMask))
+   {
+      stream->writeAffineTransform(mObjToWorld);
+      mathWrite(*stream, mObjScale);
+   }
 
+   if (stream->writeFlag(mask & SettingsMask))
+   {
       stream->write(mVelocityMod);
       stream->write(mGravityMod);
       mathWrite(*stream, mAppliedForce);
-      stream->writeFlag(mActive);
-   } else {
-      stream->writeFlag(mActive);
+      stream->writeInt(force_type, FORCE_TYPE_BITS);
+      stream->writeFlag(orient_force);
+   }
+
+   if (stream->writeFlag(mask & FadeMask))
+   {
+      U8 fade_byte = (U8)(fade_amt*255.0f);
+      stream->write(fade_byte);
    }
 
+   stream->writeFlag(mActive);
+
+   // AFX CODE BLOCK (enhanced-physical-zone)(pz-opt) >>
+
    return retMask;
 }
 
@@ -282,16 +334,12 @@ void PhysicalZone::unpackUpdate(NetConnection* con, BitStream* stream)
 {
    Parent::unpackUpdate(con, stream);
 
-   if (stream->readFlag()) {
+   bool new_ph = false;
+   if (stream->readFlag()) // PolyhedronMask
+   {
       U32 i, size;
-      MatrixF temp;
-      Point3F tempScale;
       Polyhedron tempPH;
 
-      // Transform
-      mathRead(*stream, &temp);
-      mathRead(*stream, &tempScale);
-
       // Read the polyhedron
       stream->read(&size);
       tempPH.pointList.setSize(size);
@@ -314,17 +362,46 @@ void PhysicalZone::unpackUpdate(NetConnection* con, BitStream* stream)
          stream->read(&rEdge.vertex[1]);
       }
 
+      setPolyhedron(tempPH);
+      new_ph = true;
+   }
+
+   if (stream->readFlag()) // MoveMask
+   {
+      MatrixF temp;
+      stream->readAffineTransform(&temp);
+
+      Point3F tempScale;
+      mathRead(*stream, &tempScale);
+
+      //if (!new_ph)
+      //{
+      //  Polyhedron rPolyhedron = mPolyhedron;
+      //  setPolyhedron(rPolyhedron);
+      //}
+      setScale(tempScale);
+      setTransform(temp);
+   }
+
+   if (stream->readFlag()) //SettingsMask
+   {
       stream->read(&mVelocityMod);
       stream->read(&mGravityMod);
       mathRead(*stream, &mAppliedForce);
+      force_type = stream->readInt(FORCE_TYPE_BITS); // AFX
+      orient_force = stream->readFlag(); // AFX
+   }
 
-      setPolyhedron(tempPH);
-      setScale(tempScale);
-      setTransform(temp);
-      mActive = stream->readFlag();
-   } else {
-      mActive = stream->readFlag();
+   if (stream->readFlag()) //FadeMask
+   {
+      U8 fade_byte;
+      stream->read(&fade_byte);
+      fade_amt = ((F32)fade_byte)/255.0f;
    }
+   else
+      fade_amt = 1.0f;
+
+   mActive = stream->readFlag();
 }
 
 
@@ -443,3 +520,104 @@ void PhysicalZone::deactivate()
    mActive = false;
 }
 
+void PhysicalZone::onStaticModified(const char* slotName, const char*newValue)
+{
+   if (dStricmp(slotName, "appliedForce") == 0 || dStricmp(slotName, "forceType") == 0)
+   {
+      switch (force_type)
+      {
+      case SPHERICAL:
+         force_mag = mAppliedForce.magnitudeSafe();
+         break;
+      case CYLINDRICAL:
+         {
+            Point3F force_vec = mAppliedForce;
+            force_vec.z = 0.0;
+            force_mag = force_vec.magnitudeSafe();
+         }
+         break;
+      }
+   }
+}
+
+const Point3F& PhysicalZone::getForce(const Point3F* center) const 
+{ 
+   static Point3F force_vec;
+
+   if (force_type == VECTOR)
+   {
+      if (orient_force)
+      {
+         getTransform().mulV(mAppliedForce, &force_vec);
+         force_vec *= fade_amt;
+         return force_vec; 
+      }
+      force_vec = mAppliedForce;
+      force_vec *= fade_amt;
+      return force_vec;
+   }
+
+   if (!center)
+   {
+      force_vec.zero();
+      return force_vec; 
+   }
+
+   if (force_type == SPHERICAL)
+   {
+      force_vec = *center - getPosition();
+      force_vec.normalizeSafe();
+      force_vec *= force_mag*fade_amt;
+      return force_vec;
+   }
+
+   if (orient_force)
+   {
+      force_vec = *center - getPosition();
+      getWorldTransform().mulV(force_vec);
+      force_vec.z = 0.0f;
+      force_vec.normalizeSafe();
+      force_vec *= force_mag;
+      force_vec.z = mAppliedForce.z;
+      getTransform().mulV(force_vec);
+      force_vec *= fade_amt;
+      return force_vec;
+   }
+
+   force_vec = *center - getPosition();
+   force_vec.z = 0.0f;
+   force_vec.normalizeSafe();
+   force_vec *= force_mag;
+   force_vec *= fade_amt;
+   return force_vec;
+}
+
+bool PhysicalZone::isExcludedObject(SceneObject* obj) const
+{
+   for (S32 i = 0; i < excluded_objects.size(); i++)
+      if (excluded_objects[i] == obj)
+         return true;
+
+   return false;
+}
+
+void PhysicalZone::registerExcludedObject(SceneObject* obj)
+{
+   if (isExcludedObject(obj))
+      return;
+
+   excluded_objects.push_back(obj);
+   setMaskBits(FadeMask);
+}
+
+void PhysicalZone::unregisterExcludedObject(SceneObject* obj)
+{
+   for (S32 i = 0; i < excluded_objects.size(); i++)
+      if (excluded_objects[i] == obj)
+      {
+         excluded_objects.erase(i);
+         setMaskBits(FadeMask);
+         return;
+      }
+}
+

+ 34 - 3
Engine/source/T3D/physicalZone.h

@@ -20,6 +20,11 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
+// Copyright (C) 2015 Faust Logic, Inc.
+//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+
 #ifndef _H_PHYSICALZONE
 #define _H_PHYSICALZONE
 
@@ -40,9 +45,14 @@ class PhysicalZone : public SceneObject
 {
    typedef SceneObject Parent;
 
-   enum UpdateMasks {      
+   enum UpdateMasks {
       ActiveMask        = Parent::NextFreeMask << 0,
-      NextFreeMask      = Parent::NextFreeMask << 1
+      SettingsMask      = Parent::NextFreeMask << 1,
+      FadeMask          = Parent::NextFreeMask << 2,
+      PolyhedronMask    = Parent::NextFreeMask << 3,
+      MoveMask          = Parent::NextFreeMask << 4,
+      ExclusionMask     = Parent::NextFreeMask << 5,
+      NextFreeMask      = Parent::NextFreeMask << 6
    };
 
   protected:
@@ -83,7 +93,10 @@ class PhysicalZone : public SceneObject
 
    inline F32 getVelocityMod() const      { return mVelocityMod; }
    inline F32 getGravityMod()  const      { return mGravityMod;  }
-   inline const Point3F& getForce() const { return mAppliedForce; }
+   // the scene object is now passed in to getForce() where
+   // it is needed to calculate the applied force when the
+   // force is radial.
+   const Point3F& getForce(const Point3F* center=0) const;
 
    void setPolyhedron(const Polyhedron&);
    bool testObject(SceneObject*);
@@ -96,7 +109,25 @@ class PhysicalZone : public SceneObject
    void deactivate();
    inline bool isActive() const { return mActive; }
 
+protected:
+   friend class afxPhysicalZoneData;
+   friend class afxEA_PhysicalZone;
+   Vector<SceneObject*>  excluded_objects;
+   S32    force_type;
+   F32    force_mag;
+   bool   orient_force;
+   F32    fade_amt;
+   void   setFadeAmount(F32 amt) { fade_amt = amt; if (fade_amt < 1.0f) setMaskBits(FadeMask); }
+public:
+   enum ForceType { VECTOR, SPHERICAL, CYLINDRICAL };
+   enum { FORCE_TYPE_BITS = 2 };
+   virtual void onStaticModified(const char* slotName, const char*newValue = NULL);
+   bool   isExcludedObject(SceneObject*) const;
+   void   registerExcludedObject(SceneObject*);
+   void   unregisterExcludedObject(SceneObject*);
 };
 
+typedef PhysicalZone::ForceType PhysicalZone_ForceType;
+DefineEnumType( PhysicalZone_ForceType );
 #endif // _H_PHYSICALZONE