enhanced-physical-zone -- PhysicalZone object enhanced to allow orientation add radial forces.

pz-opt -- PhysicalZone network optimizations.
This commit is contained in:
Marc Chapman 2017-07-27 01:10:20 +01:00
parent ab88b8f489
commit a7c7b67c85
3 changed files with 244 additions and 28 deletions

View file

@ -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);
}
}

View file

@ -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);
setPolyhedron(tempPH);
setScale(tempScale);
setTransform(temp);
mActive = stream->readFlag();
} else {
mActive = stream->readFlag();
force_type = stream->readInt(FORCE_TYPE_BITS); // AFX
orient_force = stream->readFlag(); // AFX
}
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;
}
}

View file

@ -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