mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-10 22:24:33 +00:00
Merge remote-tracking branch 'GG-Github/development' into fix_opengl_new_terrain_blend
This commit is contained in:
commit
ff83e8c209
1455 changed files with 98353 additions and 15020 deletions
|
|
@ -147,6 +147,7 @@ ConsoleFunction(aiConnect, S32 , 2, 20, "(...)"
|
|||
// Make sure and leav args[1] empty.
|
||||
const char* args[21];
|
||||
args[0] = "onConnect";
|
||||
args[1] = NULL; // Filled in later
|
||||
for (S32 i = 1; i < argc; i++)
|
||||
args[i + 1] = argv[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ void CameraSpline::renderTimeMap()
|
|||
|
||||
// Render the buffer
|
||||
GFX->pushWorldMatrix();
|
||||
GFX->disableShaders();
|
||||
GFX->setupGenericShaders();
|
||||
GFX->setVertexBuffer(vb);
|
||||
GFX->drawPrimitive(GFXLineStrip,0,index);
|
||||
GFX->popWorldMatrix();
|
||||
|
|
|
|||
|
|
@ -1666,7 +1666,7 @@ void Precipitation::renderObject(ObjectRenderInst *ri, SceneRenderState *state,
|
|||
}
|
||||
else
|
||||
{
|
||||
GFX->disableShaders();
|
||||
GFX->setupGenericShaders(GFXDevice::GSTexture);
|
||||
|
||||
// We don't support distance fade or lighting without shaders.
|
||||
GFX->setStateBlock(mDistantSB);
|
||||
|
|
@ -1799,7 +1799,7 @@ void Precipitation::renderObject(ObjectRenderInst *ri, SceneRenderState *state,
|
|||
GFX->setShaderConstBuffer(mSplashShaderConsts);
|
||||
}
|
||||
else
|
||||
GFX->disableShaders();
|
||||
GFX->setupGenericShaders(GFXDevice::GSTexture);
|
||||
|
||||
while (curr)
|
||||
{
|
||||
|
|
|
|||
707
Engine/source/T3D/fx/ribbon.cpp
Normal file
707
Engine/source/T3D/fx/ribbon.cpp
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/typeValidators.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "T3D/shapeBase.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "T3D/fx/ribbon.h"
|
||||
#include "math/mathUtils.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "materials/matInstance.h"
|
||||
#include "gui/3d/guiTSControl.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/processedShaderMaterial.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(RibbonData);
|
||||
IMPLEMENT_CO_NETOBJECT_V1(Ribbon);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
RibbonData::RibbonData()
|
||||
{
|
||||
for (U8 i = 0; i < NumFields; i++) {
|
||||
mSizes[i] = 0.0f;
|
||||
mColours[i].set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
mTimes[i] = -1.0f;
|
||||
}
|
||||
|
||||
mRibbonLength = 0;
|
||||
mUseFadeOut = false;
|
||||
mFadeAwayStep = 0.032f;
|
||||
segmentsPerUpdate = 1;
|
||||
mMatName = StringTable->insert("");
|
||||
mTileScale = 1.0f;
|
||||
mFixedTexcoords = false;
|
||||
mSegmentSkipAmount = 0;
|
||||
mTexcoordsRelativeToDistance = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void RibbonData::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addGroup("Ribbon");
|
||||
|
||||
addField("size", TypeF32, Offset(mSizes, RibbonData), NumFields,
|
||||
"The size of the ribbon at the specified keyframe.");
|
||||
addField("color", TypeColorF, Offset(mColours, RibbonData), NumFields,
|
||||
"The colour of the ribbon at the specified keyframe.");
|
||||
addField("position", TypeF32, Offset(mTimes, RibbonData), NumFields,
|
||||
"The position of the keyframe along the lifetime of the ribbon.");
|
||||
|
||||
addField("ribbonLength", TypeS32, Offset(mRibbonLength, RibbonData),
|
||||
"The amount of segments the Ribbon can maximally have in length.");
|
||||
addField("segmentsPerUpdate", TypeS32, Offset(segmentsPerUpdate, RibbonData),
|
||||
"How many segments to add each update.");
|
||||
addField("skipAmount", TypeS32, Offset(mSegmentSkipAmount, RibbonData),
|
||||
"The amount of segments to skip each update.");
|
||||
|
||||
addField("useFadeOut", TypeBool, Offset(mUseFadeOut, RibbonData),
|
||||
"If true, the ribbon will fade away after deletion.");
|
||||
addField("fadeAwayStep", TypeF32, Offset(mFadeAwayStep, RibbonData),
|
||||
"How much to fade the ribbon with each update, after deletion.");
|
||||
addField("ribbonMaterial", TypeString, Offset(mMatName, RibbonData),
|
||||
"The material the ribbon uses for rendering.");
|
||||
addField("tileScale", TypeF32, Offset(mTileScale, RibbonData),
|
||||
"How much to scale each 'tile' with, where 1 means the material is stretched"
|
||||
"across the whole ribbon. (If TexcoordsRelativeToDistance is true, this is in meters.)");
|
||||
addField("fixedTexcoords", TypeBool, Offset(mFixedTexcoords, RibbonData),
|
||||
"If true, this prevents 'floating' texture coordinates.");
|
||||
addField("texcoordsRelativeToDistance", TypeBool, Offset(mTexcoordsRelativeToDistance, RibbonData),
|
||||
"If true, texture coordinates are scaled relative to distance, this prevents"
|
||||
"'stretched' textures.");
|
||||
|
||||
endGroup("Ribbon");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool RibbonData::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RibbonData::preload(bool server, String &errorBuffer)
|
||||
{
|
||||
if (Parent::preload(server, errorBuffer) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void RibbonData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
for (U8 i = 0; i < NumFields; i++) {
|
||||
stream->write(mSizes[i]);
|
||||
stream->write(mColours[i]);
|
||||
stream->write(mTimes[i]);
|
||||
}
|
||||
|
||||
stream->write(mRibbonLength);
|
||||
stream->writeString(mMatName);
|
||||
stream->writeFlag(mUseFadeOut);
|
||||
stream->write(mFadeAwayStep);
|
||||
stream->write(segmentsPerUpdate);
|
||||
stream->write(mTileScale);
|
||||
stream->writeFlag(mFixedTexcoords);
|
||||
stream->writeFlag(mTexcoordsRelativeToDistance);
|
||||
}
|
||||
|
||||
void RibbonData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
for (U8 i = 0; i < NumFields; i++) {
|
||||
stream->read(&mSizes[i]);
|
||||
stream->read(&mColours[i]);
|
||||
stream->read(&mTimes[i]);
|
||||
}
|
||||
|
||||
stream->read(&mRibbonLength);
|
||||
mMatName = StringTable->insert(stream->readSTString());
|
||||
mUseFadeOut = stream->readFlag();
|
||||
stream->read(&mFadeAwayStep);
|
||||
stream->read(&segmentsPerUpdate);
|
||||
stream->read(&mTileScale);
|
||||
mFixedTexcoords = stream->readFlag();
|
||||
mTexcoordsRelativeToDistance = stream->readFlag();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------
|
||||
//
|
||||
Ribbon::Ribbon()
|
||||
{
|
||||
mTypeMask |= StaticObjectType;
|
||||
|
||||
VECTOR_SET_ASSOCIATION(mSegmentPoints);
|
||||
mSegmentPoints.clear();
|
||||
|
||||
mRibbonMat = NULL;
|
||||
|
||||
mUpdateBuffers = true;
|
||||
mDeleteOnEnd = false;
|
||||
mUseFadeOut = false;
|
||||
mFadeAwayStep = 1.0f;
|
||||
mFadeOut = 1.0f;
|
||||
|
||||
mNetFlags.clear(Ghostable);
|
||||
mNetFlags.set(IsGhost);
|
||||
|
||||
mRadiusSC = NULL;
|
||||
mRibbonProjSC = NULL;
|
||||
|
||||
mSegmentOffset = 0;
|
||||
mSegmentIdx = 0;
|
||||
|
||||
mTravelledDistance = 0;
|
||||
}
|
||||
|
||||
Ribbon::~Ribbon()
|
||||
{
|
||||
//Make sure we cleanup
|
||||
SAFE_DELETE(mRibbonMat);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Ribbon::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool Ribbon::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
// add to client side mission cleanup
|
||||
SimGroup *cleanup = dynamic_cast<SimGroup *>( Sim::findObject( "ClientMissionCleanup") );
|
||||
if( cleanup != NULL )
|
||||
{
|
||||
cleanup->addObject( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertFatal( false, "Error, could not find ClientMissionCleanup group" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isServerObject()) {
|
||||
|
||||
if(GFX->getPixelShaderVersion() >= 1.1 && dStrlen(mDataBlock->mMatName) > 0 )
|
||||
{
|
||||
mRibbonMat = MATMGR->createMatInstance( mDataBlock->mMatName );
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setZReadWrite( true, false );
|
||||
desc.cullDefined = true;
|
||||
desc.cullMode = GFXCullNone;
|
||||
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
|
||||
|
||||
desc.samplersDefined = true;
|
||||
|
||||
GFXSamplerStateDesc sDesc(GFXSamplerStateDesc::getClampLinear());
|
||||
sDesc.addressModeV = GFXAddressWrap;
|
||||
|
||||
desc.samplers[0] = sDesc;
|
||||
|
||||
mRibbonMat->addStateBlockDesc( desc );
|
||||
mRibbonMat->init(MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPCNTT>());
|
||||
|
||||
mRadiusSC = mRibbonMat->getMaterialParameterHandle( "$radius" );
|
||||
mRibbonProjSC = mRibbonMat->getMaterialParameterHandle( "$ribbonProj" );
|
||||
|
||||
} else {
|
||||
Con::warnf( "Invalid Material name: %s: for Ribbon", mDataBlock->mMatName );
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::warnf( "- This could be caused by having the shader data datablocks in server-only code." );
|
||||
#endif
|
||||
mRibbonMat = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mObjBox.minExtents.set( 1.0f, 1.0f, 1.0f );
|
||||
mObjBox.maxExtents.set( 2.0f, 2.0f, 2.0f );
|
||||
// Reset the World Box.
|
||||
resetWorldBox();
|
||||
// Set the Render Transform.
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::onRemove()
|
||||
{
|
||||
|
||||
removeFromScene();
|
||||
SAFE_DELETE(mRibbonMat);
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
|
||||
bool Ribbon::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<RibbonData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ribbon::processTick(const Move* move)
|
||||
{
|
||||
Parent::processTick(move);
|
||||
|
||||
if (mDeleteOnEnd) {
|
||||
|
||||
if (mUseFadeOut) {
|
||||
|
||||
if (mFadeOut <= 0.0f) {
|
||||
mFadeOut = 0.0f;
|
||||
//delete this class
|
||||
mDeleteOnEnd = false;
|
||||
safeDeleteObject();
|
||||
return;
|
||||
}
|
||||
mFadeOut -= mFadeAwayStep;
|
||||
if (mFadeOut < 0.0f) {
|
||||
mFadeOut = 0.0f;
|
||||
}
|
||||
|
||||
mUpdateBuffers = true;
|
||||
|
||||
} else {
|
||||
//if (mSegmentPoints.size() == 0) {
|
||||
//delete this class
|
||||
mDeleteOnEnd = false;
|
||||
safeDeleteObject();
|
||||
return;
|
||||
//}
|
||||
//mSegmentPoints.pop_back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Ribbon::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
}
|
||||
|
||||
void Ribbon::interpolateTick(F32 delta)
|
||||
{
|
||||
Parent::interpolateTick(delta);
|
||||
}
|
||||
|
||||
void Ribbon::addSegmentPoint(Point3F &point, MatrixF &mat) {
|
||||
|
||||
//update our position
|
||||
setRenderTransform(mat);
|
||||
MatrixF xform(true);
|
||||
xform.setColumn(3, point);
|
||||
setTransform(xform);
|
||||
|
||||
if(mSegmentIdx < mDataBlock->mSegmentSkipAmount)
|
||||
{
|
||||
mSegmentIdx++;
|
||||
return;
|
||||
}
|
||||
|
||||
mSegmentIdx = 0;
|
||||
|
||||
U32 segmentsToDelete = checkRibbonDistance(mDataBlock->segmentsPerUpdate);
|
||||
|
||||
for (U32 i = 0; i < segmentsToDelete; i++) {
|
||||
U32 last = mSegmentPoints.size() - 1;
|
||||
if (last < 0)
|
||||
break;
|
||||
mTravelledDistance += last ? (mSegmentPoints[last] - mSegmentPoints[last-1]).len() : 0;
|
||||
mSegmentPoints.pop_back();
|
||||
mUpdateBuffers = true;
|
||||
mSegmentOffset++;
|
||||
}
|
||||
|
||||
//If there is no other points, just add a new one.
|
||||
if (mSegmentPoints.size() == 0) {
|
||||
|
||||
mSegmentPoints.push_front(point);
|
||||
mUpdateBuffers = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Point3F startPoint = mSegmentPoints[0];
|
||||
|
||||
//add X points based on how many segments Per Update from last point to current point
|
||||
for (U32 i = 0; i < mDataBlock->segmentsPerUpdate; i++) {
|
||||
|
||||
F32 interp = (F32(i+1) / (F32)mDataBlock->segmentsPerUpdate);
|
||||
//(end - start) * percentage) + start
|
||||
Point3F derivedPoint = ((point - startPoint) * interp) + startPoint;
|
||||
|
||||
mSegmentPoints.push_front(derivedPoint);
|
||||
mUpdateBuffers = true;
|
||||
}
|
||||
|
||||
if (mSegmentPoints.size() > 1) {
|
||||
|
||||
Point3F pointA = mSegmentPoints[mSegmentPoints.size()-1];
|
||||
Point3F pointB = mSegmentPoints[0];
|
||||
|
||||
Point3F diffSize = pointA - pointB;
|
||||
|
||||
if (diffSize.x == 0.0f)
|
||||
diffSize.x = 1.0f;
|
||||
|
||||
if (diffSize.y == 0.0f)
|
||||
diffSize.y = 1.0f;
|
||||
|
||||
if (diffSize.z == 0.0f)
|
||||
diffSize.z = 1.0f;
|
||||
|
||||
Box3F objBox;
|
||||
objBox.minExtents.set( diffSize * -1 );
|
||||
objBox.maxExtents.set( diffSize );
|
||||
|
||||
if (objBox.minExtents.x > objBox.maxExtents.x) {
|
||||
F32 tmp = objBox.minExtents.x;
|
||||
objBox.minExtents.x = objBox.maxExtents.x;
|
||||
objBox.maxExtents.x = tmp;
|
||||
}
|
||||
if (objBox.minExtents.y > objBox.maxExtents.y) {
|
||||
F32 tmp = objBox.minExtents.y;
|
||||
objBox.minExtents.y = objBox.maxExtents.y;
|
||||
objBox.maxExtents.y = tmp;
|
||||
}
|
||||
if (objBox.minExtents.z > objBox.maxExtents.z) {
|
||||
F32 tmp = objBox.minExtents.z;
|
||||
objBox.minExtents.z = objBox.maxExtents.z;
|
||||
objBox.maxExtents.z = tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (objBox.isValidBox()) {
|
||||
mObjBox = objBox;
|
||||
// Reset the World Box.
|
||||
resetWorldBox();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Ribbon::deleteOnEnd() {
|
||||
|
||||
mDeleteOnEnd = true;
|
||||
mUseFadeOut = mDataBlock->mUseFadeOut;
|
||||
mFadeAwayStep = mDataBlock->mFadeAwayStep;
|
||||
|
||||
}
|
||||
|
||||
U32 Ribbon::checkRibbonDistance(S32 segments) {
|
||||
|
||||
S32 len = mSegmentPoints.size();
|
||||
S32 difference = (mDataBlock->mRibbonLength/(mDataBlock->mSegmentSkipAmount+1)) - len;
|
||||
|
||||
if (difference < 0)
|
||||
return mAbs(difference);
|
||||
|
||||
return 0; //do not delete any points
|
||||
}
|
||||
|
||||
void Ribbon::setShaderParams() {
|
||||
|
||||
F32 numSegments = (F32)mSegmentPoints.size();
|
||||
F32 length = (F32)mDataBlock->mRibbonLength;
|
||||
Point3F radius(numSegments / length, numSegments, length);
|
||||
MaterialParameters* matParams = mRibbonMat->getMaterialParameters();
|
||||
matParams->setSafe( mRadiusSC, radius );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//U32 Ribbon::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||
//{
|
||||
// U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
// return retMask;
|
||||
//}
|
||||
//
|
||||
//void Ribbon::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||
//{
|
||||
// Parent::unpackUpdate(con, stream);
|
||||
//}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void Ribbon::prepRenderImage(SceneRenderState *state)
|
||||
{
|
||||
if (mFadeOut == 0.0f)
|
||||
return;
|
||||
|
||||
if(!mRibbonMat)
|
||||
return;
|
||||
|
||||
if (mDeleteOnEnd == true && mUseFadeOut == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We only render during the normal diffuse render pass.
|
||||
if( !state->isDiffusePass() )
|
||||
return;
|
||||
|
||||
U32 segments = mSegmentPoints.size();
|
||||
if (segments < 2)
|
||||
return;
|
||||
|
||||
MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
|
||||
ri->type = RenderPassManager::RIT_Translucent;
|
||||
ri->translucentSort = true;
|
||||
ri->sortDistSq = ( mSegmentPoints[0] - state->getCameraPosition() ).lenSquared();
|
||||
|
||||
RenderPassManager *renderPass = state->getRenderPass();
|
||||
MatrixF *proj = renderPass->allocUniqueXform(MatrixF( true ));
|
||||
proj->mul(GFX->getProjectionMatrix());
|
||||
proj->mul(GFX->getWorldMatrix());
|
||||
ri->objectToWorld = &MatrixF::Identity;
|
||||
ri->worldToCamera = &MatrixF::Identity;
|
||||
ri->projection = proj;
|
||||
ri->matInst = mRibbonMat;
|
||||
|
||||
// Set up our vertex buffer and primitive buffer
|
||||
if(mUpdateBuffers)
|
||||
createBuffers(state, verts, primBuffer, segments);
|
||||
|
||||
ri->vertBuff = &verts;
|
||||
ri->primBuff = &primBuffer;
|
||||
ri->visibility = 1.0f;
|
||||
|
||||
ri->prim = renderPass->allocPrim();
|
||||
ri->prim->type = GFXTriangleList;
|
||||
ri->prim->minIndex = 0;
|
||||
ri->prim->startIndex = 0;
|
||||
ri->prim->numPrimitives = (segments-1) * 2;
|
||||
ri->prim->startVertex = 0;
|
||||
ri->prim->numVertices = segments * 2;
|
||||
|
||||
if (mRibbonMat) {
|
||||
ri->defaultKey = mRibbonMat->getStateHint();
|
||||
} else {
|
||||
ri->defaultKey = 1;
|
||||
}
|
||||
ri->defaultKey2 = (U32)ri->vertBuff; // Not 64bit safe!
|
||||
|
||||
state->getRenderPass()->addInst(ri);
|
||||
}
|
||||
|
||||
void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVertexPCNTT> &verts, GFXPrimitiveBufferHandle &pb, U32 segments) {
|
||||
PROFILE_SCOPE( Ribbon_createBuffers );
|
||||
Point3F cameraPos = state->getCameraPosition();
|
||||
U32 count = 0;
|
||||
U32 indexCount = 0;
|
||||
verts.set(GFX, (segments*2), GFXBufferTypeDynamic);
|
||||
|
||||
// create index buffer based on that size
|
||||
U32 indexListSize = (segments-1) * 6;
|
||||
pb.set( GFX, indexListSize, 0, GFXBufferTypeDynamic );
|
||||
U16 *indices = NULL;
|
||||
|
||||
verts.lock();
|
||||
pb.lock( &indices );
|
||||
F32 totalLength = 0;
|
||||
if(mDataBlock->mTexcoordsRelativeToDistance)
|
||||
{
|
||||
for (U32 i = 0; i < segments; i++)
|
||||
if (i != 0)
|
||||
totalLength += (mSegmentPoints[i] - mSegmentPoints[i-1]).len();
|
||||
}
|
||||
|
||||
U8 fixedAppend = 0;
|
||||
F32 curLength = 0;
|
||||
for (U32 i = 0; i < segments; i++) {
|
||||
|
||||
F32 interpol = ((F32)i / (F32)(segments-1));
|
||||
Point3F leftvert = mSegmentPoints[i];
|
||||
Point3F rightvert = mSegmentPoints[i];
|
||||
F32 tRadius = mDataBlock->mSizes[0];
|
||||
ColorF tColor = mDataBlock->mColours[0];
|
||||
|
||||
for (U8 j = 0; j < RibbonData::NumFields-1; j++) {
|
||||
|
||||
F32 curPosition = mDataBlock->mTimes[j];
|
||||
F32 curRadius = mDataBlock->mSizes[j];
|
||||
ColorF curColor = mDataBlock->mColours[j];
|
||||
F32 nextPosition = mDataBlock->mTimes[j+1];
|
||||
F32 nextRadius = mDataBlock->mSizes[j+1];
|
||||
ColorF nextColor = mDataBlock->mColours[j+1];
|
||||
|
||||
if ( curPosition < 0
|
||||
|| curPosition > interpol )
|
||||
break;
|
||||
F32 positionDiff = (interpol - curPosition) / (nextPosition - curPosition);
|
||||
|
||||
tRadius = curRadius + (nextRadius - curRadius) * positionDiff;
|
||||
tColor.interpolate(curColor, nextColor, positionDiff);
|
||||
}
|
||||
|
||||
Point3F diff;
|
||||
F32 length;
|
||||
if (i == 0) {
|
||||
diff = mSegmentPoints[i+1] - mSegmentPoints[i];
|
||||
length = 0;
|
||||
} else if (i == segments-1) {
|
||||
diff = mSegmentPoints[i] - mSegmentPoints[i-1];
|
||||
length = diff.len();
|
||||
} else {
|
||||
diff = mSegmentPoints[i+1] - mSegmentPoints[i-1];
|
||||
length = (mSegmentPoints[i] - mSegmentPoints[i-1]).len();
|
||||
}
|
||||
|
||||
//left point
|
||||
Point3F eyeMinPos = cameraPos - leftvert;
|
||||
Point3F perpendicular = mCross(diff, eyeMinPos);
|
||||
perpendicular.normalize();
|
||||
perpendicular = perpendicular * tRadius * -1.0f;
|
||||
perpendicular += mSegmentPoints[i];
|
||||
|
||||
verts[count].point.set(perpendicular);
|
||||
ColorF color = tColor;
|
||||
|
||||
if (mDataBlock->mUseFadeOut)
|
||||
color.alpha *= mFadeOut;
|
||||
|
||||
F32 texCoords;
|
||||
if(mDataBlock->mFixedTexcoords && !mDataBlock->mTexcoordsRelativeToDistance)
|
||||
{
|
||||
U32 fixedIdx = (i+mDataBlock->mRibbonLength-mSegmentOffset)%mDataBlock->mRibbonLength;
|
||||
if(fixedIdx == 0 && i > 0)
|
||||
fixedAppend++;
|
||||
F32 fixedInterpol = (F32)fixedIdx / (F32)(mDataBlock->mRibbonLength);
|
||||
fixedInterpol += fixedAppend;
|
||||
texCoords = (1.0f - fixedInterpol)*mDataBlock->mTileScale;
|
||||
}
|
||||
else if(mDataBlock->mTexcoordsRelativeToDistance)
|
||||
texCoords = (mTravelledDistance + (totalLength - (curLength + length)))*mDataBlock->mTileScale;
|
||||
else
|
||||
texCoords = (1.0f - interpol)*mDataBlock->mTileScale;
|
||||
|
||||
verts[count].color = color;
|
||||
verts[count].texCoord[1] = Point2F(interpol, 0);
|
||||
verts[count].texCoord[0] = Point2F(0.0f, texCoords);
|
||||
verts[count].normal.set(diff);
|
||||
|
||||
//Triangle strip style indexing, so grab last 2
|
||||
if (count > 1) {
|
||||
indices[indexCount] = count-2;
|
||||
indexCount++;
|
||||
indices[indexCount] = count;
|
||||
indexCount++;
|
||||
indices[indexCount] = count-1;
|
||||
indexCount++;
|
||||
}
|
||||
count++;
|
||||
|
||||
eyeMinPos = cameraPos - rightvert;
|
||||
perpendicular = mCross(diff, eyeMinPos);
|
||||
perpendicular.normalize();
|
||||
perpendicular = perpendicular * tRadius;
|
||||
perpendicular += mSegmentPoints[i];
|
||||
|
||||
verts[count].point.set(perpendicular);
|
||||
color = tColor;
|
||||
|
||||
if (mDataBlock->mUseFadeOut)
|
||||
color.alpha *= mFadeOut;
|
||||
|
||||
verts[count].color = color;
|
||||
verts[count].texCoord[1] = Point2F(interpol, 1);
|
||||
verts[count].texCoord[0] = Point2F(1.0f, texCoords);
|
||||
verts[count].normal.set(diff);
|
||||
|
||||
//Triangle strip style indexing, so grab last 2
|
||||
if (count > 1) {
|
||||
indices[indexCount] = count-2;
|
||||
indexCount++;
|
||||
indices[indexCount] = count-1;
|
||||
indexCount++;
|
||||
indices[indexCount] = count;
|
||||
indexCount++;
|
||||
}
|
||||
count++;
|
||||
curLength += length;
|
||||
}
|
||||
|
||||
Point3F pointA = verts[count-1].point;
|
||||
Point3F pointB = verts[0].point;
|
||||
|
||||
verts.unlock();
|
||||
pb.unlock();
|
||||
|
||||
Point3F diffSize = pointA - pointB;
|
||||
|
||||
Box3F objBox;
|
||||
objBox.minExtents.set( diffSize * -1 );
|
||||
objBox.maxExtents.set( diffSize );
|
||||
|
||||
if (objBox.minExtents.x > objBox.maxExtents.x) {
|
||||
F32 tmp = objBox.minExtents.x;
|
||||
objBox.minExtents.x = objBox.maxExtents.x;
|
||||
objBox.maxExtents.x = tmp;
|
||||
}
|
||||
if (objBox.minExtents.y > objBox.maxExtents.y) {
|
||||
F32 tmp = objBox.minExtents.y;
|
||||
objBox.minExtents.y = objBox.maxExtents.y;
|
||||
objBox.maxExtents.y = tmp;
|
||||
}
|
||||
if (objBox.minExtents.z > objBox.maxExtents.z) {
|
||||
F32 tmp = objBox.minExtents.z;
|
||||
objBox.minExtents.z = objBox.maxExtents.z;
|
||||
objBox.maxExtents.z = tmp;
|
||||
}
|
||||
|
||||
if (objBox.isValidBox()) {
|
||||
mObjBox = objBox;
|
||||
// Reset the World Box.
|
||||
resetWorldBox();
|
||||
}
|
||||
|
||||
mUpdateBuffers = false;
|
||||
}
|
||||
142
Engine/source/T3D/fx/ribbon.h
Normal file
142
Engine/source/T3D/fx/ribbon.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _RIBBON_H_
|
||||
#define _RIBBON_H_
|
||||
|
||||
#ifndef _GAMEBASE_H_
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXVERTEXBUFFER_H_
|
||||
#include "gfx/gfxVertexBuffer.h"
|
||||
#endif
|
||||
|
||||
#include "materials/materialParameters.h"
|
||||
#include "math/util/matrixSet.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
class RibbonData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
protected:
|
||||
bool onAdd();
|
||||
|
||||
public:
|
||||
|
||||
enum Constants
|
||||
{
|
||||
NumFields = 4
|
||||
};
|
||||
|
||||
F32 mSizes[NumFields]; ///< The radius for each keyframe.
|
||||
ColorF mColours[NumFields]; ///< The colour of the ribbon for each keyframe.
|
||||
F32 mTimes[NumFields]; ///< The relative time for each keyframe.
|
||||
|
||||
U32 mRibbonLength; ///< The amount of segments that will make up the ribbon.
|
||||
S32 segmentsPerUpdate; ///< Amount of segments to add each update.
|
||||
S32 mSegmentSkipAmount; ///< The amount of segments to skip each time segments are added.
|
||||
|
||||
bool mUseFadeOut; ///< If true, the ribbon will fade away after deletion.
|
||||
F32 mFadeAwayStep; ///< How quickly the ribbons is faded away after deletion.
|
||||
StringTableEntry mMatName; ///< The material for the ribbon.
|
||||
F32 mTileScale; ///< A scalar to scale the texcoord.
|
||||
bool mFixedTexcoords; ///< If true, texcoords will stay the same over the lifetime for each segment.
|
||||
bool mTexcoordsRelativeToDistance; ///< If true, texcoords will not be stretched if the distance between 2 segments are long.
|
||||
|
||||
RibbonData();
|
||||
|
||||
void packData(BitStream*);
|
||||
void unpackData(BitStream*);
|
||||
bool preload(bool server, String &errorBuffer);
|
||||
|
||||
static void initPersistFields();
|
||||
DECLARE_CONOBJECT(RibbonData);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
class Ribbon : public GameBase
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
RibbonData* mDataBlock;
|
||||
|
||||
bool mDeleteOnEnd; ///< If true, the ribbon should delete itself as soon as the last segment is deleted
|
||||
bool mUseFadeOut; ///< If true, the ribbon will fade away upon deletion
|
||||
F32 mFadeAwayStep; ///< How quickly the ribbons is faded away after deletion.
|
||||
F32 mFadeOut;
|
||||
F32 mTravelledDistance; ///< How far the ribbon has travelled in it's lifetime.
|
||||
|
||||
Vector<Point3F> mSegmentPoints; ///< The points in space where the ribbon has spawned segments.
|
||||
U32 mSegmentOffset;
|
||||
U32 mSegmentIdx;
|
||||
|
||||
bool mUpdateBuffers; ///< If true, the vertex buffers need to be updated.
|
||||
BaseMatInstance *mRibbonMat;
|
||||
MaterialParameterHandle* mRadiusSC;
|
||||
MaterialParameterHandle* mRibbonProjSC;
|
||||
GFXPrimitiveBufferHandle primBuffer;
|
||||
GFXVertexBufferHandle<GFXVertexPCNTT> verts;
|
||||
|
||||
protected:
|
||||
|
||||
bool onAdd();
|
||||
void processTick(const Move*);
|
||||
void advanceTime(F32);
|
||||
void interpolateTick(F32 delta);
|
||||
|
||||
// Rendering
|
||||
void prepRenderImage(SceneRenderState *state);
|
||||
void setShaderParams();
|
||||
|
||||
///Checks to see if ribbon is too long
|
||||
U32 checkRibbonDistance(S32 segments);
|
||||
|
||||
/// Construct the vertex and primitive buffers
|
||||
void createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVertexPCNTT> &verts, GFXPrimitiveBufferHandle &pb, U32 segments);
|
||||
|
||||
public:
|
||||
Ribbon();
|
||||
~Ribbon();
|
||||
|
||||
DECLARE_CONOBJECT(Ribbon);
|
||||
static void initPersistFields();
|
||||
bool onNewDataBlock(GameBaseData*,bool);
|
||||
void onRemove();
|
||||
|
||||
/// Used to add another segment to the ribbon.
|
||||
void addSegmentPoint(Point3F &point, MatrixF &mat);
|
||||
|
||||
/// Delete all segments.
|
||||
void clearSegments() { mSegmentPoints.clear(); }
|
||||
|
||||
/// Delete the ribbon when all segments have been deleted.
|
||||
void deleteOnEnd();
|
||||
};
|
||||
|
||||
#endif // _H_RIBBON
|
||||
|
||||
324
Engine/source/T3D/fx/ribbonNode.cpp
Normal file
324
Engine/source/T3D/fx/ribbonNode.cpp
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ribbonNode.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "T3D/fx/ribbon.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(RibbonNodeData);
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RibbonNode);
|
||||
|
||||
ConsoleDocClass( RibbonNodeData,
|
||||
"@brief Contains additional data to be associated with a RibbonNode."
|
||||
"@ingroup FX\n"
|
||||
);
|
||||
|
||||
ConsoleDocClass( RibbonNode, ""
|
||||
);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RibbonNodeData
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNodeData::RibbonNodeData()
|
||||
{
|
||||
}
|
||||
|
||||
RibbonNodeData::~RibbonNodeData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initPersistFields
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNodeData::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RibbonNode
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNode::RibbonNode()
|
||||
{
|
||||
// Todo: ScopeAlways?
|
||||
mNetFlags.set(Ghostable);
|
||||
mTypeMask |= EnvironmentObjectType;
|
||||
|
||||
mActive = true;
|
||||
|
||||
mDataBlock = NULL;
|
||||
mRibbonDatablock = NULL;
|
||||
mRibbonDatablockId = 0;
|
||||
mRibbon = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNode::~RibbonNode()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initPersistFields
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::initPersistFields()
|
||||
{
|
||||
addField( "active", TYPEID< bool >(), Offset(mActive,RibbonNode),
|
||||
"Controls whether ribbon is emitted from this node." );
|
||||
addField( "ribbon", TYPEID< RibbonData >(), Offset(mRibbonDatablock, RibbonNode),
|
||||
"Datablock to use for the ribbon." );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onAdd
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RibbonNode::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
if( !mRibbonDatablock && mRibbonDatablockId != 0 )
|
||||
{
|
||||
if( Sim::findObject(mRibbonDatablockId, mRibbonDatablock) == false )
|
||||
Con::errorf(ConsoleLogEntry::General, "RibbonNode::onAdd: Invalid packet, bad datablockId(mRibbonDatablock): %d", mRibbonDatablockId);
|
||||
}
|
||||
|
||||
if( isClientObject() )
|
||||
{
|
||||
setRibbonDatablock( mRibbonDatablock );
|
||||
}
|
||||
else
|
||||
{
|
||||
setMaskBits( StateMask | EmitterDBMask );
|
||||
}
|
||||
|
||||
mObjBox.minExtents.set(-0.5, -0.5, -0.5);
|
||||
mObjBox.maxExtents.set( 0.5, 0.5, 0.5);
|
||||
resetWorldBox();
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onRemove
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
if( isClientObject() )
|
||||
{
|
||||
if( mRibbon )
|
||||
{
|
||||
mRibbon->deleteOnEnd();
|
||||
mRibbon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onNewDataBlock
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RibbonNode::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||
{
|
||||
mDataBlock = dynamic_cast<RibbonNodeData*>( dptr );
|
||||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
setMaskBits(StateMask | EmitterDBMask);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// processTick
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::processTick(const Move* move)
|
||||
{
|
||||
Parent::processTick(move);
|
||||
|
||||
if ( isMounted() )
|
||||
{
|
||||
MatrixF mat;
|
||||
mMount.object->getMountTransform( mMount.node, mMount.xfm, &mat );
|
||||
setTransform( mat );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// advanceTime
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if(!mActive || mRibbon.isNull() || !mDataBlock)
|
||||
return;
|
||||
|
||||
MatrixF trans(getTransform());
|
||||
Point3F pos = getPosition();
|
||||
mRibbon->addSegmentPoint(pos, trans);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// packUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
U32 RibbonNode::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
if ( stream->writeFlag( mask & InitialUpdateMask ) )
|
||||
{
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & EmitterDBMask ) )
|
||||
{
|
||||
if( stream->writeFlag(mRibbonDatablock != NULL) )
|
||||
{
|
||||
stream->writeRangedU32(mRibbonDatablock->getId(), DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & StateMask ) )
|
||||
{
|
||||
stream->writeFlag( mActive );
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// unpackUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
MatrixF temp;
|
||||
Point3F tempScale;
|
||||
mathRead(*stream, &temp);
|
||||
mathRead(*stream, &tempScale);
|
||||
|
||||
setScale(tempScale);
|
||||
setTransform(temp);
|
||||
}
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
mRibbonDatablockId = stream->readFlag() ?
|
||||
stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast) : 0;
|
||||
|
||||
RibbonData *emitterDB = NULL;
|
||||
Sim::findObject( mRibbonDatablockId, emitterDB );
|
||||
if ( isProperlyAdded() )
|
||||
setRibbonDatablock( emitterDB );
|
||||
}
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
mActive = stream->readFlag();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setRibbonDatablock
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::setRibbonDatablock(RibbonData* data)
|
||||
{
|
||||
if ( isServerObject() )
|
||||
{
|
||||
setMaskBits( EmitterDBMask );
|
||||
}
|
||||
else
|
||||
{
|
||||
Ribbon* pRibbon = NULL;
|
||||
if ( data )
|
||||
{
|
||||
// Create emitter with new datablock
|
||||
pRibbon = new Ribbon;
|
||||
pRibbon->onNewDataBlock( data, false );
|
||||
if( pRibbon->registerObject() == false )
|
||||
{
|
||||
Con::warnf(ConsoleLogEntry::General, "Could not register base ribbon of class: %s", data->getName() ? data->getName() : data->getIdString() );
|
||||
delete pRibbon;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace emitter
|
||||
if ( mRibbon )
|
||||
mRibbon->deleteOnEnd();
|
||||
|
||||
mRibbon = pRibbon;
|
||||
}
|
||||
|
||||
mRibbonDatablock = data;
|
||||
}
|
||||
|
||||
DefineEngineMethod(RibbonNode, setRibbonDatablock, void, (RibbonData* ribbonDatablock), (0),
|
||||
"Assigns the datablock for this ribbon node.\n"
|
||||
"@param ribbonDatablock RibbonData datablock to assign\n"
|
||||
"@tsexample\n"
|
||||
"// Assign a new emitter datablock\n"
|
||||
"%emitter.setRibbonDatablock( %ribbonDatablock );\n"
|
||||
"@endtsexample\n" )
|
||||
{
|
||||
if ( !ribbonDatablock )
|
||||
{
|
||||
Con::errorf("RibbonData datablock could not be found when calling setRibbonDataBlock in ribbonNode.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->setRibbonDatablock(ribbonDatablock);
|
||||
}
|
||||
|
||||
DefineEngineMethod(RibbonNode, setActive, void, (bool active),,
|
||||
"Turns the ribbon on or off.\n"
|
||||
"@param active New ribbon state\n" )
|
||||
{
|
||||
object->setActive( active );
|
||||
}
|
||||
105
Engine/source/T3D/fx/ribbonNode.h
Normal file
105
Engine/source/T3D/fx/ribbonNode.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _RIBBON_NODE_H_
|
||||
#define _RIBBON_NODE_H_
|
||||
|
||||
#ifndef _GAMEBASE_H_
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#endif
|
||||
|
||||
class RibbonData;
|
||||
class Ribbon;
|
||||
|
||||
//*****************************************************************************
|
||||
// ParticleEmitterNodeData
|
||||
//*****************************************************************************
|
||||
class RibbonNodeData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
F32 timeMultiple;
|
||||
|
||||
public:
|
||||
RibbonNodeData();
|
||||
~RibbonNodeData();
|
||||
|
||||
DECLARE_CONOBJECT(RibbonNodeData);
|
||||
static void initPersistFields();
|
||||
};
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// ParticleEmitterNode
|
||||
//*****************************************************************************
|
||||
class RibbonNode : public GameBase
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
enum MaskBits
|
||||
{
|
||||
StateMask = Parent::NextFreeMask << 0,
|
||||
EmitterDBMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2,
|
||||
};
|
||||
|
||||
RibbonNodeData* mDataBlock;
|
||||
|
||||
protected:
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
||||
void inspectPostApply();
|
||||
|
||||
RibbonData* mRibbonDatablock;
|
||||
S32 mRibbonDatablockId;
|
||||
|
||||
SimObjectPtr<Ribbon> mRibbon;
|
||||
|
||||
bool mActive;
|
||||
|
||||
public:
|
||||
RibbonNode();
|
||||
~RibbonNode();
|
||||
|
||||
Ribbon *getRibbonEmitter() {return mRibbon;}
|
||||
|
||||
// Time/Move Management
|
||||
|
||||
void processTick(const Move* move);
|
||||
void advanceTime(F32 dt);
|
||||
|
||||
DECLARE_CONOBJECT(RibbonNode);
|
||||
static void initPersistFields();
|
||||
|
||||
U32 packUpdate (NetConnection *conn, U32 mask, BitStream* stream);
|
||||
void unpackUpdate(NetConnection *conn, BitStream* stream);
|
||||
|
||||
inline bool getActive( void ) { return mActive; };
|
||||
inline void setActive( bool active ) { mActive = active; setMaskBits( StateMask ); };
|
||||
|
||||
void setRibbonDatablock(RibbonData* data);
|
||||
};
|
||||
|
||||
#endif // _RIBBON_NODE_H_
|
||||
|
||||
|
|
@ -281,7 +281,8 @@ ConsoleMethod(GameConnection, setConnectArgs, void, 3, 17,
|
|||
|
||||
"@see GameConnection::onConnect()\n\n")
|
||||
{
|
||||
object->setConnectArgs(argc - 2, argv + 2);
|
||||
StringStackWrapper args(argc - 2, argv + 2);
|
||||
object->setConnectArgs(args.count(), args);
|
||||
}
|
||||
|
||||
void GameConnection::onTimedOut()
|
||||
|
|
@ -323,6 +324,7 @@ void GameConnection::onConnectionEstablished(bool isInitiator)
|
|||
|
||||
const char *argv[MaxConnectArgs + 2];
|
||||
argv[0] = "onConnect";
|
||||
argv[1] = NULL; // Filled in later
|
||||
for(U32 i = 0; i < mConnectArgc; i++)
|
||||
argv[i + 2] = mConnectArgv[i];
|
||||
// NOTE: Need to fallback to Con::execute() as IMPLEMENT_CALLBACK does not
|
||||
|
|
@ -442,7 +444,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
|
|||
*errorString = "CR_INVALID_ARGS";
|
||||
return false;
|
||||
}
|
||||
const char *connectArgv[MaxConnectArgs + 3];
|
||||
ConsoleValueRef connectArgv[MaxConnectArgs + 3];
|
||||
for(U32 i = 0; i < mConnectArgc; i++)
|
||||
{
|
||||
char argString[256];
|
||||
|
|
@ -451,6 +453,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
|
|||
connectArgv[i + 3] = mConnectArgv[i];
|
||||
}
|
||||
connectArgv[0] = "onConnectRequest";
|
||||
connectArgv[1] = NULL;
|
||||
char buffer[256];
|
||||
Net::addressToString(getNetAddress(), buffer);
|
||||
connectArgv[2] = buffer;
|
||||
|
|
@ -974,7 +977,7 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
|
|||
|
||||
void GameConnection::demoPlaybackComplete()
|
||||
{
|
||||
static const char *demoPlaybackArgv[1] = { "demoPlaybackComplete" };
|
||||
static ConsoleValueRef demoPlaybackArgv[1] = { "demoPlaybackComplete" };
|
||||
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(1, demoPlaybackArgv, false));
|
||||
Parent::demoPlaybackComplete();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ ConsoleMethod( LightBase, playAnimation, void, 2, 3, "( [LightAnimData anim] )\t
|
|||
LightAnimData *animData;
|
||||
if ( !Sim::findObject( argv[2], animData ) )
|
||||
{
|
||||
Con::errorf( "LightBase::playAnimation() - Invalid LightAnimData '%s'.", argv[2] );
|
||||
Con::errorf( "LightBase::playAnimation() - Invalid LightAnimData '%s'.", (const char*)argv[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -481,4 +481,4 @@ void LightBase::pauseAnimation( void )
|
|||
mAnimState.active = false;
|
||||
setMaskBits( UpdateMask );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,12 +223,6 @@ ConsoleDocClass( WayPoint,
|
|||
"@ingroup enviroMisc\n"
|
||||
);
|
||||
|
||||
WayPointTeam::WayPointTeam()
|
||||
{
|
||||
mTeamId = 0;
|
||||
mWayPoint = 0;
|
||||
}
|
||||
|
||||
WayPoint::WayPoint()
|
||||
{
|
||||
mName = StringTable->insert("");
|
||||
|
|
@ -252,7 +246,6 @@ bool WayPoint::onAdd()
|
|||
Sim::getWayPointSet()->addObject(this);
|
||||
else
|
||||
{
|
||||
mTeam.mWayPoint = this;
|
||||
setMaskBits(UpdateNameMask|UpdateTeamMask);
|
||||
}
|
||||
|
||||
|
|
@ -272,8 +265,6 @@ U32 WayPoint::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
|
|||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
if(stream->writeFlag(mask & UpdateNameMask))
|
||||
stream->writeString(mName);
|
||||
if(stream->writeFlag(mask & UpdateTeamMask))
|
||||
stream->write(mTeam.mTeamId);
|
||||
if(stream->writeFlag(mask & UpdateHiddenMask))
|
||||
stream->writeFlag(isHidden());
|
||||
return(retMask);
|
||||
|
|
@ -284,48 +275,17 @@ void WayPoint::unpackUpdate(NetConnection * con, BitStream * stream)
|
|||
Parent::unpackUpdate(con, stream);
|
||||
if(stream->readFlag())
|
||||
mName = stream->readSTString(true);
|
||||
if(stream->readFlag())
|
||||
stream->read(&mTeam.mTeamId);
|
||||
if(stream->readFlag())
|
||||
setHidden(stream->readFlag());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TypeWayPointTeam
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STRUCT( WayPointTeam, WayPointTeam,,
|
||||
"" )
|
||||
END_IMPLEMENT_STRUCT;
|
||||
|
||||
//FIXME: this should work but does not; need to check the stripping down to base types within TYPE
|
||||
//ConsoleType( WayPointTeam, TypeWayPointTeam, WayPointTeam* )
|
||||
ConsoleType( WayPointTeam, TypeWayPointTeam, WayPointTeam )
|
||||
|
||||
ConsoleGetType( TypeWayPointTeam )
|
||||
{
|
||||
static const U32 bufSize = 32;
|
||||
char * buf = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(buf, bufSize, "%d", ((WayPointTeam*)dptr)->mTeamId);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeWayPointTeam )
|
||||
{
|
||||
WayPointTeam * pTeam = (WayPointTeam*)dptr;
|
||||
pTeam->mTeamId = dAtoi(argv[0]);
|
||||
|
||||
if(pTeam->mWayPoint && pTeam->mWayPoint->isServerObject())
|
||||
pTeam->mWayPoint->setMaskBits(WayPoint::UpdateTeamMask);
|
||||
}
|
||||
|
||||
void WayPoint::initPersistFields()
|
||||
{
|
||||
addGroup("Misc");
|
||||
addField("markerName", TypeCaseString, Offset(mName, WayPoint), "Unique name representing this waypoint");
|
||||
addField("team", TypeWayPointTeam, Offset(mTeam, WayPoint), "Unique numerical ID assigned to this waypoint, or set of waypoints");
|
||||
endGroup("Misc");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
|
|
@ -555,7 +515,7 @@ ConsoleMethod(SpawnSphere, spawnObject, S32, 2, 3,
|
|||
String additionalProps;
|
||||
|
||||
if (argc == 3)
|
||||
additionalProps = String(argv[2]);
|
||||
additionalProps = (const char*)argv[2];
|
||||
|
||||
SimObject* obj = object->spawnObject(additionalProps);
|
||||
|
||||
|
|
|
|||
|
|
@ -92,17 +92,6 @@ class MissionMarker : public ShapeBase
|
|||
// Class: WayPoint
|
||||
//------------------------------------------------------------------------------
|
||||
class WayPoint;
|
||||
class WayPointTeam
|
||||
{
|
||||
public:
|
||||
WayPointTeam();
|
||||
|
||||
S32 mTeamId;
|
||||
WayPoint * mWayPoint;
|
||||
};
|
||||
|
||||
DECLARE_STRUCT( WayPointTeam );
|
||||
DefineConsoleType( TypeWayPointTeam, WayPointTeam * );
|
||||
|
||||
class WayPoint : public MissionMarker
|
||||
{
|
||||
|
|
@ -132,7 +121,6 @@ class WayPoint : public MissionMarker
|
|||
|
||||
// field data
|
||||
StringTableEntry mName;
|
||||
WayPointTeam mTeam;
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
|
|
|
|||
|
|
@ -147,13 +147,13 @@ ConsoleFunction( physicsDestroy, void, 1, 1, "physicsDestroy()" )
|
|||
|
||||
ConsoleFunction( physicsInitWorld, bool, 2, 2, "physicsInitWorld( String worldName )" )
|
||||
{
|
||||
return PHYSICSMGR && PHYSICSMGR->createWorld( String( argv[1] ) );
|
||||
return PHYSICSMGR && PHYSICSMGR->createWorld( (const char*)argv[1] );
|
||||
}
|
||||
|
||||
ConsoleFunction( physicsDestroyWorld, void, 2, 2, "physicsDestroyWorld( String worldName )" )
|
||||
{
|
||||
if ( PHYSICSMGR )
|
||||
PHYSICSMGR->destroyWorld( String( argv[1] ) );
|
||||
PHYSICSMGR->destroyWorld( (const char*)argv[1] );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -162,13 +162,13 @@ ConsoleFunction( physicsDestroyWorld, void, 2, 2, "physicsDestroyWorld( String w
|
|||
ConsoleFunction( physicsStartSimulation, void, 2, 2, "physicsStartSimulation( String worldName )" )
|
||||
{
|
||||
if ( PHYSICSMGR )
|
||||
PHYSICSMGR->enableSimulation( String( argv[1] ), true );
|
||||
PHYSICSMGR->enableSimulation( (const char*)argv[1], true );
|
||||
}
|
||||
|
||||
ConsoleFunction( physicsStopSimulation, void, 2, 2, "physicsStopSimulation( String worldName )" )
|
||||
{
|
||||
if ( PHYSICSMGR )
|
||||
PHYSICSMGR->enableSimulation( String( argv[1] ), false );
|
||||
PHYSICSMGR->enableSimulation( (const char*)argv[1], false );
|
||||
}
|
||||
|
||||
ConsoleFunction( physicsSimulationEnabled, bool, 1, 1, "physicsSimulationEnabled()" )
|
||||
|
|
@ -182,7 +182,7 @@ ConsoleFunction( physicsSimulationEnabled, bool, 1, 1, "physicsSimulationEnabled
|
|||
ConsoleFunction( physicsSetTimeScale, void, 2, 2, "physicsSetTimeScale( F32 scale )" )
|
||||
{
|
||||
if ( PHYSICSMGR )
|
||||
PHYSICSMGR->setTimeScale( dAtof( argv[1] ) );
|
||||
PHYSICSMGR->setTimeScale( argv[1] );
|
||||
}
|
||||
|
||||
// Get the currently set time scale.
|
||||
|
|
@ -212,5 +212,5 @@ ConsoleFunction( physicsRestoreState, void, 1, 1, "physicsRestoreState()" )
|
|||
ConsoleFunction( physicsDebugDraw, void, 2, 2, "physicsDebugDraw( bool enable )" )
|
||||
{
|
||||
if ( PHYSICSMGR )
|
||||
PHYSICSMGR->enableDebugDraw( dAtoi( argv[1] ) );
|
||||
}
|
||||
PHYSICSMGR->enableDebugDraw( (S32)argv[1] );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,28 +20,34 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Windows WGL functions
|
||||
GL_GROUP_BEGIN(ARB_win32)
|
||||
GL_FUNCTION(wglCopyContext, BOOL, (HGLRC, HGLRC, UINT))
|
||||
GL_FUNCTION(wglCreateContext, HGLRC, (HDC))
|
||||
GL_FUNCTION(wglCreateLayerContext, HGLRC, (HDC, GLint))
|
||||
GL_FUNCTION(wglDeleteContext, BOOL, (HGLRC))
|
||||
GL_FUNCTION(wglGetCurrentContext, HGLRC, (VOID))
|
||||
GL_FUNCTION(wglGetCurrentDC, HDC, (VOID))
|
||||
GL_FUNCTION(wglGetProcAddress, PROC, (LPCSTR))
|
||||
GL_FUNCTION(wglMakeCurrent, BOOL, (HDC, HGLRC))
|
||||
GL_FUNCTION(wglShareLists, BOOL, (HGLRC, HGLRC))
|
||||
GL_FUNCTION(wglDescribeLayerPlane, BOOL, (HDC, GLint, GLint, UINT, LPLAYERPLANEDESCRIPTOR))
|
||||
GL_FUNCTION(wglSetLayerPaletteEntries, GLint, (HDC, GLint, GLint, GLint, CONST COLORREF *))
|
||||
GL_FUNCTION(wglGetLayerPaletteEntries, GLint, (HDC, GLint, GLint, GLint, COLORREF *))
|
||||
GL_FUNCTION(wglRealizeLayerPalette, BOOL, (HDC, GLint, BOOL))
|
||||
GL_FUNCTION(wglSwapLayerBuffers, BOOL, (HDC, UINT))
|
||||
#ifndef _PHYSX3_H_
|
||||
#define _PHYSX3_H_
|
||||
|
||||
// Ascii and Unicode versions
|
||||
GL_FUNCTION(wglUseFontBitmapsA, BOOL, (HDC, DWORD, DWORD, DWORD))
|
||||
GL_FUNCTION(wglUseFontOutlinesA, BOOL, (HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, GLint, LPGLYPHMETRICSFLOAT))
|
||||
GL_FUNCTION(wglUseFontBitmapsW, BOOL, (HDC, DWORD, DWORD, DWORD))
|
||||
GL_FUNCTION(wglUseFontOutlinesW, BOOL, (HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, GLint, LPGLYPHMETRICSFLOAT))
|
||||
//-------------------------------------------------------------------------
|
||||
//defines to keep PhysX happy and compiling
|
||||
#if defined(TORQUE_OS_MAC) && !defined(__APPLE__)
|
||||
#define __APPLE__
|
||||
#elif defined(TORQUE_OS_LINUX) && !defined(LINUX)
|
||||
#define LINUX
|
||||
#elif defined(TORQUE_OS_WIN) && !defined(WIN32)
|
||||
#define WIN32
|
||||
#endif
|
||||
|
||||
GL_GROUP_END()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <PxExtensionsAPI.h>
|
||||
#include <PxDefaultErrorCallback.h>
|
||||
#include <PxDefaultAllocator.h>
|
||||
#include <PxDefaultSimulationFilterShader.h>
|
||||
#include <PxDefaultCpuDispatcher.h>
|
||||
#include <PxShapeExt.h>
|
||||
#include <PxSimpleFactory.h>
|
||||
#include <PxFoundation.h>
|
||||
#include <PxController.h>
|
||||
#include <PxIO.h>
|
||||
|
||||
|
||||
extern physx::PxPhysics* gPhysics3SDK;
|
||||
|
||||
#endif // _PHYSX3_
|
||||
419
Engine/source/T3D/physics/physx3/px3Body.cpp
Normal file
419
Engine/source/T3D/physics/physx3/px3Body.cpp
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3Body.h"
|
||||
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#include "T3D/physics/physx3/px3Casts.h"
|
||||
#include "T3D/physics/physx3/px3World.h"
|
||||
#include "T3D/physics/physx3/px3Collision.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
|
||||
Px3Body::Px3Body() :
|
||||
mActor( NULL ),
|
||||
mMaterial( NULL ),
|
||||
mWorld( NULL ),
|
||||
mBodyFlags( 0 ),
|
||||
mIsEnabled( true ),
|
||||
mIsStatic(false)
|
||||
{
|
||||
}
|
||||
|
||||
Px3Body::~Px3Body()
|
||||
{
|
||||
_releaseActor();
|
||||
}
|
||||
|
||||
void Px3Body::_releaseActor()
|
||||
{
|
||||
if ( !mActor )
|
||||
return;
|
||||
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
mActor->userData = NULL;
|
||||
|
||||
mActor->release();
|
||||
mActor = NULL;
|
||||
mBodyFlags = 0;
|
||||
|
||||
if ( mMaterial )
|
||||
{
|
||||
mMaterial->release();
|
||||
}
|
||||
|
||||
mColShape = NULL;
|
||||
}
|
||||
|
||||
bool Px3Body::init( PhysicsCollision *shape,
|
||||
F32 mass,
|
||||
U32 bodyFlags,
|
||||
SceneObject *obj,
|
||||
PhysicsWorld *world )
|
||||
{
|
||||
AssertFatal( obj, "Px3Body::init - Got a null scene object!" );
|
||||
AssertFatal( world, "Px3Body::init - Got a null world!" );
|
||||
AssertFatal( dynamic_cast<Px3World*>( world ), "Px3Body::init - The world is the wrong type!" );
|
||||
AssertFatal( shape, "Px3Body::init - Got a null collision shape!" );
|
||||
AssertFatal( dynamic_cast<Px3Collision*>( shape ), "Px3Body::init - The collision shape is the wrong type!" );
|
||||
AssertFatal( !((Px3Collision*)shape)->getShapes().empty(), "Px3Body::init - Got empty collision shape!" );
|
||||
|
||||
// Cleanup any previous actor.
|
||||
_releaseActor();
|
||||
|
||||
mWorld = (Px3World*)world;
|
||||
mColShape = (Px3Collision*)shape;
|
||||
mBodyFlags = bodyFlags;
|
||||
|
||||
const bool isKinematic = mBodyFlags & BF_KINEMATIC;
|
||||
const bool isTrigger = mBodyFlags & BF_TRIGGER;
|
||||
const bool isDebris = mBodyFlags & BF_DEBRIS;
|
||||
|
||||
if ( isKinematic )
|
||||
{
|
||||
mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
actor->setRigidDynamicFlag(physx::PxRigidDynamicFlag::eKINEMATIC, true);
|
||||
actor->setMass(getMax( mass, 1.0f ));
|
||||
}
|
||||
else if ( mass > 0.0f )
|
||||
{
|
||||
mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mActor = gPhysics3SDK->createRigidStatic(physx::PxTransform(physx::PxIDENTITY()));
|
||||
mIsStatic = true;
|
||||
}
|
||||
|
||||
mMaterial = gPhysics3SDK->createMaterial(0.6f,0.4f,0.1f);
|
||||
|
||||
// Add all the shapes.
|
||||
const Vector<Px3CollisionDesc*> &shapes = mColShape->getShapes();
|
||||
for ( U32 i=0; i < shapes.size(); i++ )
|
||||
{
|
||||
Px3CollisionDesc* desc = shapes[i];
|
||||
if( mass > 0.0f )
|
||||
{
|
||||
if(desc->pGeometry->getType() == physx::PxGeometryType::eTRIANGLEMESH)
|
||||
{
|
||||
Con::errorf("PhysX3 Dynamic Triangle Mesh is not supported.");
|
||||
}
|
||||
}
|
||||
physx::PxShape * pShape = mActor->createShape(*desc->pGeometry,*mMaterial);
|
||||
physx::PxFilterData colData;
|
||||
if(isDebris)
|
||||
colData.word0 = PX3_DEBRIS;
|
||||
else if(isTrigger)
|
||||
colData.word0 = PX3_TRIGGER;
|
||||
else
|
||||
colData.word0 = PX3_DEFAULT;
|
||||
|
||||
//set local pose - actor->createShape with a local pose is deprecated in physx 3.3
|
||||
pShape->setLocalPose(desc->pose);
|
||||
//set the skin width
|
||||
pShape->setContactOffset(0.01f);
|
||||
pShape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !isTrigger);
|
||||
pShape->setFlag(physx::PxShapeFlag::eSCENE_QUERY_SHAPE,true);
|
||||
pShape->setSimulationFilterData(colData);
|
||||
pShape->setQueryFilterData(colData);
|
||||
}
|
||||
|
||||
//mass & intertia has to be set after creating the shape
|
||||
if ( mass > 0.0f )
|
||||
{
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor,mass);
|
||||
}
|
||||
|
||||
// This sucks, but it has to happen if we want
|
||||
// to avoid write lock errors from PhysX right now.
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
mWorld->getScene()->addActor(*mActor);
|
||||
mIsEnabled = true;
|
||||
|
||||
if ( isDebris )
|
||||
mActor->setDominanceGroup( 31 );
|
||||
|
||||
mUserData.setObject( obj );
|
||||
mUserData.setBody( this );
|
||||
mActor->userData = &mUserData;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Px3Body::setMaterial( F32 restitution,
|
||||
F32 friction,
|
||||
F32 staticFriction )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setMaterial - The actor is null!" );
|
||||
|
||||
if ( isDynamic() )
|
||||
{
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
actor->wakeUp();
|
||||
}
|
||||
|
||||
mMaterial->setRestitution(restitution);
|
||||
mMaterial->setStaticFriction(staticFriction);
|
||||
mMaterial->setDynamicFriction(friction);
|
||||
|
||||
}
|
||||
|
||||
void Px3Body::setSleepThreshold( F32 linear, F32 angular )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setSleepThreshold - The actor is null!" );
|
||||
|
||||
if(mIsStatic)
|
||||
return;
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
physx::PxF32 massNormalized= (linear*linear+angular*angular)/2.0f;
|
||||
actor->setSleepThreshold(massNormalized);
|
||||
}
|
||||
|
||||
void Px3Body::setDamping( F32 linear, F32 angular )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setDamping - The actor is null!" );
|
||||
if(mIsStatic)
|
||||
return;
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
actor->setLinearDamping( linear );
|
||||
actor->setAngularDamping( angular );
|
||||
}
|
||||
|
||||
void Px3Body::getState( PhysicsState *outState )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getState - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::getState - This call is only for dynamics!" );
|
||||
|
||||
outState->position = px3Cast<Point3F>( mActor->getGlobalPose().p );
|
||||
outState->orientation = px3Cast<QuatF>( mActor->getGlobalPose().q );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
outState->linVelocity = px3Cast<Point3F>( actor->getLinearVelocity() );
|
||||
outState->angVelocity = px3Cast<Point3F>( actor->getAngularVelocity() );
|
||||
outState->sleeping = actor->isSleeping();
|
||||
outState->momentum = px3Cast<Point3F>( (1.0f/actor->getMass()) * actor->getLinearVelocity() );
|
||||
|
||||
}
|
||||
|
||||
F32 Px3Body::getMass() const
|
||||
{
|
||||
AssertFatal( mActor, "PxBody::getCMassPosition - The actor is null!" );
|
||||
if(mIsStatic)
|
||||
return 0;
|
||||
|
||||
const physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
return actor->getMass();
|
||||
}
|
||||
|
||||
Point3F Px3Body::getCMassPosition() const
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getCMassPosition - The actor is null!" );
|
||||
if(mIsStatic)
|
||||
return px3Cast<Point3F>(mActor->getGlobalPose().p);
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
physx::PxTransform pose = actor->getGlobalPose() * actor->getCMassLocalPose();
|
||||
return px3Cast<Point3F>(pose.p);
|
||||
}
|
||||
|
||||
void Px3Body::setLinVelocity( const Point3F &vel )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setLinVelocity - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::setLinVelocity - This call is only for dynamics!" );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
actor->setLinearVelocity( px3Cast<physx::PxVec3>( vel ) );
|
||||
}
|
||||
|
||||
void Px3Body::setAngVelocity( const Point3F &vel )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setAngVelocity - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::setAngVelocity - This call is only for dynamics!" );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
actor->setAngularVelocity(px3Cast<physx::PxVec3>( vel ) );
|
||||
}
|
||||
|
||||
Point3F Px3Body::getLinVelocity() const
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getLinVelocity - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::getLinVelocity - This call is only for dynamics!" );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
return px3Cast<Point3F>( actor->getLinearVelocity() );
|
||||
}
|
||||
|
||||
Point3F Px3Body::getAngVelocity() const
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getAngVelocity - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::getAngVelocity - This call is only for dynamics!" );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
return px3Cast<Point3F>( actor->getAngularVelocity() );
|
||||
}
|
||||
|
||||
void Px3Body::setSleeping( bool sleeping )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setSleeping - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::setSleeping - This call is only for dynamics!" );
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
if ( sleeping )
|
||||
actor->putToSleep();
|
||||
else
|
||||
actor->wakeUp();
|
||||
}
|
||||
|
||||
bool Px3Body::isDynamic() const
|
||||
{
|
||||
AssertFatal( mActor, "PxBody::isDynamic - The actor is null!" );
|
||||
return !mIsStatic && ( mBodyFlags & BF_KINEMATIC ) == 0;
|
||||
}
|
||||
|
||||
PhysicsWorld* Px3Body::getWorld()
|
||||
{
|
||||
return mWorld;
|
||||
}
|
||||
|
||||
PhysicsCollision* Px3Body::getColShape()
|
||||
{
|
||||
return mColShape;
|
||||
}
|
||||
|
||||
MatrixF& Px3Body::getTransform( MatrixF *outMatrix )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getTransform - The actor is null!" );
|
||||
|
||||
*outMatrix = px3Cast<MatrixF>(mActor->getGlobalPose());
|
||||
return *outMatrix;
|
||||
}
|
||||
|
||||
Box3F Px3Body::getWorldBounds()
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::getTransform - The actor is null!" );
|
||||
|
||||
physx::PxBounds3 bounds;
|
||||
bounds.setEmpty();
|
||||
physx::PxBounds3 shapeBounds;
|
||||
|
||||
|
||||
U32 shapeCount = mActor->getNbShapes();
|
||||
physx::PxShape **shapes = new physx::PxShape*[shapeCount];
|
||||
mActor->getShapes(shapes, shapeCount);
|
||||
for ( U32 i = 0; i < shapeCount; i++ )
|
||||
{
|
||||
// Get the shape's bounds.
|
||||
shapeBounds = physx::PxShapeExt::getWorldBounds(*shapes[i],*mActor);
|
||||
// Combine them into the total bounds.
|
||||
bounds.include( shapeBounds );
|
||||
}
|
||||
|
||||
delete [] shapes;
|
||||
|
||||
return px3Cast<Box3F>( bounds );
|
||||
}
|
||||
|
||||
void Px3Body::setSimulationEnabled( bool enabled )
|
||||
{
|
||||
if ( mIsEnabled == enabled )
|
||||
return;
|
||||
|
||||
//Don't need to enable/disable eSIMULATION_SHAPE for trigger,it's disabled permanently
|
||||
if(mBodyFlags & BF_TRIGGER)
|
||||
return;
|
||||
|
||||
// This sucks, but it has to happen if we want
|
||||
// to avoid write lock errors from PhysX right now.
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
U32 shapeCount = mActor->getNbShapes();
|
||||
physx::PxShape **shapes = new physx::PxShape*[shapeCount];
|
||||
mActor->getShapes(shapes, shapeCount);
|
||||
for ( S32 i = 0; i < mActor->getNbShapes(); i++ )
|
||||
{
|
||||
shapes[i]->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,!mIsEnabled);//?????
|
||||
}
|
||||
|
||||
delete [] shapes;
|
||||
}
|
||||
void Px3Body::setTransform( const MatrixF &transform )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::setTransform - The actor is null!" );
|
||||
|
||||
|
||||
// This sucks, but it has to happen if we want
|
||||
// to avoid write lock errors from PhysX right now.
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
|
||||
mActor->setGlobalPose(px3Cast<physx::PxTransform>(transform),false);
|
||||
|
||||
if(mIsStatic)
|
||||
return;
|
||||
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
bool kinematic = actor->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC;
|
||||
// If its dynamic we have more to do.
|
||||
if ( isDynamic() && !kinematic )
|
||||
{
|
||||
actor->setLinearVelocity( physx::PxVec3(0) );
|
||||
actor->setAngularVelocity( physx::PxVec3(0) );
|
||||
actor->wakeUp();
|
||||
}
|
||||
}
|
||||
|
||||
void Px3Body::applyCorrection( const MatrixF &transform )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::applyCorrection - The actor is null!" );
|
||||
AssertFatal( isDynamic(), "Px3Body::applyCorrection - This call is only for dynamics!" );
|
||||
|
||||
// This sucks, but it has to happen if we want
|
||||
// to avoid write lock errors from PhysX right now.
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
mActor->setGlobalPose( px3Cast<physx::PxTransform>(transform) );
|
||||
}
|
||||
|
||||
void Px3Body::applyImpulse( const Point3F &origin, const Point3F &force )
|
||||
{
|
||||
AssertFatal( mActor, "Px3Body::applyImpulse - The actor is null!" );
|
||||
|
||||
// This sucks, but it has to happen if we want
|
||||
// to avoid write lock errors from PhysX right now.
|
||||
mWorld->releaseWriteLock();
|
||||
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||
if ( mIsEnabled && isDynamic() )
|
||||
physx::PxRigidBodyExt::addForceAtPos(*actor,px3Cast<physx::PxVec3>(force),
|
||||
px3Cast<physx::PxVec3>(origin),
|
||||
physx::PxForceMode::eIMPULSE);
|
||||
|
||||
}
|
||||
|
||||
122
Engine/source/T3D/physics/physx3/px3Body.h
Normal file
122
Engine/source/T3D/physics/physx3/px3Body.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3BODY_H_
|
||||
#define _PX3BODY_H_
|
||||
|
||||
#ifndef _T3D_PHYSICS_PHYSICSBODY_H_
|
||||
#include "T3D/physics/physicsBody.h"
|
||||
#endif
|
||||
#ifndef _PHYSICS_PHYSICSUSERDATA_H_
|
||||
#include "T3D/physics/physicsUserData.h"
|
||||
#endif
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
|
||||
class Px3World;
|
||||
class Px3Collision;
|
||||
struct Px3CollisionDesc;
|
||||
|
||||
namespace physx{
|
||||
class PxRigidActor;
|
||||
class PxMaterial;
|
||||
class PxShape;
|
||||
}
|
||||
|
||||
|
||||
class Px3Body : public PhysicsBody
|
||||
{
|
||||
protected:
|
||||
|
||||
/// The physics world we are in.
|
||||
Px3World *mWorld;
|
||||
|
||||
/// The physics actor.
|
||||
physx::PxRigidActor *mActor;
|
||||
|
||||
/// The unshared local material used on all the
|
||||
/// shapes on this actor.
|
||||
physx::PxMaterial *mMaterial;
|
||||
|
||||
/// We hold the collision reference as it contains
|
||||
/// allocated objects that we own and must free.
|
||||
StrongRefPtr<Px3Collision> mColShape;
|
||||
|
||||
///
|
||||
MatrixF mInternalTransform;
|
||||
|
||||
/// The body flags set at creation time.
|
||||
U32 mBodyFlags;
|
||||
|
||||
/// Is true if this body is enabled and active
|
||||
/// in the simulation of the scene.
|
||||
bool mIsEnabled;
|
||||
bool mIsStatic;
|
||||
|
||||
///
|
||||
void _releaseActor();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Px3Body();
|
||||
virtual ~Px3Body();
|
||||
|
||||
// PhysicsObject
|
||||
virtual PhysicsWorld* getWorld();
|
||||
virtual void setTransform( const MatrixF &xfm );
|
||||
virtual MatrixF& getTransform( MatrixF *outMatrix );
|
||||
virtual Box3F getWorldBounds();
|
||||
virtual void setSimulationEnabled( bool enabled );
|
||||
virtual bool isSimulationEnabled() { return mIsEnabled; }
|
||||
|
||||
// PhysicsBody
|
||||
virtual bool init( PhysicsCollision *shape,
|
||||
F32 mass,
|
||||
U32 bodyFlags,
|
||||
SceneObject *obj,
|
||||
PhysicsWorld *world );
|
||||
|
||||
virtual bool isDynamic() const;
|
||||
virtual PhysicsCollision* getColShape();
|
||||
virtual void setSleepThreshold( F32 linear, F32 angular );
|
||||
virtual void setDamping( F32 linear, F32 angular );
|
||||
virtual void getState( PhysicsState *outState );
|
||||
virtual F32 getMass() const;
|
||||
virtual Point3F getCMassPosition() const;
|
||||
virtual void setLinVelocity( const Point3F &vel );
|
||||
virtual void setAngVelocity( const Point3F &vel );
|
||||
virtual Point3F getLinVelocity() const;
|
||||
virtual Point3F getAngVelocity() const;
|
||||
virtual void setSleeping( bool sleeping );
|
||||
virtual void setMaterial( F32 restitution,
|
||||
F32 friction,
|
||||
F32 staticFriction );
|
||||
virtual void applyCorrection( const MatrixF &xfm );
|
||||
virtual void applyImpulse( const Point3F &origin, const Point3F &force );
|
||||
};
|
||||
|
||||
#endif // _PX3BODY_H_
|
||||
137
Engine/source/T3D/physics/physx3/px3Casts.h
Normal file
137
Engine/source/T3D/physics/physx3/px3Casts.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3CASTS_H_
|
||||
#define _PX3CASTS_H_
|
||||
|
||||
#ifndef _MPOINT3_H_
|
||||
#include "math/mPoint3.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
#ifndef _MBOX_H_
|
||||
#include "math/mBox.h"
|
||||
#endif
|
||||
#ifndef _MQUAT_H_
|
||||
#include "math/mQuat.h"
|
||||
#endif
|
||||
#ifndef _MTRANSFORM_H_
|
||||
#include "math/mTransform.h"
|
||||
#endif
|
||||
|
||||
|
||||
template <class T, class F> inline T px3Cast( const F &from );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline Point3F px3Cast( const physx::PxVec3 &vec )
|
||||
{
|
||||
return Point3F( vec.x, vec.y, vec.z );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline physx::PxVec3 px3Cast( const Point3F &point )
|
||||
{
|
||||
return physx::PxVec3( point.x, point.y, point.z );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
template<>
|
||||
inline QuatF px3Cast( const physx::PxQuat &quat )
|
||||
{
|
||||
/// The Torque quat has the opposite winding order.
|
||||
return QuatF( -quat.x, -quat.y, -quat.z, quat.w );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline physx::PxQuat px3Cast( const QuatF &quat )
|
||||
{
|
||||
/// The Torque quat has the opposite winding order.
|
||||
physx::PxQuat result( -quat.x, -quat.y, -quat.z, quat.w );
|
||||
return result;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline physx::PxExtendedVec3 px3Cast( const Point3F &point )
|
||||
{
|
||||
return physx::PxExtendedVec3( point.x, point.y, point.z );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Point3F px3Cast( const physx::PxExtendedVec3 &xvec )
|
||||
{
|
||||
return Point3F( xvec.x, xvec.y, xvec.z );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline physx::PxBounds3 px3Cast( const Box3F &box )
|
||||
{
|
||||
physx::PxBounds3 bounds(px3Cast<physx::PxVec3>(box.minExtents),
|
||||
px3Cast<physx::PxVec3>(box.maxExtents));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Box3F px3Cast( const physx::PxBounds3 &bounds )
|
||||
{
|
||||
return Box3F( bounds.minimum.x,
|
||||
bounds.minimum.y,
|
||||
bounds.minimum.z,
|
||||
bounds.maximum.x,
|
||||
bounds.maximum.y,
|
||||
bounds.maximum.z );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline physx::PxTransform px3Cast( const MatrixF &xfm )
|
||||
{
|
||||
physx::PxTransform out;
|
||||
QuatF q;
|
||||
q.set(xfm);
|
||||
out.q = px3Cast<physx::PxQuat>(q);
|
||||
out.p = px3Cast<physx::PxVec3>(xfm.getPosition());
|
||||
return out;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline TransformF px3Cast(const physx::PxTransform &xfm)
|
||||
{
|
||||
TransformF out(px3Cast<Point3F>(xfm.p),AngAxisF(px3Cast<QuatF>(xfm.q)));
|
||||
return out;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline MatrixF px3Cast( const physx::PxTransform &xfm )
|
||||
{
|
||||
MatrixF out;
|
||||
TransformF t = px3Cast<TransformF>(xfm);
|
||||
out = t.getMatrix();
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif //_PX3CASTS_H_
|
||||
217
Engine/source/T3D/physics/physx3/px3Collision.cpp
Normal file
217
Engine/source/T3D/physics/physx3/px3Collision.cpp
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3Collision.h"
|
||||
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mMatrix.h"
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#include "T3D/physics/physx3/px3Casts.h"
|
||||
#include "T3D/physics/physx3/px3World.h"
|
||||
#include "T3D/physics/physx3/px3Stream.h"
|
||||
|
||||
|
||||
Px3Collision::Px3Collision()
|
||||
{
|
||||
}
|
||||
|
||||
Px3Collision::~Px3Collision()
|
||||
{
|
||||
|
||||
for ( U32 i=0; i < mColShapes.size(); i++ )
|
||||
{
|
||||
Px3CollisionDesc *desc = mColShapes[i];
|
||||
delete desc->pGeometry;
|
||||
// Delete the descriptor.
|
||||
delete desc;
|
||||
}
|
||||
|
||||
mColShapes.clear();
|
||||
}
|
||||
|
||||
void Px3Collision::addPlane( const PlaneF &plane )
|
||||
{
|
||||
physx::PxVec3 pos = px3Cast<physx::PxVec3>(plane.getPosition());
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = new physx::PxPlaneGeometry();
|
||||
desc->pose = physx::PxTransform(pos, physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0.0f, -1.0f, 0.0f)));
|
||||
mColShapes.push_back(desc);
|
||||
}
|
||||
|
||||
void Px3Collision::addBox( const Point3F &halfWidth,const MatrixF &localXfm )
|
||||
{
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = new physx::PxBoxGeometry(px3Cast<physx::PxVec3>(halfWidth));
|
||||
desc->pose = px3Cast<physx::PxTransform>(localXfm);
|
||||
mColShapes.push_back(desc);
|
||||
}
|
||||
|
||||
void Px3Collision::addSphere( F32 radius,
|
||||
const MatrixF &localXfm )
|
||||
{
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = new physx::PxSphereGeometry(radius);
|
||||
desc->pose = px3Cast<physx::PxTransform>(localXfm);
|
||||
mColShapes.push_back(desc);
|
||||
}
|
||||
|
||||
void Px3Collision::addCapsule( F32 radius,
|
||||
F32 height,
|
||||
const MatrixF &localXfm )
|
||||
{
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = new physx::PxCapsuleGeometry(radius,height*0.5);//uses half height
|
||||
desc->pose = px3Cast<physx::PxTransform>(localXfm);
|
||||
mColShapes.push_back(desc);
|
||||
}
|
||||
|
||||
bool Px3Collision::addConvex( const Point3F *points,
|
||||
U32 count,
|
||||
const MatrixF &localXfm )
|
||||
{
|
||||
physx::PxCooking *cooking = Px3World::getCooking();
|
||||
physx::PxConvexMeshDesc convexDesc;
|
||||
convexDesc.points.data = points;
|
||||
convexDesc.points.stride = sizeof(Point3F);
|
||||
convexDesc.points.count = count;
|
||||
convexDesc.flags = physx::PxConvexFlag::eFLIPNORMALS|physx::PxConvexFlag::eCOMPUTE_CONVEX | physx::PxConvexFlag::eINFLATE_CONVEX;
|
||||
|
||||
Px3MemOutStream stream;
|
||||
if(!cooking->cookConvexMesh(convexDesc,stream))
|
||||
return false;
|
||||
|
||||
physx::PxConvexMesh* convexMesh;
|
||||
Px3MemInStream in(stream.getData(), stream.getSize());
|
||||
convexMesh = gPhysics3SDK->createConvexMesh(in);
|
||||
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
physx::PxVec3 scale = px3Cast<physx::PxVec3>(localXfm.getScale());
|
||||
physx::PxQuat rotation = px3Cast<physx::PxQuat>(QuatF(localXfm));
|
||||
physx::PxMeshScale meshScale(scale,rotation);
|
||||
desc->pGeometry = new physx::PxConvexMeshGeometry(convexMesh,meshScale);
|
||||
desc->pose = px3Cast<physx::PxTransform>(localXfm);
|
||||
mColShapes.push_back(desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Px3Collision::addTriangleMesh( const Point3F *vert,
|
||||
U32 vertCount,
|
||||
const U32 *index,
|
||||
U32 triCount,
|
||||
const MatrixF &localXfm )
|
||||
{
|
||||
physx::PxCooking *cooking = Px3World::getCooking();
|
||||
physx::PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = vertCount;
|
||||
meshDesc.points.data = vert;
|
||||
meshDesc.points.stride = sizeof(Point3F);
|
||||
|
||||
meshDesc.triangles.count = triCount;
|
||||
meshDesc.triangles.data = index;
|
||||
meshDesc.triangles.stride = 3*sizeof(U32);
|
||||
meshDesc.flags = physx::PxMeshFlag::eFLIPNORMALS;
|
||||
|
||||
Px3MemOutStream stream;
|
||||
if(!cooking->cookTriangleMesh(meshDesc,stream))
|
||||
return false;
|
||||
|
||||
physx::PxTriangleMesh *mesh;
|
||||
Px3MemInStream in(stream.getData(), stream.getSize());
|
||||
mesh = gPhysics3SDK->createTriangleMesh(in);
|
||||
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = new physx::PxTriangleMeshGeometry(mesh);
|
||||
desc->pose = px3Cast<physx::PxTransform>(localXfm);
|
||||
mColShapes.push_back(desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Px3Collision::addHeightfield( const U16 *heights,
|
||||
const bool *holes,
|
||||
U32 blockSize,
|
||||
F32 metersPerSample,
|
||||
const MatrixF &localXfm )
|
||||
{
|
||||
const F32 heightScale = 0.03125f;
|
||||
physx::PxHeightFieldSample* samples = (physx::PxHeightFieldSample*) new physx::PxHeightFieldSample[blockSize*blockSize];
|
||||
memset(samples,0,blockSize*blockSize*sizeof(physx::PxHeightFieldSample));
|
||||
|
||||
physx::PxHeightFieldDesc heightFieldDesc;
|
||||
heightFieldDesc.nbColumns = blockSize;
|
||||
heightFieldDesc.nbRows = blockSize;
|
||||
heightFieldDesc.thickness = -10.f;
|
||||
heightFieldDesc.convexEdgeThreshold = 0;
|
||||
heightFieldDesc.format = physx::PxHeightFieldFormat::eS16_TM;
|
||||
heightFieldDesc.samples.data = samples;
|
||||
heightFieldDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
|
||||
|
||||
physx::PxU8 *currentByte = (physx::PxU8*)heightFieldDesc.samples.data;
|
||||
for ( U32 row = 0; row < blockSize; row++ )
|
||||
{
|
||||
const U32 tess = ( row + 1 ) % 2;
|
||||
|
||||
for ( U32 column = 0; column < blockSize; column++ )
|
||||
{
|
||||
physx::PxHeightFieldSample *currentSample = (physx::PxHeightFieldSample*)currentByte;
|
||||
|
||||
U32 index = ( blockSize - row - 1 ) + ( column * blockSize );
|
||||
currentSample->height = (physx::PxI16)heights[ index ];
|
||||
|
||||
|
||||
if ( holes && holes[ getMax( (S32)index - 1, 0 ) ] ) // row index for holes adjusted so PhysX collision shape better matches rendered terrain
|
||||
{
|
||||
currentSample->materialIndex0 = physx::PxHeightFieldMaterial::eHOLE;
|
||||
currentSample->materialIndex1 = physx::PxHeightFieldMaterial::eHOLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSample->materialIndex0 = 0;
|
||||
currentSample->materialIndex1 = 0;
|
||||
}
|
||||
|
||||
int flag = ( column + tess ) % 2;
|
||||
if(flag)
|
||||
currentSample->clearTessFlag();
|
||||
else
|
||||
currentSample->setTessFlag();
|
||||
|
||||
currentByte += heightFieldDesc.samples.stride;
|
||||
}
|
||||
}
|
||||
|
||||
physx::PxHeightField * hf = gPhysics3SDK->createHeightField(heightFieldDesc);
|
||||
physx::PxHeightFieldGeometry *geom = new physx::PxHeightFieldGeometry(hf,physx::PxMeshGeometryFlags(),heightScale,metersPerSample,metersPerSample);
|
||||
|
||||
physx::PxTransform pose= physx::PxTransform(physx::PxQuat(Float_HalfPi, physx::PxVec3(1, 0, 0 )));
|
||||
physx::PxTransform pose1= physx::PxTransform(physx::PxQuat(Float_Pi, physx::PxVec3(0, 0, 1 )));
|
||||
physx::PxTransform pose2 = pose1 * pose;
|
||||
pose2.p = physx::PxVec3(( blockSize - 1 ) * metersPerSample, 0, 0 );
|
||||
Px3CollisionDesc *desc = new Px3CollisionDesc;
|
||||
desc->pGeometry = geom;
|
||||
desc->pose = pose2;
|
||||
|
||||
mColShapes.push_back(desc);
|
||||
|
||||
SAFE_DELETE(samples);
|
||||
return true;
|
||||
}
|
||||
87
Engine/source/T3D/physics/physx3/px3Collision.h
Normal file
87
Engine/source/T3D/physics/physx3/px3Collision.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3COLLISION_H_
|
||||
#define _PX3COLLISION_H_
|
||||
|
||||
#ifndef _T3D_PHYSICS_PHYSICSCOLLISION_H_
|
||||
#include "T3D/physics/physicsCollision.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
|
||||
#include <foundation/PxTransform.h>
|
||||
|
||||
//forward declare
|
||||
namespace physx{class PxGeometry;}
|
||||
|
||||
|
||||
struct Px3CollisionDesc
|
||||
{
|
||||
physx::PxGeometry *pGeometry;
|
||||
physx::PxTransform pose;
|
||||
};
|
||||
|
||||
class Px3Collision : public PhysicsCollision
|
||||
{
|
||||
typedef Vector<Px3CollisionDesc*> Px3CollisionList;
|
||||
protected:
|
||||
/// The collision representation.
|
||||
Px3CollisionList mColShapes;
|
||||
|
||||
public:
|
||||
|
||||
Px3Collision();
|
||||
virtual ~Px3Collision();
|
||||
|
||||
/// Return the PhysX shape descriptions.
|
||||
const Px3CollisionList& getShapes() const { return mColShapes; }
|
||||
|
||||
// PhysicsCollision
|
||||
virtual void addPlane( const PlaneF &plane );
|
||||
virtual void addBox( const Point3F &halfWidth,
|
||||
const MatrixF &localXfm );
|
||||
virtual void addSphere( F32 radius,
|
||||
const MatrixF &localXfm );
|
||||
virtual void addCapsule( F32 radius,
|
||||
F32 height,
|
||||
const MatrixF &localXfm );
|
||||
virtual bool addConvex( const Point3F *points,
|
||||
U32 count,
|
||||
const MatrixF &localXfm );
|
||||
virtual bool addTriangleMesh( const Point3F *vert,
|
||||
U32 vertCount,
|
||||
const U32 *index,
|
||||
U32 triCount,
|
||||
const MatrixF &localXfm );
|
||||
virtual bool addHeightfield( const U16 *heights,
|
||||
const bool *holes,
|
||||
U32 blockSize,
|
||||
F32 metersPerSample,
|
||||
const MatrixF &localXfm );
|
||||
};
|
||||
|
||||
#endif // _PX3COLLISION_H_
|
||||
331
Engine/source/T3D/physics/physx3/px3Player.cpp
Normal file
331
Engine/source/T3D/physics/physx3/px3Player.cpp
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3Player.h"
|
||||
#include "T3D/physics/physicsPlugin.h"
|
||||
#include "T3D/physics/physx3/px3World.h"
|
||||
#include "T3D/physics/physx3/px3Casts.h"
|
||||
#include "T3D/physics/physx3/px3Utils.h"
|
||||
#include "collision/collision.h"
|
||||
|
||||
|
||||
Px3Player::Px3Player()
|
||||
: PhysicsPlayer(),
|
||||
mController( NULL ),
|
||||
mWorld( NULL ),
|
||||
mObject( NULL ),
|
||||
mSkinWidth( 0.05f ),
|
||||
mOriginOffset( 0.0f ),
|
||||
mElapsed(0)
|
||||
{
|
||||
PHYSICSMGR->getPhysicsResetSignal().notify( this, &Px3Player::_onPhysicsReset );
|
||||
}
|
||||
|
||||
Px3Player::~Px3Player()
|
||||
{
|
||||
_releaseController();
|
||||
PHYSICSMGR->getPhysicsResetSignal().remove( this, &Px3Player::_onPhysicsReset );
|
||||
}
|
||||
|
||||
void Px3Player::_releaseController()
|
||||
{
|
||||
if ( mController )
|
||||
{
|
||||
mController->getActor()->userData = NULL;
|
||||
mWorld->getStaticChangedSignal().remove( this, &Px3Player::_onStaticChanged );
|
||||
mController->release();
|
||||
}
|
||||
}
|
||||
|
||||
void Px3Player::init( const char *type,
|
||||
const Point3F &size,
|
||||
F32 runSurfaceCos,
|
||||
F32 stepHeight,
|
||||
SceneObject *obj,
|
||||
PhysicsWorld *world )
|
||||
{
|
||||
AssertFatal( obj, "Px3Player::init - Got a null scene object!" );
|
||||
AssertFatal( world, "Px3Player::init - Got a null world!" );
|
||||
AssertFatal( dynamic_cast<Px3World*>( world ), "Px3Player::init - The world is the wrong type!" );
|
||||
|
||||
// Cleanup any previous controller.
|
||||
_releaseController();
|
||||
|
||||
mObject = obj;
|
||||
mWorld = (Px3World*)world;
|
||||
mOriginOffset = size.z * 0.5f;
|
||||
|
||||
physx::PxCapsuleControllerDesc desc;
|
||||
desc.contactOffset = mSkinWidth;
|
||||
desc.radius = getMax( size.x, size.y ) * 0.5f;
|
||||
desc.radius -= mSkinWidth;
|
||||
desc.height = size.z - ( desc.radius * 2.0f );
|
||||
desc.height -= mSkinWidth * 2.0f;
|
||||
desc.climbingMode = physx::PxCapsuleClimbingMode::eCONSTRAINED;
|
||||
desc.position.set( 0, 0, 0 );
|
||||
desc.upDirection = physx::PxVec3(0,0,1);
|
||||
desc.reportCallback = this;
|
||||
desc.slopeLimit = runSurfaceCos;
|
||||
desc.stepOffset = stepHeight;
|
||||
desc.behaviorCallback = NULL;
|
||||
desc.material = gPhysics3SDK->createMaterial(0.1f, 0.1f, 0.2f);
|
||||
|
||||
mController = mWorld->createController( desc );
|
||||
|
||||
mWorld->getStaticChangedSignal().notify( this, &Px3Player::_onStaticChanged );
|
||||
physx::PxRigidDynamic *kineActor = mController->getActor();
|
||||
|
||||
//player only has one shape
|
||||
physx::PxShape *shape = px3GetFirstShape(kineActor);
|
||||
physx::PxFilterData colData;
|
||||
colData.word0 = PX3_PLAYER;
|
||||
shape->setSimulationFilterData(colData);
|
||||
shape->setQueryFilterData(colData);
|
||||
|
||||
//store geometry for later use in findContact calls
|
||||
shape->getCapsuleGeometry(mGeometry);
|
||||
|
||||
mUserData.setObject( obj );
|
||||
kineActor->userData = &mUserData;
|
||||
|
||||
}
|
||||
|
||||
void Px3Player::_onStaticChanged()
|
||||
{
|
||||
if(mController)
|
||||
mController->invalidateCache();
|
||||
}
|
||||
|
||||
void Px3Player::_onPhysicsReset( PhysicsResetEvent reset )
|
||||
{
|
||||
if(mController)
|
||||
mController->invalidateCache();
|
||||
}
|
||||
|
||||
Point3F Px3Player::move( const VectorF &disp, CollisionList &outCol )
|
||||
{
|
||||
AssertFatal( mController, "Px3Player::move - The controller is null!" );
|
||||
|
||||
// Return the last position if the simulation is stopped.
|
||||
//
|
||||
// See PxPlayer::_onPhysicsReset
|
||||
if ( !mWorld->isEnabled() )
|
||||
{
|
||||
Point3F newPos = px3Cast<Point3F>( mController->getPosition() );
|
||||
newPos.z -= mOriginOffset;
|
||||
return newPos;
|
||||
}
|
||||
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
mCollisionList = &outCol;
|
||||
|
||||
physx::PxVec3 dispNx( disp.x, disp.y, disp.z );
|
||||
if (mIsZero(disp.z))
|
||||
dispNx.z = 0.0f;
|
||||
|
||||
U32 groups = 0xffffffff;
|
||||
groups &= ~( PX3_TRIGGER ); // No trigger shapes!
|
||||
groups &= ~( PX3_DEBRIS);
|
||||
physx::PxControllerFilters filter;
|
||||
physx::PxFilterData data;
|
||||
data.word0=groups;
|
||||
filter.mFilterData = &data;
|
||||
filter.mFilterFlags = physx::PxSceneQueryFilterFlags(physx::PxControllerFlag::eCOLLISION_DOWN|physx::PxControllerFlag::eCOLLISION_SIDES|physx::PxControllerFlag::eCOLLISION_UP);
|
||||
|
||||
mController->move( dispNx,0.0001f,0, filter );
|
||||
|
||||
Point3F newPos = px3Cast<Point3F>( mController->getPosition() );
|
||||
newPos.z -= mOriginOffset;
|
||||
|
||||
mCollisionList = NULL;
|
||||
|
||||
return newPos;
|
||||
}
|
||||
|
||||
void Px3Player::onShapeHit( const physx::PxControllerShapeHit& hit )
|
||||
{
|
||||
if (!mCollisionList || mCollisionList->getCount() >= CollisionList::MaxCollisions)
|
||||
return;
|
||||
|
||||
physx::PxRigidActor *actor = hit.actor;
|
||||
PhysicsUserData *userData = PhysicsUserData::cast( actor->userData );
|
||||
|
||||
// Fill out the Collision
|
||||
// structure for use later.
|
||||
Collision &col = mCollisionList->increment();
|
||||
dMemset( &col, 0, sizeof( col ) );
|
||||
|
||||
col.normal = px3Cast<Point3F>( hit.worldNormal );
|
||||
col.point = px3Cast<Point3F>( hit.worldPos );
|
||||
col.distance = hit.length;
|
||||
if ( userData )
|
||||
col.object = userData->getObject();
|
||||
|
||||
if (mIsZero(hit.dir.z))
|
||||
{
|
||||
if (col.normal.z > 0.0f)
|
||||
{
|
||||
col.normal.z = 0.0f;
|
||||
col.normal.normalizeSafe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
col.normal.set(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Px3Player::onControllerHit( const physx::PxControllersHit& hit )
|
||||
{
|
||||
if (!mCollisionList || mCollisionList->getCount() >= CollisionList::MaxCollisions)
|
||||
return;
|
||||
|
||||
physx::PxRigidActor *actor = hit.other->getActor();
|
||||
PhysicsUserData *userData = PhysicsUserData::cast( actor->userData );
|
||||
|
||||
// For controller-to-controller hit we don't have an actual hit point, so all
|
||||
// we can do is set the hit object.
|
||||
Collision &col = mCollisionList->increment();
|
||||
dMemset( &col, 0, sizeof( col ) );
|
||||
if ( userData )
|
||||
col.object = userData->getObject();
|
||||
|
||||
}
|
||||
|
||||
void Px3Player::findContact( SceneObject **contactObject,
|
||||
VectorF *contactNormal,
|
||||
Vector<SceneObject*> *outOverlapObjects ) const
|
||||
{
|
||||
// Calculate the sweep motion...
|
||||
F32 halfCapSize = mOriginOffset;
|
||||
F32 halfSmallCapSize = halfCapSize * 0.8f;
|
||||
F32 diff = halfCapSize - halfSmallCapSize;
|
||||
|
||||
F32 distance = diff + mSkinWidth + 0.01f;
|
||||
physx::PxVec3 dir(0,0,-1);
|
||||
|
||||
physx::PxScene *scene = mWorld->getScene();
|
||||
physx::PxHitFlags hitFlags(physx::PxHitFlag::eDEFAULT);
|
||||
physx::PxQueryFilterData filterData(physx::PxQueryFlag::eDYNAMIC|physx::PxQueryFlag::eSTATIC);
|
||||
filterData.data.word0 = PX3_DEFAULT;
|
||||
physx::PxSweepHit sweepHit;
|
||||
physx::PxRigidDynamic *actor= mController->getActor();
|
||||
physx::PxU32 shapeIndex;
|
||||
|
||||
bool hit = physx::PxRigidBodyExt::linearSweepSingle(*actor,*scene,dir,distance,hitFlags,sweepHit,shapeIndex,filterData);
|
||||
if ( hit )
|
||||
{
|
||||
PhysicsUserData *data = PhysicsUserData::cast( sweepHit.actor->userData);
|
||||
if ( data )
|
||||
{
|
||||
*contactObject = data->getObject();
|
||||
*contactNormal = px3Cast<Point3F>( sweepHit.normal );
|
||||
}
|
||||
}
|
||||
|
||||
// Check for overlapped objects ( triggers )
|
||||
|
||||
if ( !outOverlapObjects )
|
||||
return;
|
||||
|
||||
filterData.data.word0 = PX3_TRIGGER;
|
||||
|
||||
const physx::PxU32 bufferSize = 10;
|
||||
physx::PxOverlapBufferN<bufferSize> hitBuffer;
|
||||
hit = scene->overlap(mGeometry,actor->getGlobalPose(),hitBuffer,filterData);
|
||||
if(hit)
|
||||
{
|
||||
for ( U32 i = 0; i < hitBuffer.nbTouches; i++ )
|
||||
{
|
||||
PhysicsUserData *data = PhysicsUserData::cast( hitBuffer.touches[i].actor->userData );
|
||||
if ( data )
|
||||
outOverlapObjects->push_back( data->getObject() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Px3Player::enableCollision()
|
||||
{
|
||||
AssertFatal( mController, "Px3Player::enableCollision - The controller is null!" );
|
||||
|
||||
mWorld->releaseWriteLock();
|
||||
px3GetFirstShape(mController->getActor())->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,true);
|
||||
}
|
||||
|
||||
void Px3Player::disableCollision()
|
||||
{
|
||||
AssertFatal( mController, "Px3Player::disableCollision - The controller is null!" );
|
||||
|
||||
mWorld->releaseWriteLock();
|
||||
px3GetFirstShape(mController->getActor())->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,false);
|
||||
}
|
||||
|
||||
PhysicsWorld* Px3Player::getWorld()
|
||||
{
|
||||
return mWorld;
|
||||
}
|
||||
|
||||
void Px3Player::setTransform( const MatrixF &transform )
|
||||
{
|
||||
AssertFatal( mController, "Px3Player::setTransform - The controller is null!" );
|
||||
|
||||
mWorld->releaseWriteLock();
|
||||
|
||||
Point3F newPos = transform.getPosition();
|
||||
newPos.z += mOriginOffset;
|
||||
|
||||
const Point3F &curPos = px3Cast<Point3F>(mController->getPosition());
|
||||
|
||||
if ( !(newPos - curPos ).isZero() )
|
||||
mController->setPosition( px3Cast<physx::PxExtendedVec3>(newPos) );
|
||||
}
|
||||
|
||||
MatrixF& Px3Player::getTransform( MatrixF *outMatrix )
|
||||
{
|
||||
AssertFatal( mController, "Px3Player::getTransform - The controller is null!" );
|
||||
|
||||
Point3F newPos = px3Cast<Point3F>( mController->getPosition() );
|
||||
newPos.z -= mOriginOffset;
|
||||
outMatrix->setPosition( newPos );
|
||||
|
||||
return *outMatrix;
|
||||
}
|
||||
|
||||
void Px3Player::setScale( const Point3F &scale )
|
||||
{
|
||||
//Ignored
|
||||
}
|
||||
|
||||
Box3F Px3Player::getWorldBounds()
|
||||
{
|
||||
physx::PxBounds3 bounds;
|
||||
physx::PxRigidDynamic *actor = mController->getActor();
|
||||
physx::PxShape *shape = px3GetFirstShape(actor);
|
||||
bounds = physx::PxShapeExt::getWorldBounds(*shape,*actor);
|
||||
return px3Cast<Box3F>( bounds );
|
||||
}
|
||||
|
||||
104
Engine/source/T3D/physics/physx3/px3Player.h
Normal file
104
Engine/source/T3D/physics/physx3/px3Player.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3PLAYER_H
|
||||
#define _PX3PLAYER_H
|
||||
|
||||
#ifndef _PHYSX3_H_
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#endif
|
||||
#ifndef _T3D_PHYSICS_PHYSICSPLAYER_H_
|
||||
#include "T3D/physics/physicsPlayer.h"
|
||||
#endif
|
||||
#ifndef _T3D_PHYSICSCOMMON_H_
|
||||
#include "T3D/physics/physicsCommon.h"
|
||||
#endif
|
||||
|
||||
class Px3World;
|
||||
|
||||
class Px3Player : public PhysicsPlayer, public physx::PxUserControllerHitReport
|
||||
{
|
||||
protected:
|
||||
|
||||
physx::PxController *mController;
|
||||
physx::PxCapsuleGeometry mGeometry;
|
||||
F32 mSkinWidth;
|
||||
|
||||
Px3World *mWorld;
|
||||
|
||||
SceneObject *mObject;
|
||||
|
||||
/// Used to get collision info out of the
|
||||
/// PxUserControllerHitReport callbacks.
|
||||
CollisionList *mCollisionList;
|
||||
|
||||
///
|
||||
F32 mOriginOffset;
|
||||
|
||||
///
|
||||
F32 mStepHeight;
|
||||
U32 mElapsed;
|
||||
///
|
||||
void _releaseController();
|
||||
|
||||
|
||||
virtual void onShapeHit( const physx::PxControllerShapeHit &hit );
|
||||
virtual void onControllerHit( const physx::PxControllersHit &hit );
|
||||
virtual void onObstacleHit(const physx::PxControllerObstacleHit &){}
|
||||
|
||||
void _findContact( SceneObject **contactObject, VectorF *contactNormal ) const;
|
||||
|
||||
void _onPhysicsReset( PhysicsResetEvent reset );
|
||||
|
||||
void _onStaticChanged();
|
||||
|
||||
public:
|
||||
|
||||
Px3Player();
|
||||
virtual ~Px3Player();
|
||||
|
||||
// PhysicsObject
|
||||
virtual PhysicsWorld* getWorld();
|
||||
virtual void setTransform( const MatrixF &transform );
|
||||
virtual MatrixF& getTransform( MatrixF *outMatrix );
|
||||
virtual void setScale( const Point3F &scale );
|
||||
virtual Box3F getWorldBounds();
|
||||
virtual void setSimulationEnabled( bool enabled ) {}
|
||||
virtual bool isSimulationEnabled() { return true; }
|
||||
|
||||
// PhysicsPlayer
|
||||
virtual void init( const char *type,
|
||||
const Point3F &size,
|
||||
F32 runSurfaceCos,
|
||||
F32 stepHeight,
|
||||
SceneObject *obj,
|
||||
PhysicsWorld *world );
|
||||
virtual Point3F move( const VectorF &displacement, CollisionList &outCol );
|
||||
virtual void findContact( SceneObject **contactObject, VectorF *contactNormal, Vector<SceneObject*> *outOverlapObjects ) const;
|
||||
virtual bool testSpacials( const Point3F &nPos, const Point3F &nSize ) const { return true; }
|
||||
virtual void setSpacials( const Point3F &nPos, const Point3F &nSize ) {}
|
||||
virtual void enableCollision();
|
||||
virtual void disableCollision();
|
||||
};
|
||||
|
||||
|
||||
#endif // _PX3PLAYER_H_
|
||||
226
Engine/source/T3D/physics/physx3/px3Plugin.cpp
Normal file
226
Engine/source/T3D/physics/physx3/px3Plugin.cpp
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "T3D/physics/physx3/px3World.h"
|
||||
#include "T3D/physics/physx3/px3Plugin.h"
|
||||
#include "T3D/physics/physx3/px3Collision.h"
|
||||
#include "T3D/physics/physx3/px3Body.h"
|
||||
#include "T3D/physics/physx3/px3Player.h"
|
||||
|
||||
#include "T3D/physics/physicsShape.h"
|
||||
#include "T3D/gameBase/gameProcess.h"
|
||||
#include "core/util/tNamedFactory.h"
|
||||
|
||||
|
||||
AFTER_MODULE_INIT( Sim )
|
||||
{
|
||||
NamedFactory<PhysicsPlugin>::add( "PhysX3", &Px3Plugin::create );
|
||||
|
||||
#if defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XBOX) || defined(TORQUE_OS_XENON)
|
||||
NamedFactory<PhysicsPlugin>::add( "default", &Px3Plugin::create );
|
||||
#endif
|
||||
}
|
||||
|
||||
PhysicsPlugin* Px3Plugin::create()
|
||||
{
|
||||
// Only create the plugin if it hasn't been set up AND
|
||||
// the PhysX world is successfully initialized.
|
||||
bool success = Px3World::restartSDK( false );
|
||||
if ( success )
|
||||
return new Px3Plugin();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Px3Plugin::Px3Plugin()
|
||||
{
|
||||
}
|
||||
|
||||
Px3Plugin::~Px3Plugin()
|
||||
{
|
||||
}
|
||||
|
||||
void Px3Plugin::destroyPlugin()
|
||||
{
|
||||
// Cleanup any worlds that are still kicking.
|
||||
Map<StringNoCase, PhysicsWorld*>::Iterator iter = mPhysicsWorldLookup.begin();
|
||||
for ( ; iter != mPhysicsWorldLookup.end(); iter++ )
|
||||
{
|
||||
iter->value->destroyWorld();
|
||||
delete iter->value;
|
||||
}
|
||||
mPhysicsWorldLookup.clear();
|
||||
|
||||
Px3World::restartSDK( true );
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void Px3Plugin::reset()
|
||||
{
|
||||
// First delete all the cleanup objects.
|
||||
if ( getPhysicsCleanup() )
|
||||
getPhysicsCleanup()->deleteAllObjects();
|
||||
|
||||
getPhysicsResetSignal().trigger( PhysicsResetEvent_Restore );
|
||||
|
||||
// Now let each world reset itself.
|
||||
Map<StringNoCase, PhysicsWorld*>::Iterator iter = mPhysicsWorldLookup.begin();
|
||||
for ( ; iter != mPhysicsWorldLookup.end(); iter++ )
|
||||
iter->value->reset();
|
||||
}
|
||||
|
||||
PhysicsCollision* Px3Plugin::createCollision()
|
||||
{
|
||||
return new Px3Collision();
|
||||
}
|
||||
|
||||
PhysicsBody* Px3Plugin::createBody()
|
||||
{
|
||||
return new Px3Body();
|
||||
}
|
||||
|
||||
PhysicsPlayer* Px3Plugin::createPlayer()
|
||||
{
|
||||
return new Px3Player();
|
||||
}
|
||||
|
||||
bool Px3Plugin::isSimulationEnabled() const
|
||||
{
|
||||
bool ret = false;
|
||||
Px3World *world = static_cast<Px3World*>( getWorld( smClientWorldName ) );
|
||||
if ( world )
|
||||
{
|
||||
ret = world->isEnabled();
|
||||
return ret;
|
||||
}
|
||||
|
||||
world = static_cast<Px3World*>( getWorld( smServerWorldName ) );
|
||||
if ( world )
|
||||
{
|
||||
ret = world->isEnabled();
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Px3Plugin::enableSimulation( const String &worldName, bool enable )
|
||||
{
|
||||
Px3World *world = static_cast<Px3World*>( getWorld( worldName ) );
|
||||
if ( world )
|
||||
world->setEnabled( enable );
|
||||
}
|
||||
|
||||
void Px3Plugin::setTimeScale( const F32 timeScale )
|
||||
{
|
||||
// Grab both the client and
|
||||
// server worlds and set their time
|
||||
// scales to the passed value.
|
||||
Px3World *world = static_cast<Px3World*>( getWorld( smClientWorldName ) );
|
||||
if ( world )
|
||||
world->setEditorTimeScale( timeScale );
|
||||
|
||||
world = static_cast<Px3World*>( getWorld( smServerWorldName ) );
|
||||
if ( world )
|
||||
world->setEditorTimeScale( timeScale );
|
||||
}
|
||||
|
||||
const F32 Px3Plugin::getTimeScale() const
|
||||
{
|
||||
// Grab both the client and
|
||||
// server worlds and call
|
||||
// setEnabled( true ) on them.
|
||||
Px3World *world = static_cast<Px3World*>( getWorld( smClientWorldName ) );
|
||||
if ( !world )
|
||||
{
|
||||
world = static_cast<Px3World*>( getWorld( smServerWorldName ) );
|
||||
if ( !world )
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return world->getEditorTimeScale();
|
||||
}
|
||||
|
||||
bool Px3Plugin::createWorld( const String &worldName )
|
||||
{
|
||||
Map<StringNoCase, PhysicsWorld*>::Iterator iter = mPhysicsWorldLookup.find( worldName );
|
||||
PhysicsWorld *world = NULL;
|
||||
|
||||
iter != mPhysicsWorldLookup.end() ? world = (*iter).value : world = NULL;
|
||||
|
||||
if ( world )
|
||||
{
|
||||
Con::errorf( "Px3Plugin::createWorld - %s world already exists!", worldName.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
world = new Px3World();
|
||||
|
||||
if ( worldName.equal( smClientWorldName, String::NoCase ) )
|
||||
world->initWorld( false, ClientProcessList::get() );
|
||||
else
|
||||
world->initWorld( true, ServerProcessList::get() );
|
||||
|
||||
mPhysicsWorldLookup.insert( worldName, world );
|
||||
|
||||
return world != NULL;
|
||||
}
|
||||
|
||||
void Px3Plugin::destroyWorld( const String &worldName )
|
||||
{
|
||||
Map<StringNoCase, PhysicsWorld*>::Iterator iter = mPhysicsWorldLookup.find( worldName );
|
||||
if ( iter == mPhysicsWorldLookup.end() )
|
||||
return;
|
||||
|
||||
PhysicsWorld *world = (*iter).value;
|
||||
world->destroyWorld();
|
||||
delete world;
|
||||
|
||||
mPhysicsWorldLookup.erase( iter );
|
||||
}
|
||||
|
||||
PhysicsWorld* Px3Plugin::getWorld( const String &worldName ) const
|
||||
{
|
||||
if ( mPhysicsWorldLookup.isEmpty() )
|
||||
return NULL;
|
||||
|
||||
Map<StringNoCase, PhysicsWorld*>::ConstIterator iter = mPhysicsWorldLookup.find( worldName );
|
||||
|
||||
return iter != mPhysicsWorldLookup.end() ? (*iter).value : NULL;
|
||||
}
|
||||
|
||||
PhysicsWorld* Px3Plugin::getWorld() const
|
||||
{
|
||||
if ( mPhysicsWorldLookup.size() == 0 )
|
||||
return NULL;
|
||||
|
||||
Map<StringNoCase, PhysicsWorld*>::ConstIterator iter = mPhysicsWorldLookup.begin();
|
||||
return iter->value;
|
||||
}
|
||||
|
||||
U32 Px3Plugin::getWorldCount() const
|
||||
{
|
||||
return mPhysicsWorldLookup.size();
|
||||
}
|
||||
59
Engine/source/T3D/physics/physx3/px3Plugin.h
Normal file
59
Engine/source/T3D/physics/physx3/px3Plugin.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3PLUGIN_H_
|
||||
#define _PX3PLUGIN_H_
|
||||
|
||||
#ifndef _T3D_PHYSICS_PHYSICSPLUGIN_H_
|
||||
#include "T3D/physics/physicsPlugin.h"
|
||||
#endif
|
||||
|
||||
class Px3ClothShape;
|
||||
|
||||
class Px3Plugin : public PhysicsPlugin
|
||||
{
|
||||
public:
|
||||
|
||||
Px3Plugin();
|
||||
~Px3Plugin();
|
||||
|
||||
/// Create function for factory.
|
||||
static PhysicsPlugin* create();
|
||||
|
||||
// PhysicsPlugin
|
||||
virtual void destroyPlugin();
|
||||
virtual void reset();
|
||||
virtual PhysicsCollision* createCollision();
|
||||
virtual PhysicsBody* createBody();
|
||||
virtual PhysicsPlayer* createPlayer();
|
||||
virtual bool isSimulationEnabled() const;
|
||||
virtual void enableSimulation( const String &worldName, bool enable );
|
||||
virtual void setTimeScale( const F32 timeScale );
|
||||
virtual const F32 getTimeScale() const;
|
||||
virtual bool createWorld( const String &worldName );
|
||||
virtual void destroyWorld( const String &worldName );
|
||||
virtual PhysicsWorld* getWorld( const String &worldName ) const;
|
||||
virtual PhysicsWorld* getWorld() const;
|
||||
virtual U32 getWorldCount() const;
|
||||
};
|
||||
|
||||
#endif // _PX3PLUGIN_H_
|
||||
92
Engine/source/T3D/physics/physx3/px3Stream.cpp
Normal file
92
Engine/source/T3D/physics/physx3/px3Stream.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3Stream.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
|
||||
Px3MemOutStream::Px3MemOutStream() : mMemStream(1024)
|
||||
{
|
||||
}
|
||||
|
||||
Px3MemOutStream::~Px3MemOutStream()
|
||||
{
|
||||
}
|
||||
|
||||
physx::PxU32 Px3MemOutStream::write(const void *src, physx::PxU32 count)
|
||||
{
|
||||
physx::PxU32 out=0;
|
||||
if(!mMemStream.write(count,src))
|
||||
return out;
|
||||
|
||||
out = count;
|
||||
return out;
|
||||
}
|
||||
|
||||
Px3MemInStream::Px3MemInStream(physx::PxU8* data, physx::PxU32 length):mMemStream(length,data)
|
||||
{
|
||||
}
|
||||
|
||||
physx::PxU32 Px3MemInStream::read(void* dest, physx::PxU32 count)
|
||||
{
|
||||
physx::PxU32 read =0;
|
||||
if(!mMemStream.read(count,dest))
|
||||
return read;
|
||||
|
||||
read = count;
|
||||
return read;
|
||||
}
|
||||
|
||||
void Px3MemInStream::seek(physx::PxU32 pos)
|
||||
{
|
||||
mMemStream.setPosition(pos);
|
||||
}
|
||||
|
||||
physx::PxU32 Px3MemInStream::getLength() const
|
||||
{
|
||||
return mMemStream.getStreamSize();
|
||||
}
|
||||
|
||||
physx::PxU32 Px3MemInStream::tell() const
|
||||
{
|
||||
return mMemStream.getPosition();
|
||||
}
|
||||
|
||||
Px3ConsoleStream::Px3ConsoleStream()
|
||||
{
|
||||
}
|
||||
|
||||
Px3ConsoleStream::~Px3ConsoleStream()
|
||||
{
|
||||
}
|
||||
|
||||
void Px3ConsoleStream::reportError( physx::PxErrorCode code, const char *message, const char* file, int line )
|
||||
{
|
||||
UTF8 info[1024];
|
||||
dSprintf( info, 1024, "File: %s\nLine: %d\n%s", file, line, message );
|
||||
Platform::AlertOK( "PhysX Error", info );
|
||||
// Con::printf( "PhysX Error:\n %s(%d) : %s\n", file, line, message );
|
||||
}
|
||||
77
Engine/source/T3D/physics/physx3/px3Stream.h
Normal file
77
Engine/source/T3D/physics/physx3/px3Stream.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3STREAM_H_
|
||||
#define _PX3STREAM_H_
|
||||
|
||||
#ifndef _PHYSX3_H_
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#endif
|
||||
#ifndef _MEMSTREAM_H_
|
||||
#include "core/stream/memStream.h"
|
||||
#endif
|
||||
|
||||
|
||||
class Px3MemOutStream : public physx::PxOutputStream
|
||||
{
|
||||
public:
|
||||
|
||||
Px3MemOutStream();
|
||||
virtual ~Px3MemOutStream();
|
||||
|
||||
void resetPosition();
|
||||
|
||||
virtual physx::PxU32 write(const void *src, physx::PxU32 count);
|
||||
physx::PxU32 getSize() const {return mMemStream.getStreamSize();}
|
||||
physx::PxU8* getData() const {return (physx::PxU8*)mMemStream.getBuffer();}
|
||||
|
||||
protected:
|
||||
|
||||
mutable MemStream mMemStream;
|
||||
};
|
||||
|
||||
class Px3MemInStream: public physx::PxInputData
|
||||
{
|
||||
public:
|
||||
Px3MemInStream(physx::PxU8* data, physx::PxU32 length);
|
||||
virtual physx::PxU32 read(void* dest, physx::PxU32 count);
|
||||
physx::PxU32 getLength() const;
|
||||
virtual void seek(physx::PxU32 pos);
|
||||
virtual physx::PxU32 tell() const;
|
||||
protected:
|
||||
mutable MemStream mMemStream;
|
||||
|
||||
};
|
||||
|
||||
class Px3ConsoleStream : public physx::PxDefaultErrorCallback
|
||||
{
|
||||
protected:
|
||||
|
||||
virtual void reportError( physx::PxErrorCode code, const char *message, const char* file, int line );
|
||||
|
||||
public:
|
||||
|
||||
Px3ConsoleStream();
|
||||
virtual ~Px3ConsoleStream();
|
||||
};
|
||||
|
||||
#endif // _PX3STREAM_H_
|
||||
32
Engine/source/T3D/physics/physx3/px3Utils.cpp
Normal file
32
Engine/source/T3D/physics/physx3/px3Utils.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3Utils.h"
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
|
||||
physx::PxShape* px3GetFirstShape(physx::PxRigidActor *actor)
|
||||
{
|
||||
physx::PxShape *shapes[1];
|
||||
actor->getShapes(shapes, 1);
|
||||
return shapes[0];
|
||||
}
|
||||
34
Engine/source/T3D/physics/physx3/px3Utils.h
Normal file
34
Engine/source/T3D/physics/physx3/px3Utils.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3UTILS_H_
|
||||
#define _PX3UTILS_H_
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxRigidActor;
|
||||
class PxShape;
|
||||
}
|
||||
|
||||
extern physx::PxShape* px3GetFirstShape(physx::PxRigidActor *actor);
|
||||
|
||||
#endif // _PX3UTILS_H_
|
||||
565
Engine/source/T3D/physics/physx3/px3World.cpp
Normal file
565
Engine/source/T3D/physics/physx3/px3World.cpp
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/physics/physx3/px3World.h"
|
||||
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#include "T3D/physics/physx3/px3Plugin.h"
|
||||
#include "T3D/physics/physx3/px3Casts.h"
|
||||
#include "T3D/physics/physx3/px3Stream.h"
|
||||
#include "T3D/physics/physicsUserData.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "platform/profiler.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "collision/collision.h"
|
||||
#include "T3D/gameBase/gameProcess.h"
|
||||
#include "gfx/sim/debugDraw.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
|
||||
physx::PxPhysics* gPhysics3SDK = NULL;
|
||||
physx::PxCooking* Px3World::smCooking = NULL;
|
||||
physx::PxFoundation* Px3World::smFoundation = NULL;
|
||||
physx::PxProfileZoneManager* Px3World::smProfileZoneManager = NULL;
|
||||
physx::PxDefaultCpuDispatcher* Px3World::smCpuDispatcher=NULL;
|
||||
Px3ConsoleStream* Px3World::smErrorCallback = NULL;
|
||||
physx::PxVisualDebuggerConnection* Px3World::smPvdConnection=NULL;
|
||||
physx::PxDefaultAllocator Px3World::smMemoryAlloc;
|
||||
//Physics timing
|
||||
F32 Px3World::smPhysicsStepTime = 1.0f/(F32)TickMs;
|
||||
U32 Px3World::smPhysicsMaxIterations = 4;
|
||||
|
||||
Px3World::Px3World(): mScene( NULL ),
|
||||
mProcessList( NULL ),
|
||||
mIsSimulating( false ),
|
||||
mErrorReport( false ),
|
||||
mTickCount( 0 ),
|
||||
mIsEnabled( false ),
|
||||
mEditorTimeScale( 1.0f ),
|
||||
mAccumulator( 0 ),
|
||||
mControllerManager( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
Px3World::~Px3World()
|
||||
{
|
||||
}
|
||||
|
||||
physx::PxCooking *Px3World::getCooking()
|
||||
{
|
||||
return smCooking;
|
||||
}
|
||||
|
||||
void Px3World::setTiming(F32 stepTime,U32 maxIterations)
|
||||
{
|
||||
smPhysicsStepTime = stepTime;
|
||||
smPhysicsMaxIterations = maxIterations;
|
||||
}
|
||||
|
||||
bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *serverWorld)
|
||||
{
|
||||
// If either the client or the server still exist
|
||||
// then we cannot reset the SDK.
|
||||
if ( clientWorld || serverWorld )
|
||||
return false;
|
||||
|
||||
if(smPvdConnection)
|
||||
smPvdConnection->release();
|
||||
|
||||
if(smCooking)
|
||||
smCooking->release();
|
||||
|
||||
if(smCpuDispatcher)
|
||||
smCpuDispatcher->release();
|
||||
|
||||
// Destroy the existing SDK.
|
||||
if ( gPhysics3SDK )
|
||||
{
|
||||
PxCloseExtensions();
|
||||
gPhysics3SDK->release();
|
||||
}
|
||||
|
||||
if(smErrorCallback)
|
||||
{
|
||||
SAFE_DELETE(smErrorCallback);
|
||||
}
|
||||
|
||||
if(smFoundation)
|
||||
{
|
||||
smFoundation->release();
|
||||
SAFE_DELETE(smErrorCallback);
|
||||
}
|
||||
|
||||
// If we're not supposed to restart... return.
|
||||
if ( destroyOnly )
|
||||
return true;
|
||||
|
||||
bool memTrack = false;
|
||||
#ifdef TORQUE_DEBUG
|
||||
memTrack = true;
|
||||
#endif
|
||||
|
||||
smErrorCallback = new Px3ConsoleStream;
|
||||
smFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, smMemoryAlloc, *smErrorCallback);
|
||||
smProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(smFoundation);
|
||||
gPhysics3SDK = PxCreatePhysics(PX_PHYSICS_VERSION, *smFoundation, physx::PxTolerancesScale(),memTrack,smProfileZoneManager);
|
||||
|
||||
if ( !gPhysics3SDK )
|
||||
{
|
||||
Con::errorf( "PhysX3 failed to initialize!" );
|
||||
Platform::messageBox( Con::getVariable( "$appName" ),
|
||||
avar("PhysX3 could not be started!\r\n"),
|
||||
MBOk, MIStop );
|
||||
Platform::forceShutdown( -1 );
|
||||
|
||||
// We shouldn't get here, but this shuts up
|
||||
// source diagnostic tools.
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!PxInitExtensions(*gPhysics3SDK))
|
||||
{
|
||||
Con::errorf( "PhysX3 failed to initialize extensions!" );
|
||||
Platform::messageBox( Con::getVariable( "$appName" ),
|
||||
avar("PhysX3 could not be started!\r\n"),
|
||||
MBOk, MIStop );
|
||||
Platform::forceShutdown( -1 );
|
||||
return false;
|
||||
}
|
||||
|
||||
smCooking = PxCreateCooking(PX_PHYSICS_VERSION, *smFoundation, physx::PxCookingParams(physx::PxTolerancesScale()));
|
||||
if(!smCooking)
|
||||
{
|
||||
Con::errorf( "PhysX3 failed to initialize cooking!" );
|
||||
Platform::messageBox( Con::getVariable( "$appName" ),
|
||||
avar("PhysX3 could not be started!\r\n"),
|
||||
MBOk, MIStop );
|
||||
Platform::forceShutdown( -1 );
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
physx::PxVisualDebuggerConnectionFlags connectionFlags(physx::PxVisualDebuggerExt::getAllConnectionFlags());
|
||||
smPvdConnection = physx::PxVisualDebuggerExt::createConnection(gPhysics3SDK->getPvdConnectionManager(),
|
||||
"localhost", 5425, 100, connectionFlags);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Px3World::destroyWorld()
|
||||
{
|
||||
getPhysicsResults();
|
||||
|
||||
// Release the tick processing signals.
|
||||
if ( mProcessList )
|
||||
{
|
||||
mProcessList->preTickSignal().remove( this, &Px3World::getPhysicsResults );
|
||||
mProcessList->postTickSignal().remove( this, &Px3World::tickPhysics );
|
||||
mProcessList = NULL;
|
||||
}
|
||||
|
||||
if(mControllerManager)
|
||||
{
|
||||
mControllerManager->release();
|
||||
mControllerManager = NULL;
|
||||
}
|
||||
|
||||
// Destroy the scene.
|
||||
if ( mScene )
|
||||
{
|
||||
// Release the scene.
|
||||
mScene->release();
|
||||
mScene = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Px3World::initWorld( bool isServer, ProcessList *processList )
|
||||
{
|
||||
if ( !gPhysics3SDK )
|
||||
{
|
||||
Con::errorf( "Physx3World::init - PhysXSDK not initialized!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
mIsServer = isServer;
|
||||
|
||||
physx::PxSceneDesc sceneDesc(gPhysics3SDK->getTolerancesScale());
|
||||
|
||||
sceneDesc.gravity = px3Cast<physx::PxVec3>(mGravity);
|
||||
sceneDesc.userData = this;
|
||||
if(!sceneDesc.cpuDispatcher)
|
||||
{
|
||||
smCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(PHYSICSMGR->getThreadCount());
|
||||
sceneDesc.cpuDispatcher = smCpuDispatcher;
|
||||
Con::printf("PhysX3 using Cpu: %d workers", smCpuDispatcher->getWorkerCount());
|
||||
}
|
||||
|
||||
|
||||
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_CCD;
|
||||
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_ACTIVETRANSFORMS;
|
||||
sceneDesc.filterShader = physx::PxDefaultSimulationFilterShader;
|
||||
|
||||
mScene = gPhysics3SDK->createScene(sceneDesc);
|
||||
|
||||
physx::PxDominanceGroupPair debrisDominance( 0.0f, 1.0f );
|
||||
mScene->setDominanceGroupPair(0,31,debrisDominance);
|
||||
|
||||
mControllerManager = PxCreateControllerManager(*mScene);
|
||||
|
||||
AssertFatal( processList, "Px3World::init() - We need a process list to create the world!" );
|
||||
mProcessList = processList;
|
||||
mProcessList->preTickSignal().notify( this, &Px3World::getPhysicsResults );
|
||||
mProcessList->postTickSignal().notify( this, &Px3World::tickPhysics, 1000.0f );
|
||||
|
||||
return true;
|
||||
}
|
||||
// Most of this borrowed from bullet physics library, see btDiscreteDynamicsWorld.cpp
|
||||
bool Px3World::_simulate(const F32 dt)
|
||||
{
|
||||
int numSimulationSubSteps = 0;
|
||||
//fixed timestep with interpolation
|
||||
mAccumulator += dt;
|
||||
if (mAccumulator >= smPhysicsStepTime)
|
||||
{
|
||||
numSimulationSubSteps = int(mAccumulator / smPhysicsStepTime);
|
||||
mAccumulator -= numSimulationSubSteps * smPhysicsStepTime;
|
||||
}
|
||||
if (numSimulationSubSteps)
|
||||
{
|
||||
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
|
||||
int clampedSimulationSteps = (numSimulationSubSteps > smPhysicsMaxIterations)? smPhysicsMaxIterations : numSimulationSubSteps;
|
||||
|
||||
for (int i=0;i<clampedSimulationSteps;i++)
|
||||
{
|
||||
mScene->fetchResults(true);
|
||||
mScene->simulate(smPhysicsStepTime);
|
||||
}
|
||||
}
|
||||
|
||||
mIsSimulating = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Px3World::tickPhysics( U32 elapsedMs )
|
||||
{
|
||||
if ( !mScene || !mIsEnabled )
|
||||
return;
|
||||
|
||||
// Did we forget to call getPhysicsResults somewhere?
|
||||
AssertFatal( !mIsSimulating, "PhysX3World::tickPhysics() - Already simulating!" );
|
||||
|
||||
// The elapsed time should be non-zero and
|
||||
// a multiple of TickMs!
|
||||
AssertFatal( elapsedMs != 0 &&
|
||||
( elapsedMs % TickMs ) == 0 , "PhysX3World::tickPhysics() - Got bad elapsed time!" );
|
||||
|
||||
PROFILE_SCOPE(Px3World_TickPhysics);
|
||||
|
||||
// Convert it to seconds.
|
||||
const F32 elapsedSec = (F32)elapsedMs * 0.001f;
|
||||
mIsSimulating = _simulate(elapsedSec * mEditorTimeScale);
|
||||
|
||||
//Con::printf( "%s PhysX3World::tickPhysics!", mIsServer ? "Client" : "Server" );
|
||||
}
|
||||
|
||||
void Px3World::getPhysicsResults()
|
||||
{
|
||||
if ( !mScene || !mIsSimulating )
|
||||
return;
|
||||
|
||||
PROFILE_SCOPE(Px3World_GetPhysicsResults);
|
||||
|
||||
// Get results from scene.
|
||||
mScene->fetchResults(true);
|
||||
mIsSimulating = false;
|
||||
mTickCount++;
|
||||
|
||||
// Con::printf( "%s PhysXWorld::getPhysicsResults!", this == smClientWorld ? "Client" : "Server" );
|
||||
}
|
||||
|
||||
void Px3World::releaseWriteLocks()
|
||||
{
|
||||
Px3World *world = dynamic_cast<Px3World*>( PHYSICSMGR->getWorld( "server" ) );
|
||||
|
||||
if ( world )
|
||||
world->releaseWriteLock();
|
||||
|
||||
world = dynamic_cast<Px3World*>( PHYSICSMGR->getWorld( "client" ) );
|
||||
|
||||
if ( world )
|
||||
world->releaseWriteLock();
|
||||
}
|
||||
|
||||
void Px3World::releaseWriteLock()
|
||||
{
|
||||
if ( !mScene || !mIsSimulating )
|
||||
return;
|
||||
|
||||
PROFILE_SCOPE(PxWorld_ReleaseWriteLock);
|
||||
|
||||
// We use checkResults here to release the write lock
|
||||
// but we do not change the simulation flag or increment
|
||||
// the tick count... we may have gotten results, but the
|
||||
// simulation hasn't really ticked!
|
||||
mScene->checkResults( true );
|
||||
//AssertFatal( mScene->isWritable(), "PhysX3World::releaseWriteLock() - We should have been writable now!" );
|
||||
}
|
||||
|
||||
bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse )
|
||||
{
|
||||
|
||||
physx::PxVec3 orig = px3Cast<physx::PxVec3>( startPnt );
|
||||
physx::PxVec3 dir = px3Cast<physx::PxVec3>( endPnt - startPnt );
|
||||
physx::PxF32 maxDist = dir.magnitude();
|
||||
dir.normalize();
|
||||
|
||||
U32 groups = 0xffffffff;
|
||||
groups &= ~( PX3_TRIGGER ); // No trigger shapes!
|
||||
|
||||
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::eIMPACT | physx::PxHitFlag::eNORMAL);
|
||||
physx::PxQueryFilterData filterData(physx::PxQueryFlag::eSTATIC|physx::PxQueryFlag::eDYNAMIC);
|
||||
filterData.data.word0 = groups;
|
||||
physx::PxRaycastBuffer buf;
|
||||
|
||||
if(!mScene->raycast(orig,dir,maxDist,buf,outFlags,filterData))
|
||||
return false;
|
||||
if(!buf.hasBlock)
|
||||
return false;
|
||||
|
||||
const physx::PxRaycastHit hit = buf.block;
|
||||
physx::PxRigidActor *actor = hit.actor;
|
||||
PhysicsUserData *userData = PhysicsUserData::cast( actor->userData );
|
||||
|
||||
if ( ri )
|
||||
{
|
||||
ri->object = ( userData != NULL ) ? userData->getObject() : NULL;
|
||||
|
||||
if ( ri->object == NULL )
|
||||
|
||||
ri->distance = hit.distance;
|
||||
ri->normal = px3Cast<Point3F>( hit.normal );
|
||||
ri->point = px3Cast<Point3F>( hit.position );
|
||||
ri->t = maxDist / hit.distance;
|
||||
}
|
||||
|
||||
if ( impulse.isZero() ||
|
||||
!actor->isRigidDynamic() ||
|
||||
actor->is<physx::PxRigidDynamic>()->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC )
|
||||
return true;
|
||||
|
||||
physx::PxRigidBody *body = actor->is<physx::PxRigidBody>();
|
||||
physx::PxVec3 force = px3Cast<physx::PxVec3>( impulse );
|
||||
physx::PxRigidBodyExt::addForceAtPos(*body,force,hit.position,physx::PxForceMode::eIMPULSE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PhysicsBody* Px3World::castRay( const Point3F &start, const Point3F &end, U32 bodyTypes )
|
||||
{
|
||||
physx::PxVec3 orig = px3Cast<physx::PxVec3>( start );
|
||||
physx::PxVec3 dir = px3Cast<physx::PxVec3>( end - start );
|
||||
physx::PxF32 maxDist = dir.magnitude();
|
||||
dir.normalize();
|
||||
|
||||
U32 groups = 0xFFFFFFFF;
|
||||
if ( !( bodyTypes & BT_Player ) )
|
||||
groups &= ~( PX3_PLAYER );
|
||||
|
||||
// TODO: For now always skip triggers and debris,
|
||||
// but we should consider how game specifc this API
|
||||
// should be in the future.
|
||||
groups &= ~( PX3_TRIGGER ); // triggers
|
||||
groups &= ~( PX3_DEBRIS ); // debris
|
||||
|
||||
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::eIMPACT | physx::PxHitFlag::eNORMAL);
|
||||
physx::PxQueryFilterData filterData;
|
||||
if(bodyTypes & BT_Static)
|
||||
filterData.flags |= physx::PxQueryFlag::eSTATIC;
|
||||
if(bodyTypes & BT_Dynamic)
|
||||
filterData.flags |= physx::PxQueryFlag::eDYNAMIC;
|
||||
|
||||
filterData.data.word0 = groups;
|
||||
physx::PxRaycastBuffer buf;
|
||||
|
||||
if( !mScene->raycast(orig,dir,maxDist,buf,outFlags,filterData) )
|
||||
return NULL;
|
||||
if(!buf.hasBlock)
|
||||
return NULL;
|
||||
|
||||
physx::PxRigidActor *actor = buf.block.actor;
|
||||
PhysicsUserData *userData = PhysicsUserData::cast( actor->userData );
|
||||
if( !userData )
|
||||
return NULL;
|
||||
|
||||
return userData->getBody();
|
||||
}
|
||||
|
||||
void Px3World::explosion( const Point3F &pos, F32 radius, F32 forceMagnitude )
|
||||
{
|
||||
physx::PxVec3 nxPos = px3Cast<physx::PxVec3>( pos );
|
||||
const physx::PxU32 bufferSize = 10;
|
||||
physx::PxSphereGeometry worldSphere(radius);
|
||||
physx::PxTransform pose(nxPos);
|
||||
physx::PxOverlapBufferN<bufferSize> buffer;
|
||||
|
||||
if(!mScene->overlap(worldSphere,pose,buffer))
|
||||
return;
|
||||
|
||||
for ( physx::PxU32 i = 0; i < buffer.nbTouches; i++ )
|
||||
{
|
||||
physx::PxRigidActor *actor = buffer.touches[i].actor;
|
||||
|
||||
bool dynamic = actor->isRigidDynamic();
|
||||
|
||||
if ( !dynamic )
|
||||
continue;
|
||||
|
||||
bool kinematic = actor->is<physx::PxRigidDynamic>()->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC;
|
||||
|
||||
if ( kinematic )
|
||||
continue;
|
||||
|
||||
physx::PxVec3 force = actor->getGlobalPose().p - nxPos;
|
||||
force.normalize();
|
||||
force *= forceMagnitude;
|
||||
|
||||
physx::PxRigidBody *body = actor->is<physx::PxRigidBody>();
|
||||
physx::PxRigidBodyExt::addForceAtPos(*body,force,nxPos,physx::PxForceMode::eIMPULSE);
|
||||
}
|
||||
}
|
||||
|
||||
void Px3World::setEnabled( bool enabled )
|
||||
{
|
||||
mIsEnabled = enabled;
|
||||
|
||||
if ( !mIsEnabled )
|
||||
getPhysicsResults();
|
||||
}
|
||||
|
||||
physx::PxController* Px3World::createController( physx::PxControllerDesc &desc )
|
||||
{
|
||||
if ( !mScene )
|
||||
return NULL;
|
||||
|
||||
// We need the writelock!
|
||||
releaseWriteLock();
|
||||
physx::PxController* pController = mControllerManager->createController(desc);
|
||||
AssertFatal( pController, "Px3World::createController - Got a null!" );
|
||||
return pController;
|
||||
}
|
||||
|
||||
static ColorI getDebugColor( physx::PxU32 packed )
|
||||
{
|
||||
ColorI col;
|
||||
col.blue = (packed)&0xff;
|
||||
col.green = (packed>>8)&0xff;
|
||||
col.red = (packed>>16)&0xff;
|
||||
col.alpha = 255;
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
void Px3World::onDebugDraw( const SceneRenderState *state )
|
||||
{
|
||||
if ( !mScene )
|
||||
return;
|
||||
|
||||
mScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE,1.0f);
|
||||
mScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_AXES,1.0f);
|
||||
mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_SHAPES,1.0f);
|
||||
|
||||
const physx::PxRenderBuffer *renderBuffer = &mScene->getRenderBuffer();
|
||||
|
||||
if(!renderBuffer)
|
||||
return;
|
||||
|
||||
// Render points
|
||||
{
|
||||
physx::PxU32 numPoints = renderBuffer->getNbPoints();
|
||||
const physx::PxDebugPoint *points = renderBuffer->getPoints();
|
||||
|
||||
PrimBuild::begin( GFXPointList, numPoints );
|
||||
|
||||
while ( numPoints-- )
|
||||
{
|
||||
PrimBuild::color( getDebugColor(points->color) );
|
||||
PrimBuild::vertex3fv(px3Cast<Point3F>(points->pos));
|
||||
points++;
|
||||
}
|
||||
|
||||
PrimBuild::end();
|
||||
}
|
||||
|
||||
// Render lines
|
||||
{
|
||||
physx::PxU32 numLines = renderBuffer->getNbLines();
|
||||
const physx::PxDebugLine *lines = renderBuffer->getLines();
|
||||
|
||||
PrimBuild::begin( GFXLineList, numLines * 2 );
|
||||
|
||||
while ( numLines-- )
|
||||
{
|
||||
PrimBuild::color( getDebugColor( lines->color0 ) );
|
||||
PrimBuild::vertex3fv( px3Cast<Point3F>(lines->pos0));
|
||||
PrimBuild::color( getDebugColor( lines->color1 ) );
|
||||
PrimBuild::vertex3fv( px3Cast<Point3F>(lines->pos1));
|
||||
lines++;
|
||||
}
|
||||
|
||||
PrimBuild::end();
|
||||
}
|
||||
|
||||
// Render triangles
|
||||
{
|
||||
physx::PxU32 numTris = renderBuffer->getNbTriangles();
|
||||
const physx::PxDebugTriangle *triangles = renderBuffer->getTriangles();
|
||||
|
||||
PrimBuild::begin( GFXTriangleList, numTris * 3 );
|
||||
|
||||
while ( numTris-- )
|
||||
{
|
||||
PrimBuild::color( getDebugColor( triangles->color0 ) );
|
||||
PrimBuild::vertex3fv( px3Cast<Point3F>(triangles->pos0) );
|
||||
PrimBuild::color( getDebugColor( triangles->color1 ) );
|
||||
PrimBuild::vertex3fv( px3Cast<Point3F>(triangles->pos1));
|
||||
PrimBuild::color( getDebugColor( triangles->color2 ) );
|
||||
PrimBuild::vertex3fv( px3Cast<Point3F>(triangles->pos2) );
|
||||
triangles++;
|
||||
}
|
||||
|
||||
PrimBuild::end();
|
||||
}
|
||||
|
||||
}
|
||||
//set simulation timing via script
|
||||
DefineEngineFunction( physx3SetSimulationTiming, void, ( F32 stepTime, U32 maxSteps ),, "Set simulation timing of the PhysX 3 plugin" )
|
||||
{
|
||||
Px3World::setTiming(stepTime,maxSteps);
|
||||
}
|
||||
106
Engine/source/T3D/physics/physx3/px3World.h
Normal file
106
Engine/source/T3D/physics/physx3/px3World.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PX3WORLD_H_
|
||||
#define _PX3WORLD_H_
|
||||
|
||||
#ifndef _T3D_PHYSICS_PHYSICSWORLD_H_
|
||||
#include "T3D/physics/physicsWorld.h"
|
||||
#endif
|
||||
#ifndef _MMATH_H_
|
||||
#include "math/mMath.h"
|
||||
#endif
|
||||
#ifndef _PHYSX3_H_
|
||||
#include "T3D/physics/physx3/px3.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
class Px3ConsoleStream;
|
||||
class Px3ContactReporter;
|
||||
class FixedStepper;
|
||||
|
||||
enum Px3CollisionGroup
|
||||
{
|
||||
PX3_DEFAULT = BIT(0),
|
||||
PX3_PLAYER = BIT(1),
|
||||
PX3_DEBRIS = BIT(2),
|
||||
PX3_TRIGGER = BIT(3),
|
||||
};
|
||||
|
||||
class Px3World : public PhysicsWorld
|
||||
{
|
||||
protected:
|
||||
|
||||
physx::PxScene* mScene;
|
||||
bool mIsEnabled;
|
||||
bool mIsSimulating;
|
||||
bool mIsServer;
|
||||
U32 mTickCount;
|
||||
ProcessList *mProcessList;
|
||||
F32 mEditorTimeScale;
|
||||
bool mErrorReport;
|
||||
physx::PxControllerManager* mControllerManager;
|
||||
static Px3ConsoleStream *smErrorCallback;
|
||||
static physx::PxDefaultAllocator smMemoryAlloc;
|
||||
static physx::PxFoundation* smFoundation;
|
||||
static physx::PxCooking *smCooking;
|
||||
static physx::PxProfileZoneManager* smProfileZoneManager;
|
||||
static physx::PxDefaultCpuDispatcher* smCpuDispatcher;
|
||||
static physx::PxVisualDebuggerConnection* smPvdConnection;
|
||||
static F32 smPhysicsStepTime;
|
||||
static U32 smPhysicsMaxIterations;
|
||||
F32 mAccumulator;
|
||||
bool _simulate(const F32 dt);
|
||||
|
||||
public:
|
||||
|
||||
Px3World();
|
||||
virtual ~Px3World();
|
||||
|
||||
virtual bool initWorld( bool isServer, ProcessList *processList );
|
||||
virtual void destroyWorld();
|
||||
virtual void onDebugDraw( const SceneRenderState *state );
|
||||
virtual void reset() {}
|
||||
virtual bool castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse );
|
||||
virtual PhysicsBody* castRay( const Point3F &start, const Point3F &end, U32 bodyTypes = BT_All );
|
||||
virtual void explosion( const Point3F &pos, F32 radius, F32 forceMagnitude );
|
||||
virtual bool isEnabled() const { return mIsEnabled; }
|
||||
physx::PxScene* getScene(){ return mScene;}
|
||||
void setEnabled( bool enabled );
|
||||
U32 getTick() { return mTickCount; }
|
||||
void tickPhysics( U32 elapsedMs );
|
||||
void getPhysicsResults();
|
||||
void setEditorTimeScale( F32 timeScale ) { mEditorTimeScale = timeScale; }
|
||||
const F32 getEditorTimeScale() const { return mEditorTimeScale; }
|
||||
void releaseWriteLock();
|
||||
bool isServer(){return mIsServer;}
|
||||
physx::PxController* createController( physx::PxControllerDesc &desc );
|
||||
//static
|
||||
static bool restartSDK( bool destroyOnly = false, Px3World *clientWorld = NULL, Px3World *serverWorld = NULL );
|
||||
static void releaseWriteLocks();
|
||||
static physx::PxCooking *getCooking();
|
||||
static void setTiming(F32 stepTime,U32 maxIterations);
|
||||
};
|
||||
|
||||
#endif // _PX3WORLD_H_
|
||||
|
|
@ -892,7 +892,7 @@ void AITurretShape::_trackTarget(F32 dt)
|
|||
//if (pitch > M_PI_F)
|
||||
// pitch = -(pitch - M_2PI_F);
|
||||
|
||||
Point3F rot(pitch, 0.0f, -yaw);
|
||||
Point3F rot(-pitch, 0.0f, yaw);
|
||||
|
||||
// If we have a rotation rate make sure we follow it
|
||||
if (mHeadingRate > 0)
|
||||
|
|
|
|||
|
|
@ -623,6 +623,11 @@ bool StandardMainLoop::doMainLoop()
|
|||
return keepRunning;
|
||||
}
|
||||
|
||||
S32 StandardMainLoop::getReturnStatus()
|
||||
{
|
||||
return Process::getReturnStatus();
|
||||
}
|
||||
|
||||
void StandardMainLoop::setRestart(bool restart )
|
||||
{
|
||||
gRequiresRestart = restart;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ public:
|
|||
/// Shut down the core libraries and call registered shutdown fucntions.
|
||||
static void shutdown();
|
||||
|
||||
/// Gets the return status code of the current process.
|
||||
static S32 getReturnStatus();
|
||||
|
||||
static void setRestart( bool restart );
|
||||
static bool requiresRestart();
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,19 @@ void HTTPObject::onConnected()
|
|||
char *pt = dStrchr(mHostName, ':');
|
||||
if(pt)
|
||||
*pt = 0;
|
||||
dSprintf(buffer, sizeof(buffer), "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", expPath, mHostName);
|
||||
|
||||
//If we want to do a get request
|
||||
if(mPost == NULL)
|
||||
{
|
||||
dSprintf(buffer, sizeof(buffer), "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", expPath, mHostName);
|
||||
}
|
||||
//Else we want to do a post request
|
||||
else
|
||||
{
|
||||
dSprintf(buffer, sizeof(buffer), "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\n%s\r\n\r\n",
|
||||
expPath, mHostName, dStrlen(mPost), mPost);
|
||||
}
|
||||
|
||||
if(pt)
|
||||
*pt = ':';
|
||||
|
||||
|
|
@ -431,8 +443,6 @@ DefineEngineMethod( HTTPObject, post, void, ( const char* Address, const char* r
|
|||
"@param requirstURI Specific location on the server to access (IE: \"index.php\".)\n"
|
||||
"@param query Actual data to transmit to the server. Can be anything required providing it sticks with limitations of the HTTP protocol. \n"
|
||||
"@param post Submission data to be processed.\n"
|
||||
|
||||
"@note The post() method is currently non-functional.\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"// Create an HTTP object for communications\n"
|
||||
|
|
|
|||
|
|
@ -251,7 +251,8 @@ ConsoleFunction( commandToServer, void, 2, RemoteCommandEvent::MaxRemoteCommandA
|
|||
NetConnection *conn = NetConnection::getConnectionToServer();
|
||||
if(!conn)
|
||||
return;
|
||||
RemoteCommandEvent::sendRemoteCommand(conn, argc - 1, argv + 1);
|
||||
StringStackWrapper args(argc - 1, argv + 1);
|
||||
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
||||
}
|
||||
|
||||
ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection client, string func, ...)"
|
||||
|
|
@ -288,7 +289,8 @@ ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandA
|
|||
NetConnection *conn;
|
||||
if(!Sim::findObject(argv[1], conn))
|
||||
return;
|
||||
RemoteCommandEvent::sendRemoteCommand(conn, argc - 2, argv + 2);
|
||||
StringStackWrapper args(argc - 2, argv + 2);
|
||||
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -304,9 +306,10 @@ DefineEngineFunction(removeTaggedString, void, (S32 tag), (-1),
|
|||
"@see addTaggedString()\n"
|
||||
"@see getTaggedString()\n"
|
||||
"@ingroup Networking\n")
|
||||
{
|
||||
RemoteCommandEvent::removeTaggedString(tag);
|
||||
}
|
||||
{
|
||||
RemoteCommandEvent::removeTaggedString(tag);
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction(addTaggedString, const char* , (const char* str), (""),
|
||||
"@brief Use the addTaggedString function to tag a new string and add it to the NetStringTable\n\n"
|
||||
|
|
@ -320,10 +323,9 @@ DefineEngineFunction(addTaggedString, const char* , (const char* str), (""),
|
|||
"@see removeTaggedString()\n"
|
||||
"@see getTaggedString()\n"
|
||||
"@ingroup Networking\n")
|
||||
{
|
||||
return RemoteCommandEvent::addTaggedString(str);
|
||||
}
|
||||
|
||||
{
|
||||
return RemoteCommandEvent::addTaggedString(str);
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction(getTaggedString, const char* , (const char *tag), (""),
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ TCPObject::~TCPObject()
|
|||
}
|
||||
}
|
||||
|
||||
bool TCPObject::processArguments(S32 argc, const char **argv)
|
||||
bool TCPObject::processArguments(S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
if(argc == 0)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
void disconnect();
|
||||
State getState() { return mState; }
|
||||
|
||||
bool processArguments(S32 argc, const char **argv);
|
||||
bool processArguments(S32 argc, ConsoleValueRef *argv);
|
||||
void send(const U8 *buffer, U32 bufferLen);
|
||||
void addToTable(NetSocket newTag);
|
||||
void removeFromTable();
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ extern "C" {
|
|||
if (!entry)
|
||||
return "";
|
||||
|
||||
const char* argv[] = {"consoleExportXML", 0};
|
||||
ConsoleValueRef argv[] = {"consoleExportXML"};
|
||||
|
||||
return entry->cb.mStringCallbackFunc(NULL, 1, argv);
|
||||
}
|
||||
|
|
@ -215,7 +215,8 @@ extern "C" {
|
|||
return "";
|
||||
}
|
||||
|
||||
return entry->cb.mStringCallbackFunc(o, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mStringCallbackFunc(o, args.count(), args);
|
||||
}
|
||||
|
||||
bool script_call_namespace_entry_bool(Namespace::Entry* entry, S32 argc, const char** argv)
|
||||
|
|
@ -233,7 +234,8 @@ extern "C" {
|
|||
return false;
|
||||
}
|
||||
|
||||
return entry->cb.mBoolCallbackFunc(o, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mBoolCallbackFunc(o, args.count(), args);
|
||||
}
|
||||
|
||||
S32 script_call_namespace_entry_int(Namespace::Entry* entry, S32 argc, const char** argv)
|
||||
|
|
@ -251,7 +253,8 @@ extern "C" {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return entry->cb.mIntCallbackFunc(o, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mIntCallbackFunc(o, args.count(), args);
|
||||
}
|
||||
|
||||
F32 script_call_namespace_entry_float(Namespace::Entry* entry, S32 argc, const char** argv)
|
||||
|
|
@ -269,7 +272,8 @@ extern "C" {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
return entry->cb.mFloatCallbackFunc(o, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mFloatCallbackFunc(o, args.count(), args);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -288,7 +292,8 @@ extern "C" {
|
|||
return;
|
||||
}
|
||||
|
||||
entry->cb.mVoidCallbackFunc(o, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
entry->cb.mVoidCallbackFunc(o, args.count(), args);
|
||||
}
|
||||
|
||||
S32 script_simobject_get_id(SimObject* so)
|
||||
|
|
|
|||
|
|
@ -132,6 +132,11 @@ extern "C" {
|
|||
|
||||
}
|
||||
|
||||
S32 torque_getreturnstatus()
|
||||
{
|
||||
return StandardMainLoop::getReturnStatus();
|
||||
}
|
||||
|
||||
// signal an engine shutdown (as with the quit(); console command)
|
||||
void torque_enginesignalshutdown()
|
||||
{
|
||||
|
|
@ -262,7 +267,8 @@ extern "C" {
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
entry->cb.mVoidCallbackFunc(NULL, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
entry->cb.mVoidCallbackFunc(NULL, args.count(), args);
|
||||
}
|
||||
|
||||
F32 torque_callfloatfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
|
||||
|
|
@ -273,7 +279,8 @@ extern "C" {
|
|||
if (!entry)
|
||||
return 0.0f;
|
||||
|
||||
return entry->cb.mFloatCallbackFunc(NULL, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mFloatCallbackFunc(NULL, args.count(), args);
|
||||
}
|
||||
|
||||
S32 torque_callintfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
|
||||
|
|
@ -284,7 +291,8 @@ extern "C" {
|
|||
if (!entry)
|
||||
return 0;
|
||||
|
||||
return entry->cb.mIntCallbackFunc(NULL, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mIntCallbackFunc(NULL, args.count(), args);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -295,7 +303,8 @@ extern "C" {
|
|||
if (!entry)
|
||||
return "";
|
||||
|
||||
return entry->cb.mStringCallbackFunc(NULL, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mStringCallbackFunc(NULL, args.count(), args);
|
||||
}
|
||||
|
||||
bool torque_callboolfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv)
|
||||
|
|
@ -305,7 +314,8 @@ extern "C" {
|
|||
if (!entry)
|
||||
return false;
|
||||
|
||||
return entry->cb.mBoolCallbackFunc(NULL, argc, argv);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return entry->cb.mBoolCallbackFunc(NULL, args.count(), args);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -319,7 +329,8 @@ extern "C" {
|
|||
if(!entry->mFunctionOffset)
|
||||
return "";
|
||||
|
||||
const char* ret = entry->mCode->exec(entry->mFunctionOffset, StringTable->insert(name), entry->mNamespace, argc, argv, false, entry->mPackage);
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
const char* ret = entry->mCode->exec(entry->mFunctionOffset, StringTable->insert(name), entry->mNamespace, args.count(), args, false, entry->mPackage);
|
||||
|
||||
if (!ret || !dStrlen(ret))
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -181,25 +181,19 @@ void DepthSortList::set(const MatrixF & mat, Point3F & extents)
|
|||
mPlaneList.clear();
|
||||
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set(-1.0f, 0.0f, 0.0f);
|
||||
mPlaneList.last().d = -mExtent.x;
|
||||
mPlaneList.last().set(-1.0f, 0.0f, 0.0f, -mExtent.x);
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set( 1.0f, 0.0f, 0.0f);
|
||||
mPlaneList.last().d = -mExtent.x;
|
||||
mPlaneList.last().set( 1.0f, 0.0f, 0.0f, -mExtent.x);
|
||||
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set( 0.0f,-1.0f, 0.0f);
|
||||
mPlaneList.last().d = 0;
|
||||
mPlaneList.last().set( 0.0f,-1.0f, 0.0f, 0);
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set( 0.0f, 1.0f, 0.0f);
|
||||
mPlaneList.last().d = -2.0f * mExtent.y;
|
||||
mPlaneList.last().set( 0.0f, 1.0f, 0.0f, -2.0f * mExtent.y);
|
||||
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set( 0.0f, 0.0f,-1.0f);
|
||||
mPlaneList.last().d = -mExtent.z;
|
||||
mPlaneList.last().set( 0.0f, 0.0f,-1.0f, -mExtent.z);
|
||||
mPlaneList.increment();
|
||||
mPlaneList.last().set( 0.0f, 0.0f, 1.0f);
|
||||
mPlaneList.last().d = -mExtent.z;
|
||||
mPlaneList.last().set( 0.0f, 0.0f, 1.0f, -mExtent.z);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "component/dynamicConsoleMethodComponent.h"
|
||||
#include "console/stringStack.h"
|
||||
|
||||
extern StringStack STR;
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(DynamicConsoleMethodComponent);
|
||||
|
||||
|
|
@ -90,7 +94,9 @@ const char *DynamicConsoleMethodComponent::callMethod( S32 argc, const char* met
|
|||
argv[1] = methodName;
|
||||
argv[2] = methodName;
|
||||
|
||||
return callMethodArgList( argc , argv );
|
||||
StringStackConsoleWrapper argsw(argc, argv);
|
||||
|
||||
return callMethodArgList( argsw.count() , argsw );
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
|
|
@ -117,7 +123,7 @@ void DynamicConsoleMethodComponent::injectMethodCall( const char* method )
|
|||
}
|
||||
#endif
|
||||
|
||||
const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, const char *argv[], bool callThis /* = true */ )
|
||||
const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis /* = true */ )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
injectMethodCall( argv[0] );
|
||||
|
|
@ -128,7 +134,7 @@ const char* DynamicConsoleMethodComponent::callMethodArgList( U32 argc, const ch
|
|||
|
||||
// Call all components that implement methodName giving them a chance to operate
|
||||
// Components are called in reverse order of addition
|
||||
const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, const char *argv[], bool callThis /* = true */ )
|
||||
const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, ConsoleValueRef argv[], bool callThis /* = true */ )
|
||||
{
|
||||
// Set Owner
|
||||
SimObject *pThis = dynamic_cast<SimObject *>( this );
|
||||
|
|
@ -150,23 +156,42 @@ const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, const char *ar
|
|||
DynamicConsoleMethodComponent *pThisComponent = dynamic_cast<DynamicConsoleMethodComponent*>( pComponent );
|
||||
AssertFatal( pThisComponent, "DynamicConsoleMethodComponent::callMethod - Non DynamicConsoleMethodComponent component attempting to callback!");
|
||||
|
||||
// Prevent stack corruption
|
||||
STR.pushFrame();
|
||||
CSTK.pushFrame();
|
||||
// --
|
||||
|
||||
// Only call on first depth components
|
||||
// Should isMethod check these calls? [11/22/2006 justind]
|
||||
if(pComponent->isEnabled())
|
||||
Con::execute( pThisComponent, argc, argv );
|
||||
|
||||
// Prevent stack corruption
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
// --
|
||||
|
||||
// Bail if this was the first element
|
||||
//if( nItr == componentList.begin() )
|
||||
// break;
|
||||
}
|
||||
unlockComponentList();
|
||||
}
|
||||
|
||||
// Prevent stack corruption
|
||||
STR.pushFrame();
|
||||
CSTK.pushFrame();
|
||||
// --
|
||||
|
||||
// Set Owner Field
|
||||
const char* result = "";
|
||||
if(callThis)
|
||||
result = Con::execute( pThis, argc, argv, true ); // true - exec method onThisOnly, not on DCMCs
|
||||
|
||||
// Prevent stack corruption
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
// --
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ protected:
|
|||
/// Internal callMethod : Actually does component notification and script method execution
|
||||
/// @attention This method does some magic to the argc argv to make Con::execute act properly
|
||||
/// as such it's internal and should not be exposed or used except by this class
|
||||
virtual const char* _callMethod( U32 argc, const char *argv[], bool callThis = true );
|
||||
virtual const char* _callMethod( U32 argc, ConsoleValueRef argv[], bool callThis = true );
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
#endif
|
||||
|
||||
/// Call Method
|
||||
virtual const char* callMethodArgList( U32 argc, const char *argv[], bool callThis = true );
|
||||
virtual const char* callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis = true );
|
||||
|
||||
/// Call Method format string
|
||||
const char* callMethod( S32 argc, const char* methodName, ... );
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ void SimComponent::onRemove()
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SimComponent::processArguments(S32 argc, const char **argv)
|
||||
bool SimComponent::processArguments(S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
for(S32 i = 0; i < argc; i++)
|
||||
{
|
||||
|
|
@ -179,7 +179,7 @@ bool SimComponent::processArguments(S32 argc, const char **argv)
|
|||
if(obj)
|
||||
addComponent(obj);
|
||||
else
|
||||
Con::printf("SimComponent::processArguments - Invalid Component Object \"%s\"", argv[i]);
|
||||
Con::printf("SimComponent::processArguments - Invalid Component Object \"%s\"", (const char*)argv[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -383,7 +383,7 @@ ConsoleMethod( SimComponent, addComponents, bool, 3, 64, "%obj.addComponents( %c
|
|||
if(obj)
|
||||
object->addComponent(obj);
|
||||
else
|
||||
Con::printf("SimComponent::addComponents - Invalid Component Object \"%s\"", argv[i]);
|
||||
Con::printf("SimComponent::addComponents - Invalid Component Object \"%s\"", (const char*)argv[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ ConsoleMethod( SimComponent, removeComponents, bool, 3, 64, "%obj.removeComponen
|
|||
if(obj)
|
||||
object->removeComponent(obj);
|
||||
else
|
||||
Con::printf("SimComponent::removeComponents - Invalid Component Object \"%s\"", argv[i]);
|
||||
Con::printf("SimComponent::removeComponents - Invalid Component Object \"%s\"", (const char*)argv[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -449,4 +449,4 @@ ConsoleMethod(SimComponent, getIsTemplate, bool, 2, 2, "() Check whether SimComp
|
|||
"@return true if is a template and false if not")
|
||||
{
|
||||
return object->getIsTemplate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ public:
|
|||
|
||||
static void initPersistFields();
|
||||
|
||||
virtual bool processArguments(S32 argc, const char **argv);
|
||||
virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
|
||||
|
||||
bool isEnabled() const { return mEnabled; }
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class ICallMethod
|
|||
{
|
||||
public:
|
||||
virtual const char* callMethod( S32 argc, const char* methodName, ... ) = 0;
|
||||
virtual const char* callMethodArgList( U32 argc, const char *argv[], bool callThis = true ) = 0;
|
||||
virtual const char* callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis = true ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -158,7 +158,7 @@ SimXMLDocument::~SimXMLDocument()
|
|||
// -----------------------------------------------------------------------------
|
||||
// Included for completeness.
|
||||
// -----------------------------------------------------------------------------
|
||||
bool SimXMLDocument::processArguments(S32 argc, const char** argv)
|
||||
bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
return argc == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class SimXMLDocument: public SimObject
|
|||
// tie in to the script language. The .cc file has more in depth
|
||||
// comments on these.
|
||||
//-----------------------------------------------------------------------
|
||||
bool processArguments(S32 argc, const char** argv);
|
||||
bool processArguments(S32 argc, ConsoleValueRef *argv);
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
static void initPersistFields();
|
||||
|
|
|
|||
|
|
@ -103,10 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
|
|||
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
|
||||
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
|
||||
|
||||
const char* argv[ 3 ];
|
||||
argv[ 0 ] = smCompareFunction;
|
||||
argv[ 1 ] = ea->key;
|
||||
argv[ 2 ] = eb->key;
|
||||
ConsoleValueRef argv[] = { smCompareFunction, ea->key, eb->key };
|
||||
|
||||
S32 result = dAtoi( Con::execute( 3, argv ) );
|
||||
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
|
||||
|
|
@ -118,10 +115,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void
|
|||
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
|
||||
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
|
||||
|
||||
const char* argv[ 3 ];
|
||||
argv[ 0 ] = smCompareFunction;
|
||||
argv[ 1 ] = ea->value;
|
||||
argv[ 2 ] = eb->value;
|
||||
ConsoleValueRef argv[] = { smCompareFunction, ea->value, eb->value };
|
||||
|
||||
S32 result = dAtoi( Con::execute( 3, argv ) );
|
||||
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ enum TypeReq
|
|||
TypeReqNone,
|
||||
TypeReqUInt,
|
||||
TypeReqFloat,
|
||||
TypeReqString
|
||||
TypeReqString,
|
||||
TypeReqVar
|
||||
};
|
||||
|
||||
/// Representation of a node for the scripting language parser.
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
|||
return OP_STR_TO_FLT;
|
||||
case TypeReqNone:
|
||||
return OP_STR_TO_NONE;
|
||||
case TypeReqVar:
|
||||
return OP_SAVEVAR_STR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -120,6 +122,8 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
|||
return OP_FLT_TO_STR;
|
||||
case TypeReqNone:
|
||||
return OP_FLT_TO_NONE;
|
||||
case TypeReqVar:
|
||||
return OP_SAVEVAR_FLT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -134,6 +138,24 @@ static U32 conversionOp(TypeReq src, TypeReq dst)
|
|||
return OP_UINT_TO_STR;
|
||||
case TypeReqNone:
|
||||
return OP_UINT_TO_NONE;
|
||||
case TypeReqVar:
|
||||
return OP_SAVEVAR_UINT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(src == TypeReqVar)
|
||||
{
|
||||
switch(dst)
|
||||
{
|
||||
case TypeReqUInt:
|
||||
return OP_LOADVAR_UINT;
|
||||
case TypeReqFloat:
|
||||
return OP_LOADVAR_FLT;
|
||||
case TypeReqString:
|
||||
return OP_LOADVAR_STR;
|
||||
case TypeReqNone:
|
||||
return OP_COPYVAR_TO_NONE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -192,8 +214,22 @@ U32 ReturnStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
|
|||
codeStream.emit(OP_RETURN_VOID);
|
||||
else
|
||||
{
|
||||
ip = expr->compile(codeStream, ip, TypeReqString);
|
||||
codeStream.emit(OP_RETURN);
|
||||
TypeReq walkType = expr->getPreferredType();
|
||||
if (walkType == TypeReqNone) walkType = TypeReqString;
|
||||
ip = expr->compile(codeStream, ip, walkType);
|
||||
|
||||
// Return the correct type
|
||||
switch (walkType) {
|
||||
case TypeReqUInt:
|
||||
codeStream.emit(OP_RETURN_UINT);
|
||||
break;
|
||||
case TypeReqFloat:
|
||||
codeStream.emit(OP_RETURN_FLT);
|
||||
break;
|
||||
default:
|
||||
codeStream.emit(OP_RETURN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return codeStream.tell();
|
||||
}
|
||||
|
|
@ -698,8 +734,13 @@ U32 VarNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|||
case TypeReqString:
|
||||
codeStream.emit(OP_LOADVAR_STR);
|
||||
break;
|
||||
case TypeReqVar:
|
||||
codeStream.emit(OP_LOADVAR_VAR);
|
||||
break;
|
||||
case TypeReqNone:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return codeStream.tell();
|
||||
}
|
||||
|
|
@ -881,7 +922,20 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|||
if(subType == TypeReqNone)
|
||||
subType = type;
|
||||
if(subType == TypeReqNone)
|
||||
subType = TypeReqString;
|
||||
{
|
||||
// What we need to do in this case is turn it into a VarNode reference.
|
||||
// Unfortunately other nodes such as field access (SlotAccessNode)
|
||||
// cannot be optimized in the same manner as all fields are exposed
|
||||
// and set as strings.
|
||||
if (dynamic_cast<VarNode*>(expr) != NULL)
|
||||
{
|
||||
subType = TypeReqVar;
|
||||
}
|
||||
else
|
||||
{
|
||||
subType = TypeReqString;
|
||||
}
|
||||
}
|
||||
// if it's an array expr, the formula is:
|
||||
// eval expr
|
||||
// (push and pop if it's TypeReqString) OP_ADVANCE_STR
|
||||
|
|
@ -903,6 +957,7 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|||
precompileIdent(varName);
|
||||
|
||||
ip = expr->compile(codeStream, ip, subType);
|
||||
|
||||
if(arrayIndex)
|
||||
{
|
||||
if(subType == TypeReqString)
|
||||
|
|
@ -934,6 +989,9 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|||
case TypeReqFloat:
|
||||
codeStream.emit(OP_SAVEVAR_FLT);
|
||||
break;
|
||||
case TypeReqVar:
|
||||
codeStream.emit(OP_SAVEVAR_VAR);
|
||||
break;
|
||||
case TypeReqNone:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1102,8 +1160,21 @@ U32 FuncCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type)
|
|||
codeStream.emit(OP_PUSH_FRAME);
|
||||
for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext())
|
||||
{
|
||||
ip = walk->compile(codeStream, ip, TypeReqString);
|
||||
codeStream.emit(OP_PUSH);
|
||||
TypeReq walkType = walk->getPreferredType();
|
||||
if (walkType == TypeReqNone) walkType = TypeReqString;
|
||||
ip = walk->compile(codeStream, ip, walkType);
|
||||
switch (walk->getPreferredType())
|
||||
{
|
||||
case TypeReqFloat:
|
||||
codeStream.emit(OP_PUSH_FLT);
|
||||
break;
|
||||
case TypeReqUInt:
|
||||
codeStream.emit(OP_PUSH_UINT);
|
||||
break;
|
||||
default:
|
||||
codeStream.emit(OP_PUSH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(callType == MethodCall || callType == ParentCall)
|
||||
codeStream.emit(OP_CALLFUNC);
|
||||
|
|
@ -1392,6 +1463,7 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root)
|
|||
// OP_FINISH_OBJECT <-- fail point jumps to this opcode
|
||||
|
||||
codeStream.emit(OP_PUSH_FRAME);
|
||||
|
||||
ip = classNameExpr->compile(codeStream, ip, TypeReqString);
|
||||
codeStream.emit(OP_PUSH);
|
||||
|
||||
|
|
@ -1399,8 +1471,21 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root)
|
|||
codeStream.emit(OP_PUSH);
|
||||
for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext())
|
||||
{
|
||||
ip = exprWalk->compile(codeStream, ip, TypeReqString);
|
||||
codeStream.emit(OP_PUSH);
|
||||
TypeReq walkType = exprWalk->getPreferredType();
|
||||
if (walkType == TypeReqNone) walkType = TypeReqString;
|
||||
ip = exprWalk->compile(codeStream, ip, walkType);
|
||||
switch (exprWalk->getPreferredType())
|
||||
{
|
||||
case TypeReqFloat:
|
||||
codeStream.emit(OP_PUSH_FLT);
|
||||
break;
|
||||
case TypeReqUInt:
|
||||
codeStream.emit(OP_PUSH_UINT);
|
||||
break;
|
||||
default:
|
||||
codeStream.emit(OP_PUSH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
codeStream.emit(OP_CREATE_OBJECT);
|
||||
codeStream.emitSTE(parentObject);
|
||||
|
|
|
|||
|
|
@ -832,6 +832,26 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
|
|||
break;
|
||||
}
|
||||
|
||||
case OP_RETURN_UINT:
|
||||
{
|
||||
Con::printf( "%i: OP_RETURNUINT", ip - 1 );
|
||||
|
||||
if( upToReturn )
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_RETURN_FLT:
|
||||
{
|
||||
Con::printf( "%i: OP_RETURNFLT", ip - 1 );
|
||||
|
||||
if( upToReturn )
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_CMPEQ:
|
||||
{
|
||||
Con::printf( "%i: OP_CMPEQ", ip - 1 );
|
||||
|
|
@ -1012,6 +1032,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
|
|||
break;
|
||||
}
|
||||
|
||||
case OP_LOADVAR_VAR:
|
||||
{
|
||||
Con::printf( "%i: OP_LOADVAR_VAR", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_SAVEVAR_UINT:
|
||||
{
|
||||
Con::printf( "%i: OP_SAVEVAR_UINT", ip - 1 );
|
||||
|
|
@ -1030,6 +1056,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
|
|||
break;
|
||||
}
|
||||
|
||||
case OP_SAVEVAR_VAR:
|
||||
{
|
||||
Con::printf( "%i: OP_SAVEVAR_VAR", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_SETCUROBJECT:
|
||||
{
|
||||
Con::printf( "%i: OP_SETCUROBJECT", ip - 1 );
|
||||
|
|
@ -1161,6 +1193,12 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
|
|||
break;
|
||||
}
|
||||
|
||||
case OP_COPYVAR_TO_NONE:
|
||||
{
|
||||
Con::printf( "%i: OP_COPYVAR_TO_NONE", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_LOADIMMED_UINT:
|
||||
{
|
||||
U32 val = code[ ip ];
|
||||
|
|
@ -1287,6 +1325,24 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn )
|
|||
break;
|
||||
}
|
||||
|
||||
case OP_PUSH_UINT:
|
||||
{
|
||||
Con::printf( "%i: OP_PUSH_UINT", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_PUSH_FLT:
|
||||
{
|
||||
Con::printf( "%i: OP_PUSH_FLT", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_PUSH_VAR:
|
||||
{
|
||||
Con::printf( "%i: OP_PUSH_VAR", ip - 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_PUSH_FRAME:
|
||||
{
|
||||
Con::printf( "%i: OP_PUSH_FRAME", ip - 1 );
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "console/consoleParser.h"
|
||||
|
||||
class Stream;
|
||||
class ConsoleValue;
|
||||
class ConsoleValueRef;
|
||||
|
||||
/// Core TorqueScript code management class.
|
||||
///
|
||||
|
|
@ -145,8 +147,8 @@ public:
|
|||
/// -1 a new frame is created. If the index is out of range the
|
||||
/// top stack frame is used.
|
||||
/// @param packageName The code package name or null.
|
||||
const char *exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
|
||||
const char **argv, bool noCalls, StringTableEntry packageName,
|
||||
ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
|
||||
ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName,
|
||||
S32 setFrame = -1);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,11 @@ IterStackRecord iterStack[ MaxStackSize ];
|
|||
F64 floatStack[MaxStackSize];
|
||||
S64 intStack[MaxStackSize];
|
||||
|
||||
|
||||
|
||||
|
||||
StringStack STR;
|
||||
ConsoleValueStack CSTK;
|
||||
|
||||
U32 _FLT = 0; ///< Stack pointer for floatStack.
|
||||
U32 _UINT = 0; ///< Stack pointer for intStack.
|
||||
|
|
@ -191,18 +195,16 @@ namespace Con
|
|||
return STR.getArgBuffer(bufferSize);
|
||||
}
|
||||
|
||||
char *getFloatArg(F64 arg)
|
||||
ConsoleValueRef getFloatArg(F64 arg)
|
||||
{
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%g", arg);
|
||||
return ret;
|
||||
ConsoleValueRef ref = arg;
|
||||
return ref;
|
||||
}
|
||||
|
||||
char *getIntArg(S32 arg)
|
||||
ConsoleValueRef getIntArg(S32 arg)
|
||||
{
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
ConsoleValueRef ref = arg;
|
||||
return ref;
|
||||
}
|
||||
|
||||
char *getStringArg( const char *arg )
|
||||
|
|
@ -284,6 +286,25 @@ inline void ExprEvalState::setStringVariable(const char *val)
|
|||
currentVariable->setStringValue(val);
|
||||
}
|
||||
|
||||
inline void ExprEvalState::setCopyVariable()
|
||||
{
|
||||
if (copyVariable)
|
||||
{
|
||||
switch (copyVariable->value.type)
|
||||
{
|
||||
case ConsoleValue::TypeInternalInt:
|
||||
currentVariable->setIntValue(copyVariable->getIntValue());
|
||||
break;
|
||||
case ConsoleValue::TypeInternalFloat:
|
||||
currentVariable->setFloatValue(copyVariable->getFloatValue());
|
||||
break;
|
||||
default:
|
||||
currentVariable->setStringValue(copyVariable->getStringValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// Gets a component of an object's field value or a variable and returns it
|
||||
|
|
@ -404,14 +425,15 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
|
|||
}
|
||||
}
|
||||
|
||||
const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
U32 stackStart = STR.mStartStackSize;
|
||||
U32 consoleStackStart = CSTK.mStackPos;
|
||||
#endif
|
||||
|
||||
static char traceBuffer[1024];
|
||||
U32 i;
|
||||
S32 i;
|
||||
|
||||
U32 iterDepth = 0;
|
||||
|
||||
|
|
@ -427,7 +449,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
// assume this points into a function decl:
|
||||
U32 fnArgc = code[ip + 2 + 6];
|
||||
thisFunctionName = CodeToSTE(code, ip);
|
||||
argc = getMin(argc-1, fnArgc); // argv[0] is func name
|
||||
S32 wantedArgc = getMin(argc-1, fnArgc); // argv[0] is func name
|
||||
if(gEvalState.traceOn)
|
||||
{
|
||||
traceBuffer[0] = 0;
|
||||
|
|
@ -448,22 +470,33 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
|
||||
"%s(", thisFunctionName);
|
||||
}
|
||||
for(i = 0; i < argc; i++)
|
||||
for (i = 0; i < wantedArgc; i++)
|
||||
{
|
||||
dStrcat(traceBuffer, argv[i+1]);
|
||||
if(i != argc - 1)
|
||||
dStrcat(traceBuffer, ", ");
|
||||
dStrcat(traceBuffer, argv[i + 1]);
|
||||
if (i != wantedArgc - 1)
|
||||
dStrcat(traceBuffer, ", ");
|
||||
}
|
||||
dStrcat(traceBuffer, ")");
|
||||
Con::printf("%s", traceBuffer);
|
||||
}
|
||||
gEvalState.pushFrame(thisFunctionName, thisNamespace);
|
||||
popFrame = true;
|
||||
for(i = 0; i < argc; i++)
|
||||
|
||||
for(i = 0; i < wantedArgc; i++)
|
||||
{
|
||||
StringTableEntry var = CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2));
|
||||
gEvalState.setCurVarNameCreate(var);
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
|
||||
ConsoleValueRef ref = argv[i+1];
|
||||
|
||||
if (argv[i+1].isString())
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
else if (argv[i+1].isInt())
|
||||
gEvalState.setIntVariable(argv[i+1]);
|
||||
else if (argv[i+1].isFloat())
|
||||
gEvalState.setFloatVariable(argv[i+1]);
|
||||
else
|
||||
gEvalState.setStringVariable(argv[i+1]);
|
||||
}
|
||||
ip = ip + (fnArgc * 2) + (2 + 6 + 1);
|
||||
curFloatTable = functionFloats;
|
||||
|
|
@ -500,6 +533,10 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
}
|
||||
}
|
||||
|
||||
// Reset the console stack frame which at this point will contain
|
||||
// either nothing or argv[] which we just copied
|
||||
CSTK.resetFrame();
|
||||
|
||||
// Grab the state of the telenet debugger here once
|
||||
// so that the push and pop frames are always balanced.
|
||||
const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
|
||||
|
|
@ -533,7 +570,7 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
char nsDocBlockClass[nsDocLength];
|
||||
|
||||
U32 callArgc;
|
||||
const char **callArgv;
|
||||
ConsoleValueRef *callArgv;
|
||||
|
||||
static char curFieldArray[256];
|
||||
static char prevFieldArray[256];
|
||||
|
|
@ -546,6 +583,10 @@ const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNam
|
|||
Con::gCurrentRoot = this->modPath;
|
||||
}
|
||||
const char * val;
|
||||
const char *retValue;
|
||||
|
||||
// note: anything returned is pushed to CSTK and will be invalidated on the next exec()
|
||||
ConsoleValueRef returnValue;
|
||||
|
||||
// The frame temp is used by the variable accessor ops (OP_SAVEFIELD_* and
|
||||
// OP_LOADFIELD_*) to store temporary values for the fields.
|
||||
|
|
@ -618,8 +659,8 @@ breakContinue:
|
|||
objectCreationStack[ objectCreationStackIndex++ ].failJump = failJump;
|
||||
|
||||
// Get the constructor information off the stack.
|
||||
STR.getArgcArgv(NULL, &callArgc, &callArgv);
|
||||
const char* objectName = callArgv[ 2 ];
|
||||
CSTK.getArgcArgv(NULL, &callArgc, &callArgv);
|
||||
const char *objectName = callArgv[ 2 ];
|
||||
|
||||
// Con::printf("Creating object...");
|
||||
|
||||
|
|
@ -641,6 +682,7 @@ breakContinue:
|
|||
Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare data block %s with a different class.", getFileLine(ip), objectName);
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -662,18 +704,19 @@ breakContinue:
|
|||
break;
|
||||
}
|
||||
|
||||
SimObject *obj = Sim::findObject( objectName );
|
||||
SimObject *obj = Sim::findObject( (const char*)objectName );
|
||||
if (obj /*&& !obj->isLocalName()*/)
|
||||
{
|
||||
if ( isSingleton )
|
||||
{
|
||||
// Make sure we're not trying to change types
|
||||
if ( dStricmp( obj->getClassName(), callArgv[1] ) != 0 )
|
||||
if ( dStricmp( obj->getClassName(), (const char*)callArgv[1] ) != 0 )
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s] with a different class [%s] - was [%s].",
|
||||
getFileLine(ip), objectName, callArgv[1], obj->getClassName());
|
||||
getFileLine(ip), objectName, (const char*)callArgv[1], obj->getClassName());
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -691,13 +734,29 @@ breakContinue:
|
|||
// string stack and may get stomped if deleteObject triggers
|
||||
// script execution.
|
||||
|
||||
const char* savedArgv[ StringStack::MaxArgs ];
|
||||
dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
|
||||
ConsoleValueRef savedArgv[ StringStack::MaxArgs ];
|
||||
for (int i=0; i<callArgc; i++) {
|
||||
savedArgv[i] = callArgv[i];
|
||||
}
|
||||
//dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc );
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
obj->deleteObject();
|
||||
obj = NULL;
|
||||
|
||||
dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
|
||||
//dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc );
|
||||
for (int i=0; i<callArgc; i++) {
|
||||
callArgv[i] = savedArgv[i];
|
||||
}
|
||||
}
|
||||
else if( dStricmp( redefineBehavior, "renameNew" ) == 0 )
|
||||
{
|
||||
|
|
@ -726,6 +785,7 @@ breakContinue:
|
|||
getFileLine(ip), newName.c_str() );
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
|
@ -737,6 +797,7 @@ breakContinue:
|
|||
getFileLine(ip), objectName);
|
||||
ip = failJump;
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -744,16 +805,17 @@ breakContinue:
|
|||
}
|
||||
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
|
||||
if(!currentNewObject)
|
||||
{
|
||||
// Well, looks like we have to create a new object.
|
||||
ConsoleObject *object = ConsoleObject::create(callArgv[1]);
|
||||
ConsoleObject *object = ConsoleObject::create((const char*)callArgv[1]);
|
||||
|
||||
// Deal with failure!
|
||||
if(!object)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
ip = failJump;
|
||||
break;
|
||||
}
|
||||
|
|
@ -769,7 +831,7 @@ breakContinue:
|
|||
else
|
||||
{
|
||||
// They tried to make a non-datablock with a datablock keyword!
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
// Clean up...
|
||||
delete object;
|
||||
ip = failJump;
|
||||
|
|
@ -783,7 +845,7 @@ breakContinue:
|
|||
// Deal with the case of a non-SimObject.
|
||||
if(!currentNewObject)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), (const char*)callArgv[1]);
|
||||
delete object;
|
||||
ip = failJump;
|
||||
break;
|
||||
|
|
@ -810,7 +872,7 @@ breakContinue:
|
|||
else
|
||||
{
|
||||
if ( Con::gObjectCopyFailures == -1 )
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, callArgv[1]);
|
||||
Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, (const char*)callArgv[1]);
|
||||
else
|
||||
++Con::gObjectCopyFailures;
|
||||
|
||||
|
|
@ -833,15 +895,30 @@ breakContinue:
|
|||
currentNewObject->setOriginalName( objectName );
|
||||
}
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
// Do the constructor parameters.
|
||||
if(!currentNewObject->processArguments(callArgc-3, callArgv+3))
|
||||
{
|
||||
delete currentNewObject;
|
||||
currentNewObject = NULL;
|
||||
ip = failJump;
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
|
||||
// If it's not a datablock, allow people to modify bits of it.
|
||||
if(!isDataBlock)
|
||||
{
|
||||
|
|
@ -866,6 +943,11 @@ breakContinue:
|
|||
|
||||
// Con::printf("Adding object %s", currentNewObject->getName());
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
// --
|
||||
|
||||
// Make sure it wasn't already added, then add it.
|
||||
if(currentNewObject->isProperlyAdded() == false)
|
||||
{
|
||||
|
|
@ -889,6 +971,10 @@ breakContinue:
|
|||
Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", getFileLine(ip), currentNewObject->getName(), currentNewObject->getClassName());
|
||||
delete currentNewObject;
|
||||
ip = failJump;
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -897,6 +983,8 @@ breakContinue:
|
|||
SimDataBlock *dataBlock = dynamic_cast<SimDataBlock *>(currentNewObject);
|
||||
static String errorStr;
|
||||
|
||||
|
||||
|
||||
// If so, preload it.
|
||||
if(dataBlock && !dataBlock->preload(true, errorStr))
|
||||
{
|
||||
|
|
@ -904,6 +992,11 @@ breakContinue:
|
|||
currentNewObject->getName(), errorStr.c_str());
|
||||
dataBlock->deleteObject();
|
||||
ip = failJump;
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -958,6 +1051,10 @@ breakContinue:
|
|||
else
|
||||
intStack[++_UINT] = currentNewObject->getId();
|
||||
|
||||
// Prevent stack value corruption
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
// --
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1040,6 +1137,29 @@ breakContinue:
|
|||
// We're falling thru here on purpose.
|
||||
|
||||
case OP_RETURN:
|
||||
retValue = STR.getStringValue();
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
// Clear iterator state.
|
||||
while( iterDepth > 0 )
|
||||
{
|
||||
iterStack[ -- _ITER ].mIsStringIter = false;
|
||||
-- iterDepth;
|
||||
}
|
||||
|
||||
STR.rewind();
|
||||
STR.setStringValue( retValue ); // Not nice but works.
|
||||
retValue = STR.getStringValue();
|
||||
}
|
||||
|
||||
// Previously the return value was on the stack and would be returned using STR.getStringValue().
|
||||
// Now though we need to wrap it in a ConsoleValueRef
|
||||
returnValue.value = CSTK.pushStackString(retValue);
|
||||
|
||||
goto execFinished;
|
||||
|
||||
case OP_RETURN_FLT:
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
|
|
@ -1050,10 +1170,27 @@ breakContinue:
|
|||
-- iterDepth;
|
||||
}
|
||||
|
||||
const char* returnValue = STR.getStringValue();
|
||||
STR.rewind();
|
||||
STR.setStringValue( returnValue ); // Not nice but works.
|
||||
}
|
||||
|
||||
returnValue.value = CSTK.pushFLT(floatStack[_FLT]);
|
||||
_FLT--;
|
||||
|
||||
goto execFinished;
|
||||
|
||||
case OP_RETURN_UINT:
|
||||
|
||||
if( iterDepth > 0 )
|
||||
{
|
||||
// Clear iterator state.
|
||||
while( iterDepth > 0 )
|
||||
{
|
||||
iterStack[ -- _ITER ].mIsStringIter = false;
|
||||
-- iterDepth;
|
||||
}
|
||||
}
|
||||
|
||||
returnValue.value = CSTK.pushUINT(intStack[_UINT]);
|
||||
_UINT--;
|
||||
|
||||
goto execFinished;
|
||||
|
||||
|
|
@ -1196,7 +1333,7 @@ breakContinue:
|
|||
var = CodeToSTE(code, ip);
|
||||
ip += 2;
|
||||
|
||||
// See OP_SETCURVAR
|
||||
// See OP_SETCURVAR
|
||||
prevField = NULL;
|
||||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
|
@ -1253,6 +1390,11 @@ breakContinue:
|
|||
STR.setStringValue(val);
|
||||
break;
|
||||
|
||||
case OP_LOADVAR_VAR:
|
||||
// Sets current source of OP_SAVEVAR_VAR
|
||||
gEvalState.copyVariable = gEvalState.currentVariable;
|
||||
break;
|
||||
|
||||
case OP_SAVEVAR_UINT:
|
||||
gEvalState.setIntVariable(intStack[_UINT]);
|
||||
break;
|
||||
|
|
@ -1264,6 +1406,11 @@ breakContinue:
|
|||
case OP_SAVEVAR_STR:
|
||||
gEvalState.setStringVariable(STR.getStringValue());
|
||||
break;
|
||||
|
||||
case OP_SAVEVAR_VAR:
|
||||
// this basically handles %var1 = %var2
|
||||
gEvalState.setCopyVariable();
|
||||
break;
|
||||
|
||||
case OP_SETCUROBJECT:
|
||||
// Save the previous object for parsing vector fields.
|
||||
|
|
@ -1451,6 +1598,10 @@ breakContinue:
|
|||
_UINT--;
|
||||
break;
|
||||
|
||||
case OP_COPYVAR_TO_NONE:
|
||||
gEvalState.copyVariable = NULL;
|
||||
break;
|
||||
|
||||
case OP_LOADIMMED_UINT:
|
||||
intStack[_UINT+1] = code[ip++];
|
||||
_UINT++;
|
||||
|
|
@ -1527,6 +1678,7 @@ breakContinue:
|
|||
getFileLine(ip-7), fnNamespace ? fnNamespace : "",
|
||||
fnNamespace ? "::" : "", fnName);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1562,7 +1714,7 @@ breakContinue:
|
|||
U32 callType = code[ip+4];
|
||||
|
||||
ip += 5;
|
||||
STR.getArgcArgv(fnName, &callArgc, &callArgv);
|
||||
CSTK.getArgcArgv(fnName, &callArgc, &callArgv);
|
||||
|
||||
const char *componentReturnValue = "";
|
||||
|
||||
|
|
@ -1586,14 +1738,16 @@ breakContinue:
|
|||
else if(callType == FuncCallExprNode::MethodCall)
|
||||
{
|
||||
saveObject = gEvalState.thisObject;
|
||||
gEvalState.thisObject = Sim::findObject(callArgv[1]);
|
||||
gEvalState.thisObject = Sim::findObject((const char*)callArgv[1]);
|
||||
if(!gEvalState.thisObject)
|
||||
{
|
||||
// Go back to the previous saved object.
|
||||
gEvalState.thisObject = saveObject;
|
||||
|
||||
Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), callArgv[1], fnName);
|
||||
Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), (const char*)callArgv[1], fnName);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
STR.setStringValue("");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1649,6 +1803,7 @@ breakContinue:
|
|||
}
|
||||
}
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
|
||||
if( routingId == MethodOnComponent )
|
||||
STR.setStringValue( componentReturnValue );
|
||||
|
|
@ -1659,12 +1814,33 @@ breakContinue:
|
|||
}
|
||||
if(nsEntry->mType == Namespace::Entry::ConsoleFunctionType)
|
||||
{
|
||||
const char *ret = "";
|
||||
ConsoleValueRef ret;
|
||||
if(nsEntry->mFunctionOffset)
|
||||
ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
|
||||
|
||||
|
||||
STR.popFrame();
|
||||
STR.setStringValue(ret);
|
||||
// Functions are assumed to return strings, so look ahead to see if we can skip the conversion
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
intStack[++_UINT] = (U32)((S32)ret);
|
||||
}
|
||||
else if(code[ip] == OP_STR_TO_FLT)
|
||||
{
|
||||
ip++;
|
||||
floatStack[++_FLT] = (F32)ret;
|
||||
}
|
||||
else if(code[ip] == OP_STR_TO_NONE)
|
||||
{
|
||||
STR.setStringValue(ret.getStringValue());
|
||||
ip++;
|
||||
}
|
||||
else
|
||||
STR.setStringValue((const char*)ret);
|
||||
|
||||
// This will clear everything including returnValue
|
||||
CSTK.popFrame();
|
||||
STR.clearFunctionOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1685,6 +1861,7 @@ breakContinue:
|
|||
callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs);
|
||||
Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-6), nsEntry->mUsage);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1694,16 +1871,18 @@ breakContinue:
|
|||
{
|
||||
const char *ret = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(ret != STR.getStringValue())
|
||||
STR.setStringValue(ret);
|
||||
else
|
||||
STR.setLen(dStrlen(ret));
|
||||
//else
|
||||
// STR.setLen(dStrlen(ret));
|
||||
break;
|
||||
}
|
||||
case Namespace::Entry::IntCallbackType:
|
||||
{
|
||||
S32 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1726,6 +1905,7 @@ breakContinue:
|
|||
{
|
||||
F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1750,12 +1930,14 @@ breakContinue:
|
|||
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-6), fnName, functionName);
|
||||
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
STR.setStringValue("");
|
||||
break;
|
||||
case Namespace::Entry::BoolCallbackType:
|
||||
{
|
||||
bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
if(code[ip] == OP_STR_TO_UINT)
|
||||
{
|
||||
ip++;
|
||||
|
|
@ -1810,10 +1992,26 @@ breakContinue:
|
|||
break;
|
||||
case OP_PUSH:
|
||||
STR.push();
|
||||
CSTK.pushString(STR.getPreviousStringValue());
|
||||
break;
|
||||
case OP_PUSH_UINT:
|
||||
CSTK.pushUINT(intStack[_UINT]);
|
||||
_UINT--;
|
||||
break;
|
||||
case OP_PUSH_FLT:
|
||||
CSTK.pushFLT(floatStack[_FLT]);
|
||||
_FLT--;
|
||||
break;
|
||||
case OP_PUSH_VAR:
|
||||
if (gEvalState.currentVariable)
|
||||
CSTK.pushValue(gEvalState.currentVariable->value);
|
||||
else
|
||||
CSTK.pushString("");
|
||||
break;
|
||||
|
||||
case OP_PUSH_FRAME:
|
||||
STR.pushFrame();
|
||||
CSTK.pushFrame();
|
||||
break;
|
||||
|
||||
case OP_ASSERT:
|
||||
|
|
@ -2043,7 +2241,8 @@ execFinished:
|
|||
AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
|
||||
AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
|
||||
#endif
|
||||
return STR.getStringValue();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ namespace Compiler
|
|||
OP_RETURN,
|
||||
// fixes a bug when not explicitly returning a value
|
||||
OP_RETURN_VOID,
|
||||
OP_RETURN_FLT,
|
||||
OP_RETURN_UINT,
|
||||
|
||||
OP_CMPEQ,
|
||||
OP_CMPGR,
|
||||
OP_CMPGE,
|
||||
|
|
@ -96,10 +99,12 @@ namespace Compiler
|
|||
OP_LOADVAR_UINT,// 40
|
||||
OP_LOADVAR_FLT,
|
||||
OP_LOADVAR_STR,
|
||||
OP_LOADVAR_VAR,
|
||||
|
||||
OP_SAVEVAR_UINT,
|
||||
OP_SAVEVAR_FLT,
|
||||
OP_SAVEVAR_STR,
|
||||
OP_SAVEVAR_VAR,
|
||||
|
||||
OP_SETCUROBJECT,
|
||||
OP_SETCUROBJECT_NEW,
|
||||
|
|
@ -126,6 +131,7 @@ namespace Compiler
|
|||
OP_UINT_TO_FLT,
|
||||
OP_UINT_TO_STR,
|
||||
OP_UINT_TO_NONE,
|
||||
OP_COPYVAR_TO_NONE,
|
||||
|
||||
OP_LOADIMMED_UINT,
|
||||
OP_LOADIMMED_FLT,
|
||||
|
|
@ -145,8 +151,11 @@ namespace Compiler
|
|||
OP_TERMINATE_REWIND_STR, // 80
|
||||
OP_COMPARE_STR,
|
||||
|
||||
OP_PUSH,
|
||||
OP_PUSH_FRAME,
|
||||
OP_PUSH, // String
|
||||
OP_PUSH_UINT, // Integer
|
||||
OP_PUSH_FLT, // Float
|
||||
OP_PUSH_VAR, // Variable
|
||||
OP_PUSH_FRAME, // Frame
|
||||
|
||||
OP_ASSERT,
|
||||
OP_BREAK,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
|
||||
extern StringStack STR;
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
ConsoleDocFragment* ConsoleDocFragment::smFirst;
|
||||
ExprEvalState gEvalState;
|
||||
|
|
@ -709,10 +710,11 @@ void errorf(const char* fmt,...)
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void setVariable(const char *name, const char *value)
|
||||
bool getVariableObjectField(const char *name, SimObject **object, const char **field)
|
||||
{
|
||||
// get the field info from the object..
|
||||
if(name[0] != '$' && dStrchr(name, '.') && !isFunction(name))
|
||||
const char *dot = dStrchr(name, '.');
|
||||
if(name[0] != '$' && dot)
|
||||
{
|
||||
S32 len = dStrlen(name);
|
||||
AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - name too long");
|
||||
|
|
@ -721,17 +723,17 @@ void setVariable(const char *name, const char *value)
|
|||
char * token = dStrtok(scratchBuffer, ".");
|
||||
SimObject * obj = Sim::findObject(token);
|
||||
if(!obj)
|
||||
return;
|
||||
return false;
|
||||
|
||||
token = dStrtok(0, ".\0");
|
||||
if(!token)
|
||||
return;
|
||||
return false;
|
||||
|
||||
while(token != NULL)
|
||||
{
|
||||
const char * val = obj->getDataField(StringTable->insert(token), 0);
|
||||
if(!val)
|
||||
return;
|
||||
return false;
|
||||
|
||||
char *fieldToken = token;
|
||||
token = dStrtok(0, ".\0");
|
||||
|
|
@ -739,17 +741,72 @@ void setVariable(const char *name, const char *value)
|
|||
{
|
||||
obj = Sim::findObject(token);
|
||||
if(!obj)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->setDataField(StringTable->insert(fieldToken), 0, value);
|
||||
*object = obj;
|
||||
*field = fieldToken;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Dictionary::Entry *getLocalVariableEntry(const char *name)
|
||||
{
|
||||
name = prependPercent(name);
|
||||
return gEvalState.getCurrentFrame().lookup(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *getVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
gEvalState.globalVars.setVariable(StringTable->insert(name), value);
|
||||
return gEvalState.globalVars.lookup(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *addVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
return gEvalState.globalVars.add(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *getAddVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
StringTableEntry stName = StringTable->insert(name);
|
||||
Dictionary::Entry *entry = gEvalState.globalVars.lookup(stName);
|
||||
if (!entry)
|
||||
entry = gEvalState.globalVars.add(stName);
|
||||
return entry;
|
||||
}
|
||||
|
||||
Dictionary::Entry *getAddLocalVariableEntry(const char *name)
|
||||
{
|
||||
name = prependPercent(name);
|
||||
StringTableEntry stName = StringTable->insert(name);
|
||||
Dictionary::Entry *entry = gEvalState.getCurrentFrame().lookup(stName);
|
||||
if (!entry)
|
||||
entry = gEvalState.getCurrentFrame().add(stName);
|
||||
return entry;
|
||||
}
|
||||
|
||||
void setVariable(const char *name, const char *value)
|
||||
{
|
||||
SimObject *obj = NULL;
|
||||
const char *objField = NULL;
|
||||
|
||||
if (getVariableObjectField(name, &obj, &objField))
|
||||
{
|
||||
obj->setDataField(StringTable->insert(objField), 0, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = prependDollar(name);
|
||||
gEvalState.globalVars.setVariable(StringTable->insert(name), value);
|
||||
}
|
||||
}
|
||||
|
||||
void setLocalVariable(const char *name, const char *value)
|
||||
|
|
@ -760,21 +817,57 @@ void setLocalVariable(const char *name, const char *value)
|
|||
|
||||
void setBoolVariable(const char *varName, bool value)
|
||||
{
|
||||
setVariable(varName, value ? "1" : "0");
|
||||
SimObject *obj = NULL;
|
||||
const char *objField = NULL;
|
||||
|
||||
if (getVariableObjectField(varName, &obj, &objField))
|
||||
{
|
||||
obj->setDataField(StringTable->insert(objField), 0, value ? "1" : "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
varName = prependDollar(varName);
|
||||
Dictionary::Entry *entry = getAddVariableEntry(varName);
|
||||
entry->setStringValue(value ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
void setIntVariable(const char *varName, S32 value)
|
||||
{
|
||||
char scratchBuffer[32];
|
||||
dSprintf(scratchBuffer, sizeof(scratchBuffer), "%d", value);
|
||||
setVariable(varName, scratchBuffer);
|
||||
SimObject *obj = NULL;
|
||||
const char *objField = NULL;
|
||||
|
||||
if (getVariableObjectField(varName, &obj, &objField))
|
||||
{
|
||||
char scratchBuffer[32];
|
||||
dSprintf(scratchBuffer, sizeof(scratchBuffer), "%d", value);
|
||||
obj->setDataField(StringTable->insert(objField), 0, scratchBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
varName = prependDollar(varName);
|
||||
Dictionary::Entry *entry = getAddVariableEntry(varName);
|
||||
entry->setIntValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void setFloatVariable(const char *varName, F32 value)
|
||||
{
|
||||
char scratchBuffer[32];
|
||||
dSprintf(scratchBuffer, sizeof(scratchBuffer), "%g", value);
|
||||
setVariable(varName, scratchBuffer);
|
||||
SimObject *obj = NULL;
|
||||
const char *objField = NULL;
|
||||
|
||||
if (getVariableObjectField(varName, &obj, &objField))
|
||||
{
|
||||
char scratchBuffer[32];
|
||||
dSprintf(scratchBuffer, sizeof(scratchBuffer), "%g", value);
|
||||
obj->setDataField(StringTable->insert(objField), 0, scratchBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
varName = prependDollar(varName);
|
||||
Dictionary::Entry *entry = getAddVariableEntry(varName);
|
||||
entry->setFloatValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -825,13 +918,14 @@ void stripColorChars(char* line)
|
|||
}
|
||||
}
|
||||
|
||||
const char *getVariable(const char *name)
|
||||
//
|
||||
const char *getObjectTokenField(const char *name)
|
||||
{
|
||||
// get the field info from the object..
|
||||
if(name[0] != '$' && dStrchr(name, '.') && !isFunction(name))
|
||||
const char *dot = dStrchr(name, '.');
|
||||
if(name[0] != '$' && dot)
|
||||
{
|
||||
S32 len = dStrlen(name);
|
||||
AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - name too long");
|
||||
AssertFatal(len < sizeof(scratchBuffer)-1, "Sim::getVariable - object name too long");
|
||||
dMemcpy(scratchBuffer, name, len+1);
|
||||
|
||||
char * token = dStrtok(scratchBuffer, ".");
|
||||
|
|
@ -861,8 +955,21 @@ const char *getVariable(const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
name = prependDollar(name);
|
||||
return gEvalState.globalVars.getVariable(StringTable->insert(name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *getVariable(const char *name)
|
||||
{
|
||||
const char *objField = getObjectTokenField(name);
|
||||
if (objField)
|
||||
{
|
||||
return objField;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary::Entry *entry = getVariableEntry(name);
|
||||
return entry ? entry->getStringValue() : "";
|
||||
}
|
||||
}
|
||||
|
||||
const char *getLocalVariable(const char *name)
|
||||
|
|
@ -874,20 +981,45 @@ const char *getLocalVariable(const char *name)
|
|||
|
||||
bool getBoolVariable(const char *varName, bool def)
|
||||
{
|
||||
const char *value = getVariable(varName);
|
||||
return *value ? dAtob(value) : def;
|
||||
const char *objField = getObjectTokenField(varName);
|
||||
if (objField)
|
||||
{
|
||||
return *objField ? dAtob(objField) : def;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary::Entry *entry = getVariableEntry(varName);
|
||||
objField = entry ? entry->getStringValue() : "";
|
||||
return *objField ? dAtob(objField) : def;
|
||||
}
|
||||
}
|
||||
|
||||
S32 getIntVariable(const char *varName, S32 def)
|
||||
{
|
||||
const char *value = getVariable(varName);
|
||||
return *value ? dAtoi(value) : def;
|
||||
const char *objField = getObjectTokenField(varName);
|
||||
if (objField)
|
||||
{
|
||||
return *objField ? dAtoi(objField) : def;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary::Entry *entry = getVariableEntry(varName);
|
||||
return entry ? entry->getIntValue() : def;
|
||||
}
|
||||
}
|
||||
|
||||
F32 getFloatVariable(const char *varName, F32 def)
|
||||
{
|
||||
const char *value = getVariable(varName);
|
||||
return *value ? dAtof(value) : def;
|
||||
const char *objField = getObjectTokenField(varName);
|
||||
if (objField)
|
||||
{
|
||||
return *objField ? dAtof(objField) : def;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary::Entry *entry = getVariableEntry(varName);
|
||||
return entry ? entry->getFloatValue() : def;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -1032,7 +1164,7 @@ const char *evaluatef(const char* string, ...)
|
|||
return newCodeBlock->compileExec(NULL, buffer, false, 0);
|
||||
}
|
||||
|
||||
const char *execute(S32 argc, const char *argv[])
|
||||
const char *execute(S32 argc, ConsoleValueRef argv[])
|
||||
{
|
||||
#ifdef TORQUE_MULTITHREAD
|
||||
if(isMainThread())
|
||||
|
|
@ -1044,10 +1176,11 @@ const char *execute(S32 argc, const char *argv[])
|
|||
|
||||
if(!ent)
|
||||
{
|
||||
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", argv[0]);
|
||||
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]);
|
||||
|
||||
// Clean up arg buffers, if any.
|
||||
STR.clearFunctionOffset();
|
||||
CSTK.resetFrame();
|
||||
return "";
|
||||
}
|
||||
return ent->execute(argc, argv, &gEvalState);
|
||||
|
|
@ -1064,10 +1197,15 @@ const char *execute(S32 argc, const char *argv[])
|
|||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
|
||||
const char *execute(S32 argc, const char *argv[])
|
||||
{
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return execute(args.count(), args);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
|
||||
{
|
||||
static char idBuf[16];
|
||||
if(argc < 2)
|
||||
return "";
|
||||
|
||||
|
|
@ -1078,13 +1216,21 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
|
|||
{
|
||||
ICallMethod *com = dynamic_cast<ICallMethod *>(object);
|
||||
if(com)
|
||||
{
|
||||
STR.pushFrame();
|
||||
CSTK.pushFrame();
|
||||
com->callMethodArgList(argc, argv, false);
|
||||
STR.popFrame();
|
||||
CSTK.popFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if(object->getNamespace())
|
||||
{
|
||||
dSprintf(idBuf, sizeof(idBuf), "%d", object->getId());
|
||||
argv[1] = idBuf;
|
||||
ConsoleValueRef internalArgv[StringStack::MaxArgs];
|
||||
|
||||
U32 ident = object->getId();
|
||||
ConsoleValueRef oldIdent = argv[1];
|
||||
|
||||
StringTableEntry funcName = StringTable->insert(argv[0]);
|
||||
Namespace::Entry *ent = object->getNamespace()->lookup(funcName);
|
||||
|
|
@ -1095,13 +1241,12 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
|
|||
|
||||
// Clean up arg buffers, if any.
|
||||
STR.clearFunctionOffset();
|
||||
CSTK.resetFrame();
|
||||
return "";
|
||||
}
|
||||
|
||||
// Twiddle %this argument
|
||||
const char *oldArg1 = argv[1];
|
||||
dSprintf(idBuf, sizeof(idBuf), "%d", object->getId());
|
||||
argv[1] = idBuf;
|
||||
argv[1] = (S32)ident;
|
||||
|
||||
SimObject *save = gEvalState.thisObject;
|
||||
gEvalState.thisObject = object;
|
||||
|
|
@ -1109,90 +1254,62 @@ const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCa
|
|||
gEvalState.thisObject = save;
|
||||
|
||||
// Twiddle it back
|
||||
argv[1] = oldArg1;
|
||||
argv[1] = oldIdent;
|
||||
|
||||
return ret;
|
||||
}
|
||||
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), argv[0]);
|
||||
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]);
|
||||
return "";
|
||||
}
|
||||
|
||||
#define B( a ) const char* a = NULL
|
||||
#define A const char*
|
||||
inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc,
|
||||
A a, B(b), B(c), B(d), B(e), B(f), B(g), B(h), B(i), B(j), B(k))
|
||||
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
|
||||
{
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return execute(object, args.count(), args, thisCallOnly);
|
||||
}
|
||||
|
||||
inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
#undef A
|
||||
#undef B
|
||||
const U32 maxArg = 12;
|
||||
AssertWarn(checkArgc == argc, "Incorrect arg count passed to Con::executef(SimObject*)");
|
||||
AssertFatal(argc <= maxArg - 1, "Too many args passed to Con::_executef(SimObject*). Please update the function to handle more.");
|
||||
const char* argv[maxArg];
|
||||
argv[0] = a;
|
||||
argv[1] = a;
|
||||
argv[2] = b;
|
||||
argv[3] = c;
|
||||
argv[4] = d;
|
||||
argv[5] = e;
|
||||
argv[6] = f;
|
||||
argv[7] = g;
|
||||
argv[8] = h;
|
||||
argv[9] = i;
|
||||
argv[10] = j;
|
||||
argv[11] = k;
|
||||
return execute(obj, argc+1, argv);
|
||||
return execute(obj, argc, argv);
|
||||
}
|
||||
|
||||
#define A const char*
|
||||
#define A ConsoleValueRef
|
||||
#define OBJ SimObject* obj
|
||||
const char *executef(OBJ, A a) { return _executef(obj, 1, 1, a); }
|
||||
const char *executef(OBJ, A a, A b) { return _executef(obj, 2, 2, a, b); }
|
||||
const char *executef(OBJ, A a, A b, A c) { return _executef(obj, 3, 3, a, b, c); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d) { return _executef(obj, 4, 4, a, b, c, d); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e) { return _executef(obj, 5, 5, a, b, c, d, e); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f) { return _executef(obj, 6, 6, a, b, c, d, e, f); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g) { return _executef(obj, 7, 7, a, b, c, d, e, f, g); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h) { return _executef(obj, 8, 8, a, b, c, d, e, f, g, h); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i) { return _executef(obj, 9, 9, a, b, c, d, e, f, g, h, i); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { return _executef(obj,10,10, a, b, c, d, e, f, g, h, i, j); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j, A k) { return _executef(obj,11,11, a, b, c, d, e, f, g, h, i, j, k); }
|
||||
#undef A
|
||||
const char *executef(OBJ, A a) { ConsoleValueRef params[] = {a,ConsoleValueRef()}; return _executef(obj, 2, 2, params); }
|
||||
const char *executef(OBJ, A a, A b) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b}; return _executef(obj, 3, 3, params); }
|
||||
const char *executef(OBJ, A a, A b, A c) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c}; return _executef(obj, 4, 4, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d}; return _executef(obj, 5, 5, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e}; return _executef(obj, 6, 6, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f}; return _executef(obj, 7, 7, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g}; return _executef(obj, 8, 8, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h}; return _executef(obj, 9, 9, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i}; return _executef(obj, 10, 10, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j}; return _executef(obj, 11, 11, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j, A k) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j,k}; return _executef(obj, 12, 12, params); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define B( a ) const char* a = NULL
|
||||
#define A const char*
|
||||
inline const char*_executef(S32 checkArgc, S32 argc, A a, B(b), B(c), B(d), B(e), B(f), B(g), B(h), B(i), B(j))
|
||||
inline const char*_executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
#undef A
|
||||
#undef B
|
||||
const U32 maxArg = 10;
|
||||
AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef()");
|
||||
AssertFatal(argc <= maxArg, "Too many args passed to Con::_executef(). Please update the function to handle more.");
|
||||
const char* argv[maxArg];
|
||||
argv[0] = a;
|
||||
argv[1] = b;
|
||||
argv[2] = c;
|
||||
argv[3] = d;
|
||||
argv[4] = e;
|
||||
argv[5] = f;
|
||||
argv[6] = g;
|
||||
argv[7] = h;
|
||||
argv[8] = i;
|
||||
argv[9] = j;
|
||||
return execute(argc, argv);
|
||||
}
|
||||
|
||||
#define A const char*
|
||||
const char *executef(A a) { return _executef(1, 1, a); }
|
||||
const char *executef(A a, A b) { return _executef(2, 2, a, b); }
|
||||
const char *executef(A a, A b, A c) { return _executef(3, 3, a, b, c); }
|
||||
const char *executef(A a, A b, A c, A d) { return _executef(4, 4, a, b, c, d); }
|
||||
const char *executef(A a, A b, A c, A d, A e) { return _executef(5, 5, a, b, c, d, e); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f) { return _executef(6, 6, a, b, c, d, e, f); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g) { return _executef(7, 7, a, b, c, d, e, f, g); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h) { return _executef(8, 8, a, b, c, d, e, f, g, h); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i) { return _executef(9, 9, a, b, c, d, e, f, g, h, i); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { return _executef(10,10,a, b, c, d, e, f, g, h, i, j); }
|
||||
#define A ConsoleValueRef
|
||||
const char *executef(A a) { ConsoleValueRef params[] = {a}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b) { ConsoleValueRef params[] = {a,b}; return _executef(2, 2, params); }
|
||||
const char *executef(A a, A b, A c) { ConsoleValueRef params[] = {a,b,c}; return _executef(3, 3, params); }
|
||||
const char *executef(A a, A b, A c, A d) { ConsoleValueRef params[] = {a,b,c,d}; return _executef(4, 4, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e) { ConsoleValueRef params[] = {a,b,c,d,e}; return _executef(5, 5, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f) { ConsoleValueRef params[] = {a,b,c,d,e,f}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g) { ConsoleValueRef params[] = {a,b,c,d,e,f,g}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i,j}; return _executef(1, 1, params); }
|
||||
#undef A
|
||||
|
||||
|
||||
|
|
@ -1390,10 +1507,10 @@ StringTableEntry getModNameFromPath(const char *path)
|
|||
void postConsoleInput( RawData data )
|
||||
{
|
||||
// Schedule this to happen at the next time event.
|
||||
char *argv[2];
|
||||
ConsoleValueRef argv[2];
|
||||
argv[0] = "eval";
|
||||
argv[1] = ( char* ) data.data;
|
||||
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, const_cast<const char**>(argv), false));
|
||||
argv[1] = ( const char* ) data.data;
|
||||
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, argv, false));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -1456,3 +1573,247 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
|
|||
{
|
||||
Con::warnf( "%s", message );
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(const ConsoleValueRef &ref)
|
||||
{
|
||||
value = ref.value;
|
||||
stringStackValue = ref.stringStackValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(const char *newValue) : value(NULL)
|
||||
{
|
||||
*this = newValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(const String &newValue) : value(NULL)
|
||||
{
|
||||
*this = (const char*)(newValue.utf8());
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(U32 newValue) : value(NULL)
|
||||
{
|
||||
*this = newValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(S32 newValue) : value(NULL)
|
||||
{
|
||||
*this = newValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(F32 newValue) : value(NULL)
|
||||
{
|
||||
*this = newValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(F64 newValue) : value(NULL)
|
||||
{
|
||||
*this = newValue;
|
||||
}
|
||||
|
||||
StringStackWrapper::StringStackWrapper(int targc, ConsoleValueRef targv[])
|
||||
{
|
||||
argv = new const char*[targc];
|
||||
argc = targc;
|
||||
|
||||
for (int i=0; i<targc; i++)
|
||||
{
|
||||
argv[i] = dStrdup(targv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
StringStackWrapper::~StringStackWrapper()
|
||||
{
|
||||
for (int i=0; i<argc; i++)
|
||||
{
|
||||
dFree(argv[i]);
|
||||
}
|
||||
delete[] argv;
|
||||
}
|
||||
|
||||
|
||||
StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ)
|
||||
{
|
||||
argv = new ConsoleValueRef[targc];
|
||||
argc = targc;
|
||||
|
||||
for (int i=0; i<targc; i++) {
|
||||
argv[i] = ConsoleValueRef(targ[i]);
|
||||
}
|
||||
}
|
||||
|
||||
StringStackConsoleWrapper::~StringStackConsoleWrapper()
|
||||
{
|
||||
for (int i=0; i<argc; i++)
|
||||
{
|
||||
argv[i] = NULL;
|
||||
}
|
||||
delete[] argv;
|
||||
}
|
||||
|
||||
S32 ConsoleValue::getSignedIntValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
return (S32)fval;
|
||||
else
|
||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
||||
}
|
||||
|
||||
U32 ConsoleValue::getIntValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
return ival;
|
||||
else
|
||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
||||
}
|
||||
|
||||
F32 ConsoleValue::getFloatValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
return fval;
|
||||
else
|
||||
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
||||
}
|
||||
|
||||
const char *ConsoleValue::getStringValue()
|
||||
{
|
||||
if(type == TypeInternalString || type == TypeInternalStackString)
|
||||
return sval;
|
||||
if(type == TypeInternalFloat)
|
||||
return Con::getData(TypeF32, &fval, 0);
|
||||
else if(type == TypeInternalInt)
|
||||
return Con::getData(TypeS32, &ival, 0);
|
||||
else
|
||||
return Con::getData(type, dataPtr, 0, enumTable);
|
||||
}
|
||||
|
||||
bool ConsoleValue::getBoolValue()
|
||||
{
|
||||
if(type == TypeInternalString || type == TypeInternalStackString)
|
||||
return dAtob(sval);
|
||||
if(type == TypeInternalFloat)
|
||||
return fval > 0;
|
||||
else if(type == TypeInternalInt)
|
||||
return ival > 0;
|
||||
else {
|
||||
const char *value = Con::getData(type, dataPtr, 0, enumTable);
|
||||
return dAtob(value);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleValue::setIntValue(S32 val)
|
||||
{
|
||||
setFloatValue(val);
|
||||
}
|
||||
|
||||
void ConsoleValue::setIntValue(U32 val)
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
{
|
||||
fval = (F32)val;
|
||||
ival = val;
|
||||
if(sval != typeValueEmpty)
|
||||
{
|
||||
if (type != TypeInternalStackString) dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *dptr = Con::getData(TypeS32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleValue::setBoolValue(bool val)
|
||||
{
|
||||
return setIntValue(val ? 1 : 0);
|
||||
}
|
||||
|
||||
void ConsoleValue::setFloatValue(F32 val)
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
{
|
||||
fval = val;
|
||||
ival = static_cast<U32>(val);
|
||||
if(sval != typeValueEmpty)
|
||||
{
|
||||
if (type != TypeInternalStackString) dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalFloat;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *dptr = Con::getData(TypeF32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *ConsoleValueRef::getStringArgValue()
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (stringStackValue == NULL)
|
||||
stringStackValue = Con::getStringArg(value->getStringValue());
|
||||
return stringStackValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
|
||||
{
|
||||
value = newValue.value;
|
||||
stringStackValue = newValue.stringStackValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
|
||||
{
|
||||
value = CSTK.pushStackString(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(U32 newValue)
|
||||
{
|
||||
value = CSTK.pushUINT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace Con
|
||||
{
|
||||
void resetStackFrame()
|
||||
{
|
||||
CSTK.resetFrame();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,15 +29,18 @@
|
|||
#ifndef _BITSET_H_
|
||||
#include "core/bitSet.h"
|
||||
#endif
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "core/util/str.h"
|
||||
#include "core/util/journal/journaledSignal.h"
|
||||
|
||||
class SimObject;
|
||||
class Namespace;
|
||||
struct ConsoleFunctionHeader;
|
||||
|
||||
|
||||
class EngineEnumTable;
|
||||
typedef EngineEnumTable EnumTable;
|
||||
|
||||
|
|
@ -110,6 +113,185 @@ struct ConsoleLogEntry
|
|||
};
|
||||
|
||||
typedef const char *StringTableEntry;
|
||||
extern char *typeValueEmpty;
|
||||
|
||||
class ConsoleValue
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
TypeInternalInt = -4,
|
||||
TypeInternalFloat = -3,
|
||||
TypeInternalStackString = -2,
|
||||
TypeInternalString = -1,
|
||||
};
|
||||
|
||||
S32 type;
|
||||
|
||||
public:
|
||||
|
||||
// NOTE: This is protected to ensure no one outside
|
||||
// of this structure is messing with it.
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
|
||||
|
||||
// An variable is either a real dynamic type or
|
||||
// its one exposed from C++ using a data pointer.
|
||||
//
|
||||
// We use this nameless union and struct setup
|
||||
// to optimize the memory usage.
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char *sval;
|
||||
U32 ival; // doubles as strlen when type is TypeInternalString
|
||||
F32 fval;
|
||||
U32 bufferLen;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
/// The real data pointer.
|
||||
void *dataPtr;
|
||||
|
||||
/// The enum lookup table for enumerated types.
|
||||
const EnumTable *enumTable;
|
||||
};
|
||||
};
|
||||
|
||||
U32 getIntValue();
|
||||
S32 getSignedIntValue();
|
||||
F32 getFloatValue();
|
||||
const char *getStringValue();
|
||||
bool getBoolValue();
|
||||
|
||||
void setIntValue(U32 val);
|
||||
void setIntValue(S32 val);
|
||||
void setFloatValue(F32 val);
|
||||
void setStringValue(const char *value);
|
||||
void setStackStringValue(const char *value);
|
||||
void setBoolValue(bool val);
|
||||
|
||||
void init()
|
||||
{
|
||||
ival = 0;
|
||||
fval = 0;
|
||||
sval = typeValueEmpty;
|
||||
bufferLen = 0;
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
if (type <= TypeInternalString &&
|
||||
sval != typeValueEmpty && type != TypeInternalStackString )
|
||||
dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
type = ConsoleValue::TypeInternalString;
|
||||
ival = 0;
|
||||
fval = 0;
|
||||
bufferLen = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Proxy class for console variables
|
||||
// Can point to existing console variables,
|
||||
// or act like a free floating value.
|
||||
class ConsoleValueRef
|
||||
{
|
||||
public:
|
||||
ConsoleValue *value;
|
||||
const char *stringStackValue;
|
||||
|
||||
ConsoleValueRef() : value(0), stringStackValue(0) { ; }
|
||||
~ConsoleValueRef() { ; }
|
||||
|
||||
ConsoleValueRef(const ConsoleValueRef &ref);
|
||||
ConsoleValueRef(const char *value);
|
||||
ConsoleValueRef(const String &ref);
|
||||
ConsoleValueRef(U32 value);
|
||||
ConsoleValueRef(S32 value);
|
||||
ConsoleValueRef(F32 value);
|
||||
ConsoleValueRef(F64 value);
|
||||
|
||||
const char *getStringValue() { return value ? value->getStringValue() : ""; }
|
||||
const char *getStringArgValue();
|
||||
|
||||
inline U32 getIntValue() { return value ? value->getIntValue() : 0; }
|
||||
inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; }
|
||||
inline F32 getFloatValue() { return value ? value->getFloatValue() : 0.0f; }
|
||||
inline bool getBoolValue() { return value ? value->getBoolValue() : false; }
|
||||
|
||||
inline operator const char*() { return getStringValue(); }
|
||||
inline operator String() { return String(getStringValue()); }
|
||||
inline operator U32() { return getIntValue(); }
|
||||
inline operator S32() { return getSignedIntValue(); }
|
||||
inline operator F32() { return getFloatValue(); }
|
||||
|
||||
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStackString : true; }
|
||||
inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; }
|
||||
inline bool isFloat() { return value ? value->type == ConsoleValue::TypeInternalFloat : false; }
|
||||
|
||||
// Note: operators replace value
|
||||
ConsoleValueRef& operator=(const ConsoleValueRef &other);
|
||||
ConsoleValueRef& operator=(const char *newValue);
|
||||
ConsoleValueRef& operator=(U32 newValue);
|
||||
ConsoleValueRef& operator=(S32 newValue);
|
||||
ConsoleValueRef& operator=(F32 newValue);
|
||||
ConsoleValueRef& operator=(F64 newValue);
|
||||
};
|
||||
|
||||
// Overrides to allow ConsoleValueRefs to be directly converted to S32&F32
|
||||
|
||||
inline S32 dAtoi(ConsoleValueRef &ref)
|
||||
{
|
||||
return ref.getSignedIntValue();
|
||||
}
|
||||
|
||||
inline F32 dAtof(ConsoleValueRef &ref)
|
||||
{
|
||||
return ref.getFloatValue();
|
||||
}
|
||||
|
||||
inline bool dAtob(ConsoleValue &ref)
|
||||
{
|
||||
return ref.getBoolValue();
|
||||
}
|
||||
|
||||
|
||||
// Transparently converts ConsoleValue[] to const char**
|
||||
class StringStackWrapper
|
||||
{
|
||||
public:
|
||||
const char **argv;
|
||||
int argc;
|
||||
|
||||
StringStackWrapper(int targc, ConsoleValueRef targv[]);
|
||||
~StringStackWrapper();
|
||||
|
||||
const char* operator[](int idx) { return argv[idx]; }
|
||||
operator const char**() { return argv; }
|
||||
|
||||
int count() { return argc; }
|
||||
};
|
||||
|
||||
// Transparently converts const char** to ConsoleValue
|
||||
class StringStackConsoleWrapper
|
||||
{
|
||||
public:
|
||||
ConsoleValueRef *argv;
|
||||
int argc;
|
||||
|
||||
StringStackConsoleWrapper(int targc, const char **targv);
|
||||
~StringStackConsoleWrapper();
|
||||
|
||||
ConsoleValueRef& operator[](int idx) { return argv[idx]; }
|
||||
operator ConsoleValueRef*() { return argv; }
|
||||
|
||||
int count() { return argc; }
|
||||
};
|
||||
|
||||
/// @defgroup console_callbacks Scripting Engine Callbacks
|
||||
///
|
||||
|
|
@ -129,11 +311,11 @@ typedef const char *StringTableEntry;
|
|||
/// @{
|
||||
|
||||
///
|
||||
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef S32 (*IntCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef F32 (*FloatCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef void (*VoidCallback)(SimObject *obj, S32 argc, const char *argv[]); // We have it return a value so things don't break..
|
||||
typedef bool (*BoolCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
|
||||
typedef S32 (*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
|
||||
typedef F32 (*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
|
||||
typedef void (*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break..
|
||||
typedef bool (*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
|
||||
|
||||
typedef void (*ConsumerCallback)(U32 level, const char *consoleLine);
|
||||
/// @}
|
||||
|
|
@ -183,7 +365,8 @@ namespace Con
|
|||
/// 09/27/07 - RDB - 44->45 Patch from Andreas Kirsch: Added opcode to support correct void return
|
||||
/// 01/13/09 - TMS - 45->46 Added script assert
|
||||
/// 09/07/14 - jamesu - 46->47 64bit support
|
||||
DSOVersion = 47,
|
||||
/// 10/14/14 - jamesu - 47->48 Added opcodes to reduce reliance on strings in function calls
|
||||
DSOVersion = 48,
|
||||
|
||||
MaxLineLength = 512, ///< Maximum length of a line of console input.
|
||||
MaxDataTypes = 256 ///< Maximum number of registered data types.
|
||||
|
|
@ -416,6 +599,11 @@ namespace Con
|
|||
/// @return The string value of the variable or "" if the variable does not exist.
|
||||
const char* getVariable(const char* name);
|
||||
|
||||
/// Retrieve the string value of an object field
|
||||
/// @param name "object.field" string to query
|
||||
/// @return The string value of the variable or NULL if no object is specified
|
||||
const char* getObjectField(const char* name);
|
||||
|
||||
/// Same as setVariable(), but for bools.
|
||||
void setBoolVariable (const char* name,bool var);
|
||||
|
||||
|
|
@ -566,9 +754,11 @@ namespace Con
|
|||
/// char* result = execute(2, argv);
|
||||
/// @endcode
|
||||
const char *execute(S32 argc, const char* argv[]);
|
||||
const char *execute(S32 argc, ConsoleValueRef argv[]);
|
||||
|
||||
/// @see execute(S32 argc, const char* argv[])
|
||||
#define ARG const char*
|
||||
// Note: this can't be ConsoleValueRef& since the compiler will confuse it with SimObject*
|
||||
#define ARG ConsoleValueRef
|
||||
const char *executef( ARG);
|
||||
const char *executef( ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG);
|
||||
|
|
@ -581,7 +771,6 @@ namespace Con
|
|||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
#undef ARG
|
||||
|
||||
|
||||
/// Call a Torque Script member function of a SimObject from C/C++ code.
|
||||
/// @param object Object on which to execute the method call.
|
||||
/// @param argc Number of elements in the argv parameter (must be >2, see argv)
|
||||
|
|
@ -595,9 +784,10 @@ namespace Con
|
|||
/// char* result = execute(mysimobject, 3, argv);
|
||||
/// @endcode
|
||||
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly = false);
|
||||
const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
|
||||
|
||||
/// @see execute(SimObject *, S32 argc, const char *argv[])
|
||||
#define ARG const char*
|
||||
/// @see execute(SimObject *, S32 argc, ConsoleValueRef argv[])
|
||||
#define ARG ConsoleValueRef
|
||||
const char *executef(SimObject *, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG);
|
||||
|
|
@ -641,12 +831,14 @@ namespace Con
|
|||
char* getReturnBuffer( const StringBuilder& str );
|
||||
|
||||
char* getArgBuffer(U32 bufferSize);
|
||||
char* getFloatArg(F64 arg);
|
||||
char* getIntArg (S32 arg);
|
||||
ConsoleValueRef getFloatArg(F64 arg);
|
||||
ConsoleValueRef getIntArg (S32 arg);
|
||||
char* getStringArg( const char *arg );
|
||||
char* getStringArg( const String& arg );
|
||||
/// @}
|
||||
|
||||
void resetStackFrame();
|
||||
|
||||
/// @name Namespaces
|
||||
/// @{
|
||||
|
||||
|
|
@ -942,14 +1134,14 @@ struct ConsoleDocFragment
|
|||
static ConsoleConstructor cfg_ConsoleFunctionGroup_##groupName##_GroupBegin(NULL,#groupName,usage)
|
||||
|
||||
# define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
|
||||
returnType cf_##name(SimObject *, S32, const char **argv); \
|
||||
returnType cf_##name(SimObject *, S32, ConsoleValueRef *argv); \
|
||||
ConsoleConstructor cc_##name##_obj(NULL,#name,cf_##name,usage1,minArgs,maxArgs); \
|
||||
returnType cf_##name(SimObject *, S32 argc, const char **argv)
|
||||
returnType cf_##name(SimObject *, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \
|
||||
returnType ctf_##name(SimObject *, S32, const char **argv); \
|
||||
returnType ctf_##name(SimObject *, S32, ConsoleValueRef *argv); \
|
||||
ConsoleConstructor cc_##name##_obj(NULL,#name,ctf_##name,usage1,minArgs,maxArgs, true); \
|
||||
returnType ctf_##name(SimObject *, S32 argc, const char **argv)
|
||||
returnType ctf_##name(SimObject *, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleFunctionGroupEnd(groupName) \
|
||||
static ConsoleConstructor cfg_##groupName##_GroupEnd(NULL,#groupName,NULL)
|
||||
|
|
@ -962,22 +1154,22 @@ struct ConsoleDocFragment
|
|||
static ConsoleConstructor cc_##className##_##groupName##_GroupBegin(#className,#groupName,usage)
|
||||
|
||||
# define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1) \
|
||||
inline returnType cm_##className##_##name(className *, S32, const char **argv); \
|
||||
returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, const char **argv) { \
|
||||
inline returnType cm_##className##_##name(className *, S32, ConsoleValueRef *argv); \
|
||||
returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
|
||||
AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \
|
||||
conmethod_return_##returnType ) cm_##className##_##name(static_cast<className*>(object),argc,argv); \
|
||||
}; \
|
||||
ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage1,minArgs,maxArgs); \
|
||||
inline returnType cm_##className##_##name(className *object, S32 argc, const char **argv)
|
||||
inline returnType cm_##className##_##name(className *object, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleStaticMethod(className,name,returnType,minArgs,maxArgs,usage1) \
|
||||
inline returnType cm_##className##_##name(S32, const char **); \
|
||||
returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, const char **argv) { \
|
||||
inline returnType cm_##className##_##name(S32, ConsoleValueRef *); \
|
||||
returnType cm_##className##_##name##_caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
|
||||
conmethod_return_##returnType ) cm_##className##_##name(argc,argv); \
|
||||
}; \
|
||||
ConsoleConstructor \
|
||||
cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage1,minArgs,maxArgs); \
|
||||
inline returnType cm_##className##_##name(S32 argc, const char **argv)
|
||||
inline returnType cm_##className##_##name(S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleMethodGroupEnd(className, groupName) \
|
||||
static ConsoleConstructor cc_##className##_##groupName##_GroupEnd(#className,#groupName,NULL)
|
||||
|
|
@ -1000,32 +1192,32 @@ struct ConsoleDocFragment
|
|||
|
||||
// These are identical to what's above, we just want to null out the usage strings.
|
||||
# define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
|
||||
static returnType c##name(SimObject *, S32, const char **); \
|
||||
static returnType c##name(SimObject *, S32, ConsoleValueRef*); \
|
||||
static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs);\
|
||||
static returnType c##name(SimObject *, S32 argc, const char **argv)
|
||||
static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \
|
||||
static returnType c##name(SimObject *, S32, const char **); \
|
||||
static returnType c##name(SimObject *, S32, ConsoleValueRef*); \
|
||||
static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs, true);\
|
||||
static returnType c##name(SimObject *, S32 argc, const char **argv)
|
||||
static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1) \
|
||||
static inline returnType c##className##name(className *, S32, const char **argv); \
|
||||
static returnType c##className##name##caster(SimObject *object, S32 argc, const char **argv) { \
|
||||
static inline returnType c##className##name(className *, S32, ConsoleValueRef *argv); \
|
||||
static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
|
||||
conmethod_return_##returnType ) c##className##name(static_cast<className*>(object),argc,argv); \
|
||||
}; \
|
||||
static ConsoleConstructor \
|
||||
className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs); \
|
||||
static inline returnType c##className##name(className *object, S32 argc, const char **argv)
|
||||
static inline returnType c##className##name(className *object, S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
# define ConsoleStaticMethod(className,name,returnType,minArgs,maxArgs,usage1) \
|
||||
static inline returnType c##className##name(S32, const char **); \
|
||||
static returnType c##className##name##caster(SimObject *object, S32 argc, const char **argv) { \
|
||||
static inline returnType c##className##name(S32, ConsoleValueRef*); \
|
||||
static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
|
||||
conmethod_return_##returnType ) c##className##name(argc,argv); \
|
||||
}; \
|
||||
static ConsoleConstructor \
|
||||
className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs); \
|
||||
static inline returnType c##className##name(S32 argc, const char **argv)
|
||||
static inline returnType c##className##name(S32 argc, ConsoleValueRef *argv)
|
||||
|
||||
#define ConsoleDoc( text )
|
||||
|
||||
|
|
|
|||
|
|
@ -1207,7 +1207,9 @@ ConsoleFunction( nextToken, const char *, 4, 4, "( string str, string token, str
|
|||
"@endtsexample\n\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
char *str = (char *) argv[1];
|
||||
char buffer[4096];
|
||||
dStrncpy(buffer, argv[1], 4096);
|
||||
char *str = buffer;
|
||||
const char *token = argv[2];
|
||||
const char *delim = argv[3];
|
||||
|
||||
|
|
@ -1240,7 +1242,9 @@ ConsoleFunction( nextToken, const char *, 4, 4, "( string str, string token, str
|
|||
str++;
|
||||
}
|
||||
|
||||
return str;
|
||||
char *ret = Con::getReturnBuffer(dStrlen(str)+1);
|
||||
dStrncpy(ret, str, dStrlen(str)+1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -1302,16 +1306,17 @@ ConsoleFunction(getTag, const char *, 2, 2, "(string textTagString)"
|
|||
TORQUE_UNUSED(argc);
|
||||
if(argv[1][0] == StringTagPrefixByte)
|
||||
{
|
||||
const char *arg = argv[1];
|
||||
const char * space = dStrchr(argv[1], ' ');
|
||||
|
||||
U32 len;
|
||||
if(space)
|
||||
len = space - argv[1];
|
||||
len = space - arg;
|
||||
else
|
||||
len = dStrlen(argv[1]) + 1;
|
||||
len = dStrlen(arg) + 1;
|
||||
|
||||
char * ret = Con::getReturnBuffer(len);
|
||||
dStrncpy(ret, argv[1] + 1, len - 1);
|
||||
dStrncpy(ret, arg + 1, len - 1);
|
||||
ret[len - 1] = 0;
|
||||
|
||||
return(ret);
|
||||
|
|
@ -1517,11 +1522,12 @@ ConsoleFunction( realQuit, void, 1, 1, "" )
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( quitWithErrorMessage, void, ( const char* message ),,
|
||||
DefineConsoleFunction( quitWithErrorMessage, void, ( const char* message, S32 status ), (0),
|
||||
"Display an error message box showing the given @a message and then shut down the engine and exit its process.\n"
|
||||
"This function cleanly uninitialized the engine and then exits back to the system with a process "
|
||||
"exit status indicating an error.\n\n"
|
||||
"@param message The message to log to the console and show in an error message box.\n\n"
|
||||
"@param message The message to log to the console and show in an error message box.\n"
|
||||
"@param status The status code to return to the OS.\n\n"
|
||||
"@see quit\n\n"
|
||||
"@ingroup Platform" )
|
||||
{
|
||||
|
|
@ -1532,7 +1538,20 @@ DefineConsoleFunction( quitWithErrorMessage, void, ( const char* message ),,
|
|||
// as the script code should not be allowed to pretty much hard-crash the engine
|
||||
// and prevent proper shutdown. Changed this to use postQuitMessage.
|
||||
|
||||
Platform::postQuitMessage( -1 );
|
||||
Platform::postQuitMessage( status );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( quitWithStatus, void, ( S32 status ), (0),
|
||||
"Shut down the engine and exit its process.\n"
|
||||
"This function cleanly uninitializes the engine and then exits back to the system with a given "
|
||||
"return status code.\n\n"
|
||||
"@param status The status code to return to the OS.\n\n"
|
||||
"@see quitWithErrorMessage\n\n"
|
||||
"@ingroup Platform" )
|
||||
{
|
||||
Platform::postQuitMessage(status);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2368,7 +2387,7 @@ ConsoleFunction(isDefined, bool, 2, 3, "(string varName)"
|
|||
if (dStrcmp(argv[1], "0") && dStrcmp(argv[1], "") && (Sim::findObject(argv[1]) != NULL))
|
||||
return true;
|
||||
else if (argc > 2)
|
||||
Con::errorf("%s() - can't assign a value to a variable of the form \"%s\"", __FUNCTION__, argv[1]);
|
||||
Con::errorf("%s() - can't assign a value to a variable of the form \"%s\"", __FUNCTION__, (const char*)argv[1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -2403,7 +2422,7 @@ ConsoleFunction( pushInstantGroup, void, 1, 2, "([group])"
|
|||
"@internal")
|
||||
{
|
||||
if( argc > 1 )
|
||||
Con::pushInstantGroup( argv[ 1 ] );
|
||||
Con::pushInstantGroup( (const char*)argv[ 1 ] );
|
||||
else
|
||||
Con::pushInstantGroup();
|
||||
}
|
||||
|
|
@ -2423,7 +2442,7 @@ ConsoleFunction(getPrefsPath, const char *, 1, 2, "([relativeFileName])"
|
|||
"@note Appears to be useless in Torque 3D, should be deprecated\n"
|
||||
"@internal")
|
||||
{
|
||||
const char *filename = Platform::getPrefsPath(argc > 1 ? argv[1] : NULL);
|
||||
const char *filename = Platform::getPrefsPath(argc > 1 ? (const char*)argv[1] : NULL);
|
||||
if(filename == NULL || *filename == 0)
|
||||
return "";
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
//#define DEBUG_SPEW
|
||||
|
||||
|
||||
#define ST_INIT_SIZE 15
|
||||
|
||||
static char scratchBuffer[1024];
|
||||
|
|
@ -168,13 +167,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
|
|||
|
||||
for(s = sortList.begin(); s != sortList.end(); s++)
|
||||
{
|
||||
switch((*s)->type)
|
||||
switch((*s)->value.type)
|
||||
{
|
||||
case Entry::TypeInternalInt:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
|
||||
case ConsoleValue::TypeInternalInt:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat);
|
||||
break;
|
||||
case Entry::TypeInternalFloat:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
|
||||
case ConsoleValue::TypeInternalFloat:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.fval, cat);
|
||||
break;
|
||||
default:
|
||||
expandEscape(expandBuffer, (*s)->getStringValue());
|
||||
|
|
@ -228,13 +227,13 @@ void Dictionary::exportVariables( const char *varString, Vector<String> *names,
|
|||
|
||||
if ( values )
|
||||
{
|
||||
switch ( (*s)->type )
|
||||
switch ( (*s)->value.type )
|
||||
{
|
||||
case Entry::TypeInternalInt:
|
||||
values->push_back( String::ToString( (*s)->ival ) );
|
||||
case ConsoleValue::TypeInternalInt:
|
||||
values->push_back( String::ToString( (*s)->value.ival ) );
|
||||
break;
|
||||
case Entry::TypeInternalFloat:
|
||||
values->push_back( String::ToString( (*s)->fval ) );
|
||||
case ConsoleValue::TypeInternalFloat:
|
||||
values->push_back( String::ToString( (*s)->value.fval ) );
|
||||
break;
|
||||
default:
|
||||
expandEscape( expandBuffer, (*s)->getStringValue() );
|
||||
|
|
@ -284,6 +283,7 @@ Dictionary::Entry *Dictionary::lookup(StringTableEntry name)
|
|||
Dictionary::Entry *Dictionary::add(StringTableEntry name)
|
||||
{
|
||||
// Try to find an existing match.
|
||||
//printf("Add Variable %s\n", name);
|
||||
|
||||
Entry* ret = lookup( name );
|
||||
if( ret )
|
||||
|
|
@ -307,7 +307,7 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
|
|||
for( Entry* entry = hashTable->data[ i ]; entry != NULL; )
|
||||
{
|
||||
Entry* next = entry->nextEntry;
|
||||
S32 index = HashPointer( entry->name ) % newTableSize;
|
||||
U32 index = HashPointer( entry->name ) % newTableSize;
|
||||
|
||||
entry->nextEntry = newTableData[ index ];
|
||||
newTableData[ index ] = entry;
|
||||
|
|
@ -330,7 +330,7 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name)
|
|||
|
||||
ret = hashTable->mChunker.alloc();
|
||||
constructInPlace( ret, name );
|
||||
S32 idx = HashPointer(name) % hashTable->size;
|
||||
U32 idx = HashPointer(name) % hashTable->size;
|
||||
ret->nextEntry = hashTable->data[idx];
|
||||
hashTable->data[idx] = ret;
|
||||
|
||||
|
|
@ -454,7 +454,7 @@ char *typeValueEmpty = "";
|
|||
Dictionary::Entry::Entry(StringTableEntry in_name)
|
||||
{
|
||||
name = in_name;
|
||||
type = TypeInternalString;
|
||||
value.type = ConsoleValue::TypeInternalString;
|
||||
notify = NULL;
|
||||
nextEntry = NULL;
|
||||
mUsage = NULL;
|
||||
|
|
@ -462,17 +462,12 @@ Dictionary::Entry::Entry(StringTableEntry in_name)
|
|||
|
||||
// NOTE: This is data inside a nameless
|
||||
// union, so we don't need to init the rest.
|
||||
ival = 0;
|
||||
fval = 0;
|
||||
sval = typeValueEmpty;
|
||||
bufferLen = 0;
|
||||
value.init();
|
||||
}
|
||||
|
||||
Dictionary::Entry::~Entry()
|
||||
{
|
||||
if ( type <= TypeInternalString &&
|
||||
sval != typeValueEmpty )
|
||||
dFree(sval);
|
||||
value.cleanup();
|
||||
|
||||
if ( notify )
|
||||
delete notify;
|
||||
|
|
@ -497,15 +492,11 @@ const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
|
|||
return "";
|
||||
}
|
||||
|
||||
void Dictionary::Entry::setStringValue(const char * value)
|
||||
void ConsoleValue::setStringValue(const char * value)
|
||||
{
|
||||
if( mIsConstant )
|
||||
{
|
||||
Con::errorf( "Cannot assign value to constant '%s'.", name );
|
||||
return;
|
||||
}
|
||||
if (value == NULL) value = typeValueEmpty;
|
||||
|
||||
if(type <= TypeInternalString)
|
||||
if(type <= ConsoleValue::TypeInternalString)
|
||||
{
|
||||
// Let's not remove empty-string-valued global vars from the dict.
|
||||
// If we remove them, then they won't be exported, and sometimes
|
||||
|
|
@ -519,6 +510,16 @@ void Dictionary::Entry::setStringValue(const char * value)
|
|||
return;
|
||||
}
|
||||
*/
|
||||
if (value == typeValueEmpty)
|
||||
{
|
||||
if (sval && sval != typeValueEmpty && type != TypeInternalStackString) dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
bufferLen = 0;
|
||||
fval = 0.f;
|
||||
ival = 0;
|
||||
type = TypeInternalString;
|
||||
return;
|
||||
}
|
||||
|
||||
U32 stringLen = dStrlen(value);
|
||||
|
||||
|
|
@ -537,25 +538,92 @@ void Dictionary::Entry::setStringValue(const char * value)
|
|||
ival = 0;
|
||||
}
|
||||
|
||||
type = TypeInternalString;
|
||||
|
||||
// may as well pad to the next cache line
|
||||
U32 newLen = ((stringLen + 1) + 15) & ~15;
|
||||
|
||||
if(sval == typeValueEmpty)
|
||||
|
||||
if(sval == typeValueEmpty || type == TypeInternalStackString)
|
||||
sval = (char *) dMalloc(newLen);
|
||||
else if(newLen > bufferLen)
|
||||
sval = (char *) dRealloc(sval, newLen);
|
||||
|
||||
type = TypeInternalString;
|
||||
|
||||
bufferLen = newLen;
|
||||
dStrcpy(sval, value);
|
||||
}
|
||||
else
|
||||
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
||||
}
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if ( notify )
|
||||
notify->trigger();
|
||||
|
||||
void ConsoleValue::setStackStringValue(const char * value)
|
||||
{
|
||||
if (value == NULL) value = typeValueEmpty;
|
||||
|
||||
if(type <= ConsoleValue::TypeInternalString)
|
||||
{
|
||||
if (value == typeValueEmpty)
|
||||
{
|
||||
if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString) dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
bufferLen = 0;
|
||||
fval = 0.f;
|
||||
ival = 0;
|
||||
type = TypeInternalString;
|
||||
return;
|
||||
}
|
||||
|
||||
U32 stringLen = dStrlen(value);
|
||||
if(stringLen < 256)
|
||||
{
|
||||
fval = dAtof(value);
|
||||
ival = dAtoi(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
fval = 0.f;
|
||||
ival = 0;
|
||||
}
|
||||
|
||||
type = TypeInternalStackString;
|
||||
sval = (char*)value;
|
||||
bufferLen = stringLen;
|
||||
}
|
||||
else
|
||||
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
||||
}
|
||||
|
||||
|
||||
S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
|
||||
{
|
||||
Entry *ent = lookup(name);
|
||||
if(ent)
|
||||
{
|
||||
if(entValid)
|
||||
*entValid = true;
|
||||
return ent->getIntValue();
|
||||
}
|
||||
|
||||
if(entValid)
|
||||
*entValid = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
F32 Dictionary::getFloatVariable(StringTableEntry name, bool *entValid)
|
||||
{
|
||||
Entry *ent = lookup(name);
|
||||
if(ent)
|
||||
{
|
||||
if(entValid)
|
||||
*entValid = true;
|
||||
return ent->getFloatValue();
|
||||
}
|
||||
|
||||
if(entValid)
|
||||
*entValid = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Dictionary::setVariable(StringTableEntry name, const char *value)
|
||||
|
|
@ -582,19 +650,19 @@ Dictionary::Entry* Dictionary::addVariable( const char *name,
|
|||
|
||||
Entry *ent = add(StringTable->insert(name));
|
||||
|
||||
if ( ent->type <= Entry::TypeInternalString &&
|
||||
ent->sval != typeValueEmpty )
|
||||
dFree(ent->sval);
|
||||
if ( ent->value.type <= ConsoleValue::TypeInternalString &&
|
||||
ent->value.sval != typeValueEmpty && ent->value.type != ConsoleValue::TypeInternalStackString )
|
||||
dFree(ent->value.sval);
|
||||
|
||||
ent->type = type;
|
||||
ent->dataPtr = dataPtr;
|
||||
ent->value.type = type;
|
||||
ent->value.dataPtr = dataPtr;
|
||||
ent->mUsage = usage;
|
||||
|
||||
// Fetch enum table, if any.
|
||||
|
||||
ConsoleBaseType* conType = ConsoleBaseType::getType( type );
|
||||
AssertFatal( conType, "Dictionary::addVariable - invalid console type" );
|
||||
ent->enumTable = conType->getEnumTable();
|
||||
ent->value.enumTable = conType->getEnumTable();
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
|
@ -616,7 +684,7 @@ void Dictionary::addVariableNotify( const char *name, const Con::NotifyDelegate
|
|||
return;
|
||||
|
||||
if ( !ent->notify )
|
||||
ent->notify = new Entry::NotifySignal();
|
||||
ent->notify = new Entry::NotifySignal();
|
||||
|
||||
ent->notify->notify( callback );
|
||||
}
|
||||
|
|
@ -1268,7 +1336,7 @@ void Namespace::markGroup(const char* name, const char* usage)
|
|||
|
||||
extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
|
||||
|
||||
const char *Namespace::Entry::execute(S32 argc, const char **argv, ExprEvalState *state)
|
||||
const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
|
||||
{
|
||||
if(mType == ConsoleFunctionType)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class Namespace
|
|||
void clear();
|
||||
|
||||
///
|
||||
const char *execute( S32 argc, const char** argv, ExprEvalState* state );
|
||||
const char *execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
|
||||
|
||||
/// Return a one-line documentation text string for the function.
|
||||
String getBriefDescription( String* outRemainingDocText = NULL ) const;
|
||||
|
|
@ -275,7 +275,7 @@ class Namespace
|
|||
|
||||
typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
|
||||
|
||||
extern char *typeValueEmpty;
|
||||
|
||||
|
||||
class Dictionary
|
||||
{
|
||||
|
|
@ -283,16 +283,9 @@ public:
|
|||
|
||||
struct Entry
|
||||
{
|
||||
enum
|
||||
{
|
||||
TypeInternalInt = -3,
|
||||
TypeInternalFloat = -2,
|
||||
TypeInternalString = -1,
|
||||
};
|
||||
|
||||
StringTableEntry name;
|
||||
ConsoleValue value;
|
||||
Entry *nextEntry;
|
||||
S32 type;
|
||||
|
||||
typedef Signal<void()> NotifySignal;
|
||||
|
||||
|
|
@ -306,74 +299,42 @@ public:
|
|||
/// Whether this is a constant that cannot be assigned to.
|
||||
bool mIsConstant;
|
||||
|
||||
protected:
|
||||
|
||||
// NOTE: This is protected to ensure no one outside
|
||||
// of this structure is messing with it.
|
||||
|
||||
friend class Dictionary;
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
|
||||
|
||||
// An variable is either a real dynamic type or
|
||||
// its one exposed from C++ using a data pointer.
|
||||
//
|
||||
// We use this nameless union and struct setup
|
||||
// to optimize the memory usage.
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char *sval;
|
||||
U32 ival; // doubles as strlen when type is TypeInternalString
|
||||
F32 fval;
|
||||
U32 bufferLen;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
/// The real data pointer.
|
||||
void *dataPtr;
|
||||
|
||||
/// The enum lookup table for enumerated types.
|
||||
const EnumTable *enumTable;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma warning( pop ) // C4201
|
||||
|
||||
public:
|
||||
|
||||
Entry() {
|
||||
name = NULL;
|
||||
notify = NULL;
|
||||
nextEntry = NULL;
|
||||
mUsage = NULL;
|
||||
mIsConstant = false;
|
||||
value.init();
|
||||
}
|
||||
|
||||
Entry(StringTableEntry name);
|
||||
~Entry();
|
||||
|
||||
U32 getIntValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
return ival;
|
||||
else
|
||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
||||
|
||||
Entry *mNext;
|
||||
|
||||
void reset() {
|
||||
name = NULL;
|
||||
value.cleanup();
|
||||
if ( notify )
|
||||
delete notify;
|
||||
}
|
||||
|
||||
F32 getFloatValue()
|
||||
inline U32 getIntValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
return fval;
|
||||
else
|
||||
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
||||
return value.getIntValue();
|
||||
}
|
||||
|
||||
const char *getStringValue()
|
||||
inline F32 getFloatValue()
|
||||
{
|
||||
if(type == TypeInternalString)
|
||||
return sval;
|
||||
if(type == TypeInternalFloat)
|
||||
return Con::getData(TypeF32, &fval, 0);
|
||||
else if(type == TypeInternalInt)
|
||||
return Con::getData(TypeS32, &ival, 0);
|
||||
else
|
||||
return Con::getData(type, dataPtr, 0, enumTable);
|
||||
return value.getFloatValue();
|
||||
}
|
||||
|
||||
inline const char *getStringValue()
|
||||
{
|
||||
return value.getStringValue();
|
||||
}
|
||||
|
||||
void setIntValue(U32 val)
|
||||
|
|
@ -383,23 +344,8 @@ public:
|
|||
Con::errorf( "Cannot assign value to constant '%s'.", name );
|
||||
return;
|
||||
}
|
||||
|
||||
if(type <= TypeInternalString)
|
||||
{
|
||||
fval = (F32)val;
|
||||
ival = val;
|
||||
if(sval != typeValueEmpty)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *dptr = Con::getData(TypeS32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
|
||||
value.setIntValue(val);
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if ( notify )
|
||||
|
|
@ -413,159 +359,163 @@ public:
|
|||
Con::errorf( "Cannot assign value to constant '%s'.", name );
|
||||
return;
|
||||
}
|
||||
|
||||
if(type <= TypeInternalString)
|
||||
{
|
||||
fval = val;
|
||||
ival = static_cast<U32>(val);
|
||||
if(sval != typeValueEmpty)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalFloat;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *dptr = Con::getData(TypeF32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
|
||||
value.setFloatValue(val);
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if ( notify )
|
||||
notify->trigger();
|
||||
}
|
||||
|
||||
void setStringValue(const char *value);
|
||||
void setStringValue(const char *newValue)
|
||||
{
|
||||
if( mIsConstant )
|
||||
{
|
||||
Con::errorf( "Cannot assign value to constant '%s'.", name );
|
||||
return;
|
||||
}
|
||||
|
||||
value.setStringValue(newValue);
|
||||
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if ( notify )
|
||||
notify->trigger();
|
||||
}
|
||||
};
|
||||
|
||||
struct HashTableData
|
||||
{
|
||||
Dictionary* owner;
|
||||
S32 size;
|
||||
S32 count;
|
||||
Entry **data;
|
||||
FreeListChunker< Entry > mChunker;
|
||||
|
||||
HashTableData( Dictionary* owner )
|
||||
: owner( owner ), size( 0 ), count( 0 ), data( NULL ) {}
|
||||
};
|
||||
struct HashTableData
|
||||
{
|
||||
Dictionary* owner;
|
||||
S32 size;
|
||||
S32 count;
|
||||
Entry **data;
|
||||
FreeListChunker< Entry > mChunker;
|
||||
|
||||
HashTableData( Dictionary* owner )
|
||||
: owner( owner ), size( 0 ), count( 0 ), data( NULL ) {}
|
||||
};
|
||||
|
||||
HashTableData* hashTable;
|
||||
HashTableData ownHashTable;
|
||||
ExprEvalState *exprState;
|
||||
|
||||
StringTableEntry scopeName;
|
||||
Namespace *scopeNamespace;
|
||||
CodeBlock *code;
|
||||
U32 ip;
|
||||
HashTableData* hashTable;
|
||||
HashTableData ownHashTable;
|
||||
ExprEvalState *exprState;
|
||||
|
||||
Dictionary();
|
||||
~Dictionary();
|
||||
StringTableEntry scopeName;
|
||||
Namespace *scopeNamespace;
|
||||
CodeBlock *code;
|
||||
U32 ip;
|
||||
|
||||
Entry *lookup(StringTableEntry name);
|
||||
Entry *add(StringTableEntry name);
|
||||
void setState(ExprEvalState *state, Dictionary* ref=NULL);
|
||||
void remove(Entry *);
|
||||
void reset();
|
||||
Dictionary();
|
||||
~Dictionary();
|
||||
|
||||
void exportVariables( const char *varString, const char *fileName, bool append );
|
||||
void exportVariables( const char *varString, Vector<String> *names, Vector<String> *values );
|
||||
void deleteVariables( const char *varString );
|
||||
Entry *lookup(StringTableEntry name);
|
||||
Entry *add(StringTableEntry name);
|
||||
void setState(ExprEvalState *state, Dictionary* ref=NULL);
|
||||
void remove(Entry *);
|
||||
void reset();
|
||||
|
||||
void setVariable(StringTableEntry name, const char *value);
|
||||
const char *getVariable(StringTableEntry name, bool *valid = NULL);
|
||||
|
||||
U32 getCount() const
|
||||
{
|
||||
void exportVariables( const char *varString, const char *fileName, bool append );
|
||||
void exportVariables( const char *varString, Vector<String> *names, Vector<String> *values );
|
||||
void deleteVariables( const char *varString );
|
||||
|
||||
void setVariable(StringTableEntry name, const char *value);
|
||||
const char *getVariable(StringTableEntry name, bool *valid = NULL);
|
||||
S32 getIntVariable(StringTableEntry name, bool *valid = NULL);
|
||||
F32 getFloatVariable(StringTableEntry name, bool *entValid = NULL);
|
||||
|
||||
U32 getCount() const
|
||||
{
|
||||
return hashTable->count;
|
||||
}
|
||||
bool isOwner() const
|
||||
{
|
||||
}
|
||||
bool isOwner() const
|
||||
{
|
||||
return hashTable->owner;
|
||||
}
|
||||
}
|
||||
|
||||
/// @see Con::addVariable
|
||||
Entry* addVariable( const char *name,
|
||||
S32 type,
|
||||
void *dataPtr,
|
||||
const char* usage );
|
||||
/// @see Con::addVariable
|
||||
Entry* addVariable( const char *name,
|
||||
S32 type,
|
||||
void *dataPtr,
|
||||
const char* usage );
|
||||
|
||||
/// @see Con::removeVariable
|
||||
bool removeVariable(StringTableEntry name);
|
||||
/// @see Con::removeVariable
|
||||
bool removeVariable(StringTableEntry name);
|
||||
|
||||
/// @see Con::addVariableNotify
|
||||
void addVariableNotify( const char *name, const Con::NotifyDelegate &callback );
|
||||
/// @see Con::addVariableNotify
|
||||
void addVariableNotify( const char *name, const Con::NotifyDelegate &callback );
|
||||
|
||||
/// @see Con::removeVariableNotify
|
||||
void removeVariableNotify( const char *name, const Con::NotifyDelegate &callback );
|
||||
/// @see Con::removeVariableNotify
|
||||
void removeVariableNotify( const char *name, const Con::NotifyDelegate &callback );
|
||||
|
||||
/// Return the best tab completion for prevText, with the length
|
||||
/// of the pre-tab string in baseLen.
|
||||
const char *tabComplete(const char *prevText, S32 baseLen, bool);
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
/// Return the best tab completion for prevText, with the length
|
||||
/// of the pre-tab string in baseLen.
|
||||
const char *tabComplete(const char *prevText, S32 baseLen, bool);
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
};
|
||||
|
||||
class ExprEvalState
|
||||
{
|
||||
public:
|
||||
/// @name Expression Evaluation
|
||||
/// @{
|
||||
/// @name Expression Evaluation
|
||||
/// @{
|
||||
|
||||
///
|
||||
SimObject *thisObject;
|
||||
Dictionary::Entry *currentVariable;
|
||||
bool traceOn;
|
||||
|
||||
U32 mStackDepth;
|
||||
///
|
||||
SimObject *thisObject;
|
||||
Dictionary::Entry *currentVariable;
|
||||
Dictionary::Entry *copyVariable;
|
||||
bool traceOn;
|
||||
|
||||
ExprEvalState();
|
||||
~ExprEvalState();
|
||||
U32 mStackDepth;
|
||||
|
||||
/// @}
|
||||
ExprEvalState();
|
||||
~ExprEvalState();
|
||||
|
||||
/// @name Stack Management
|
||||
/// @{
|
||||
/// @}
|
||||
|
||||
/// The stack of callframes. The extra redirection is necessary since Dictionary holds
|
||||
/// an interior pointer that will become invalid when the object changes address.
|
||||
Vector< Dictionary* > stack;
|
||||
/// @name Stack Management
|
||||
/// @{
|
||||
|
||||
///
|
||||
Dictionary globalVars;
|
||||
|
||||
void setCurVarName(StringTableEntry name);
|
||||
void setCurVarNameCreate(StringTableEntry name);
|
||||
S32 getIntVariable();
|
||||
F64 getFloatVariable();
|
||||
const char *getStringVariable();
|
||||
void setIntVariable(S32 val);
|
||||
void setFloatVariable(F64 val);
|
||||
void setStringVariable(const char *str);
|
||||
/// The stack of callframes. The extra redirection is necessary since Dictionary holds
|
||||
/// an interior pointer that will become invalid when the object changes address.
|
||||
Vector< Dictionary* > stack;
|
||||
|
||||
void pushFrame(StringTableEntry frameName, Namespace *ns);
|
||||
void popFrame();
|
||||
///
|
||||
Dictionary globalVars;
|
||||
|
||||
/// Puts a reference to an existing stack frame
|
||||
/// on the top of the stack.
|
||||
void pushFrameRef(S32 stackIndex);
|
||||
|
||||
U32 getStackDepth() const
|
||||
{
|
||||
return mStackDepth;
|
||||
}
|
||||
|
||||
Dictionary& getCurrentFrame()
|
||||
{
|
||||
void setCurVarName(StringTableEntry name);
|
||||
void setCurVarNameCreate(StringTableEntry name);
|
||||
|
||||
S32 getIntVariable();
|
||||
F64 getFloatVariable();
|
||||
const char *getStringVariable();
|
||||
void setIntVariable(S32 val);
|
||||
void setFloatVariable(F64 val);
|
||||
void setStringVariable(const char *str);
|
||||
void setCopyVariable();
|
||||
|
||||
void pushFrame(StringTableEntry frameName, Namespace *ns);
|
||||
void popFrame();
|
||||
|
||||
/// Puts a reference to an existing stack frame
|
||||
/// on the top of the stack.
|
||||
void pushFrameRef(S32 stackIndex);
|
||||
|
||||
U32 getStackDepth() const
|
||||
{
|
||||
return mStackDepth;
|
||||
}
|
||||
|
||||
Dictionary& getCurrentFrame()
|
||||
{
|
||||
return *( stack[ mStackDepth - 1 ] );
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
/// @}
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
};
|
||||
|
||||
namespace Con
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void ConsoleLogger::initPersistFields()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ConsoleLogger::processArguments( S32 argc, const char **argv )
|
||||
bool ConsoleLogger::processArguments( S32 argc, ConsoleValueRef *argv )
|
||||
{
|
||||
if( argc == 0 )
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class ConsoleLogger : public SimObject
|
|||
/// // Example script constructor usage.
|
||||
/// %obj = new ConsoleLogger( objName, logFileName, [append = false] );
|
||||
/// @endcode
|
||||
bool processArguments( S32 argc, const char **argv );
|
||||
bool processArguments( S32 argc, ConsoleValueRef *argv );
|
||||
|
||||
/// Default constructor, make sure to initalize
|
||||
ConsoleLogger();
|
||||
|
|
|
|||
|
|
@ -834,3 +834,44 @@ DefineEngineFunction( sizeof, S32, ( const char *objectOrClass ),,
|
|||
Con::warnf("could not find a class rep for that object or class name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNSName ),,
|
||||
"@brief Links childNS to parentNS.\n\n"
|
||||
"Links childNS to parentNS, or nothing if parentNS is NULL.\n"
|
||||
"Will unlink the namespace from previous namespace if a parent already exists.\n"
|
||||
"@internal\n")
|
||||
{
|
||||
StringTableEntry childNSSTE = StringTable->insert(childNSName.c_str());
|
||||
StringTableEntry parentNSSTE = StringTable->insert(parentNSName.c_str());
|
||||
|
||||
Namespace *childNS = Namespace::find(childNSSTE);
|
||||
Namespace *parentNS = Namespace::find(parentNSSTE);
|
||||
Namespace *currentParent = childNS->getParent();
|
||||
|
||||
if (!childNS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Link to new NS if applicable
|
||||
|
||||
if (currentParent != parentNS)
|
||||
{
|
||||
if (currentParent != NULL)
|
||||
{
|
||||
if (!childNS->unlinkClass(currentParent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parentNS != NULL)
|
||||
{
|
||||
return childNS->classLinkTo(parentNS);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,12 +146,12 @@ inline const char* EngineMarshallData( U32 value )
|
|||
/// Marshal data from native into client form stored directly in
|
||||
/// client function invocation vector.
|
||||
template< typename T >
|
||||
inline void EngineMarshallData( const T& arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = Con::getStringArg( castConsoleTypeToString( arg ) );
|
||||
argc ++;
|
||||
}
|
||||
inline void EngineMarshallData( bool arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( bool arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
if( arg )
|
||||
argv[ argc ] = "1";
|
||||
|
|
@ -159,33 +159,33 @@ inline void EngineMarshallData( bool arg, S32& argc, const char** argv )
|
|||
argv[ argc ] = "0";
|
||||
argc ++;
|
||||
}
|
||||
inline void EngineMarshallData( S32 arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = Con::getIntArg( arg );
|
||||
argv[ argc ] = arg;
|
||||
argc ++;
|
||||
}
|
||||
inline void EngineMarshallData( U32 arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
EngineMarshallData( S32( arg ), argc, argv );
|
||||
}
|
||||
inline void EngineMarshallData( F32 arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = Con::getFloatArg( arg );
|
||||
argv[ argc ] = arg;
|
||||
argc ++;
|
||||
}
|
||||
inline void EngineMarshallData( const char* arg, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = arg;
|
||||
argc ++;
|
||||
}
|
||||
template< typename T >
|
||||
inline void EngineMarshallData( T* object, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( T* object, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = ( object ? object->getIdString() : "0" );
|
||||
argc ++;
|
||||
}
|
||||
template< typename T >
|
||||
inline void EngineMarshallData( const T* object, S32& argc, const char** argv )
|
||||
inline void EngineMarshallData( const T* object, S32& argc, ConsoleValueRef *argv )
|
||||
{
|
||||
argv[ argc ] = ( object ? object->getIdString() : "0" );
|
||||
argc ++;
|
||||
|
|
@ -208,6 +208,11 @@ struct EngineUnmarshallData
|
|||
template<>
|
||||
struct EngineUnmarshallData< S32 >
|
||||
{
|
||||
S32 operator()( ConsoleValueRef &ref ) const
|
||||
{
|
||||
return (S32)ref;
|
||||
}
|
||||
|
||||
S32 operator()( const char* str ) const
|
||||
{
|
||||
return dAtoi( str );
|
||||
|
|
@ -216,6 +221,11 @@ struct EngineUnmarshallData< S32 >
|
|||
template<>
|
||||
struct EngineUnmarshallData< U32 >
|
||||
{
|
||||
U32 operator()( ConsoleValueRef &ref ) const
|
||||
{
|
||||
return (U32)((S32)ref);
|
||||
}
|
||||
|
||||
U32 operator()( const char* str ) const
|
||||
{
|
||||
return dAtoui( str );
|
||||
|
|
@ -224,6 +234,11 @@ struct EngineUnmarshallData< U32 >
|
|||
template<>
|
||||
struct EngineUnmarshallData< F32 >
|
||||
{
|
||||
F32 operator()( ConsoleValueRef &ref ) const
|
||||
{
|
||||
return (F32)ref;
|
||||
}
|
||||
|
||||
F32 operator()( const char* str ) const
|
||||
{
|
||||
return dAtof( str );
|
||||
|
|
@ -1392,12 +1407,12 @@ struct _EngineConsoleThunk< startArgc, R() >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 0;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
|
||||
{
|
||||
return _EngineConsoleThunkReturnValue( fn() );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
|
||||
{
|
||||
return _EngineConsoleThunkReturnValue( ( frame->*fn )() );
|
||||
}
|
||||
|
|
@ -1407,12 +1422,12 @@ struct _EngineConsoleThunk< startArgc, void() >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 0;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
|
||||
{
|
||||
fn();
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
|
||||
{
|
||||
return ( frame->*fn )();
|
||||
}
|
||||
|
|
@ -1423,13 +1438,13 @@ struct _EngineConsoleThunk< startArgc, R( A ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 1 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
return _EngineConsoleThunkReturnValue( fn( a ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
return _EngineConsoleThunkReturnValue( ( frame->*fn )( a ) );
|
||||
|
|
@ -1440,13 +1455,13 @@ struct _EngineConsoleThunk< startArgc, void( A ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 1 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
fn( a );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
( frame->*fn )( a );
|
||||
|
|
@ -1458,14 +1473,14 @@ struct _EngineConsoleThunk< startArgc, R( A, B ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 2 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
return _EngineConsoleThunkReturnValue( fn( a, b ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1477,14 +1492,14 @@ struct _EngineConsoleThunk< startArgc, void( A, B ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 2 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
fn( a, b );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1497,7 +1512,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 3 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1505,7 +1520,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1518,7 +1533,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 3 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1526,7 +1541,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
|
|||
fn( a, b, c );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1540,7 +1555,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 4 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1549,7 +1564,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1563,7 +1578,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 4 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1572,7 +1587,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
|
|||
fn( a, b, c, d );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1587,7 +1602,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 5 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1597,7 +1612,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1612,7 +1627,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 5 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1622,7 +1637,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
|
|||
fn( a, b, c, d, e );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1638,7 +1653,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 6 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1649,7 +1664,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1665,7 +1680,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 6 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1676,7 +1691,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
|
|||
fn( a, b, c, d, e, f );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1693,7 +1708,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 7 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1705,7 +1720,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1722,7 +1737,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 7 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1734,7 +1749,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
|
|||
fn( a, b, c, d, e, f, g );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1752,7 +1767,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 8 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1765,7 +1780,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1783,7 +1798,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 8 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1796,7 +1811,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
|
|||
fn( a, b, c, d, e, f, g, h );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1815,7 +1830,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 9 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1829,7 +1844,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1848,7 +1863,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 9 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1862,7 +1877,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
|
|||
fn( a, b, c, d, e, f, g, h, i );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1882,7 +1897,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 10 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1897,7 +1912,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1917,7 +1932,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 10 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1932,7 +1947,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
|
|||
fn( a, b, c, d, e, f, g, h, i, j );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1952,7 +1967,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
{
|
||||
typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
|
||||
static const S32 NUM_ARGS = 11 + startArgc;
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -1968,7 +1983,7 @@ struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k ) );
|
||||
}
|
||||
template< typename Frame >
|
||||
static ReturnType thunk( S32 argc, const char** argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -1989,7 +2004,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
{
|
||||
typedef void ReturnType;
|
||||
static const S32 NUM_ARGS = 11 + startArgc;
|
||||
static void thunk( S32 argc, const char** argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.a ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
|
||||
|
|
@ -2005,7 +2020,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
fn( a, b, c, d, e, f, g, h, i, j, k );
|
||||
}
|
||||
template< typename Frame >
|
||||
static void thunk( S32 argc, const char** argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
|
||||
{
|
||||
A a = ( startArgc < argc ? EngineUnmarshallData< A >()( argv[ startArgc ] ) : A( defaultArgs.b ) );
|
||||
B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
|
||||
|
|
@ -2089,7 +2104,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
( void* ) &fn ## name, \
|
||||
0 \
|
||||
); \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, const char** argv ) \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
|
||||
{ \
|
||||
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
|
||||
argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
|
||||
|
|
@ -2169,7 +2184,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
( void* ) &fn ## className ## _ ## name, \
|
||||
0 \
|
||||
); \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, const char** argv ) \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
|
||||
{ \
|
||||
_ ## className ## name ## frame frame; \
|
||||
frame.object = static_cast< className* >( object ); \
|
||||
|
|
@ -2226,7 +2241,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
( void* ) &fn ## className ## _ ## name, \
|
||||
0 \
|
||||
); \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, const char** argv )\
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
|
||||
{ \
|
||||
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
|
||||
argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
|
||||
|
|
@ -2250,7 +2265,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
#define DefineConsoleFunction( name, returnType, args, defaultArgs, usage ) \
|
||||
static inline returnType _fn ## name ## impl args; \
|
||||
static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, const char** argv ) \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
|
||||
{ \
|
||||
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
|
||||
argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
|
||||
|
|
@ -2275,7 +2290,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
}; \
|
||||
static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
|
||||
_fn ## className ## name ## DefaultArgs defaultArgs; \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, const char** argv ) \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
|
||||
{ \
|
||||
_ ## className ## name ## frame frame; \
|
||||
frame.object = static_cast< className* >( object ); \
|
||||
|
|
@ -2297,7 +2312,7 @@ struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
|
|||
#define DefineConsoleStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
|
||||
static inline returnType _fn ## className ## name ## impl args; \
|
||||
static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, const char** argv )\
|
||||
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
|
||||
{ \
|
||||
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
|
||||
argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
|
||||
|
|
@ -2620,14 +2635,19 @@ struct _EngineConsoleCallbackHelper
|
|||
|
||||
SimObject* mThis;
|
||||
S32 mArgc;
|
||||
const char* mArgv[ MAX_ARGUMENTS + 2 ];
|
||||
ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
|
||||
|
||||
const char* _exec()
|
||||
{
|
||||
if( mThis )
|
||||
{
|
||||
// Cannot invoke callback until object has been registered
|
||||
return mThis->isProperlyAdded() ? Con::execute( mThis, mArgc, mArgv ) : "";
|
||||
if (mThis->isProperlyAdded()) {
|
||||
return Con::execute( mThis, mArgc, mArgv );
|
||||
} else {
|
||||
Con::resetStackFrame(); // We might have pushed some vars here
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else
|
||||
return Con::execute( mArgc, mArgv );
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ static void dumpVariable( Stream& stream,
|
|||
{
|
||||
// Skip variables defined in script.
|
||||
|
||||
if( entry->type < 0 )
|
||||
if( entry->value.type < 0 )
|
||||
return;
|
||||
|
||||
// Skip internals... don't export them.
|
||||
|
|
@ -149,7 +149,7 @@ static void dumpVariable( Stream& stream,
|
|||
|
||||
// Skip variables for which we can't decipher their type.
|
||||
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.type );
|
||||
if( !type )
|
||||
{
|
||||
Con::errorf( "Can't find type for variable '%s'", entry->name );
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ ConsoleMethod(FieldBrushObject, copyFields, void, 3, 4, "(simObject, [fieldList]
|
|||
}
|
||||
|
||||
// Fetch field list.
|
||||
const char* pFieldList = (argc > 3 ) ? argv[3] : NULL;
|
||||
const char* pFieldList = (argc > 3 ) ? (const char*)argv[3] : NULL;
|
||||
|
||||
// Copy Fields.
|
||||
object->copyFields( pSimObject, pFieldList );
|
||||
|
|
|
|||
|
|
@ -2204,7 +2204,7 @@ ConsoleMethod( PersistenceManager, setDirty, void, 3, 4, "(SimObject object, [fi
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2213,7 +2213,7 @@ ConsoleMethod( PersistenceManager, setDirty, void, 3, 4, "(SimObject object, [fi
|
|||
|
||||
if( dirtyObject == Sim::getRootGroup() )
|
||||
{
|
||||
Con::errorf( "%s(): Cannot save RootGroup", argv[ 0 ] );
|
||||
Con::errorf( "%s(): Cannot save RootGroup", (const char*)argv[ 0 ] );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2234,7 +2234,7 @@ ConsoleMethod( PersistenceManager, removeDirty, void, 3, 3, "(SimObject object)"
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2251,7 +2251,7 @@ ConsoleMethod( PersistenceManager, isDirty, bool, 3, 3, "(SimObject object)"
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2280,7 +2280,7 @@ ConsoleMethod( PersistenceManager, getDirtyObject, S32, 3, 3, "( index )"
|
|||
const S32 index = dAtoi( argv[2] );
|
||||
if ( index < 0 || index >= object->getDirtyList().size() )
|
||||
{
|
||||
Con::warnf( "PersistenceManager::getDirtyObject() - Index (%s) out of range.", argv[2] );
|
||||
Con::warnf( "PersistenceManager::getDirtyObject() - Index (%s) out of range.", (const char*)argv[2] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2333,7 +2333,7 @@ ConsoleMethod( PersistenceManager, saveDirtyObject, bool, 3, 3, "(SimObject obje
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2358,7 +2358,7 @@ ConsoleMethod( PersistenceManager, removeObjectFromFile, void, 3, 4, "(SimObject
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2380,7 +2380,7 @@ ConsoleMethod( PersistenceManager, removeField, void, 4, 4, "(SimObject object,
|
|||
{
|
||||
if (!Sim::findObject(argv[2], dirtyObject))
|
||||
{
|
||||
Con::printf("%s(): Invalid SimObject: %s", argv[0], argv[2]);
|
||||
Con::printf("%s(): Invalid SimObject: %s", (const char*)argv[0], (const char*)argv[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2390,4 +2390,4 @@ ConsoleMethod( PersistenceManager, removeField, void, 4, 4, "(SimObject object,
|
|||
if (argv[3][0])
|
||||
object->addRemoveField(dirtyObject, argv[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,20 +138,20 @@ ConsoleDocFragment _spawnObject1(
|
|||
ConsoleFunction(spawnObject, S32, 3, 6, "spawnObject(class [, dataBlock, name, properties, script])"
|
||||
"@hide")
|
||||
{
|
||||
String spawnClass(argv[1]);
|
||||
String spawnClass((const char*)argv[1]);
|
||||
String spawnDataBlock;
|
||||
String spawnName;
|
||||
String spawnProperties;
|
||||
String spawnScript;
|
||||
|
||||
if (argc >= 3)
|
||||
spawnDataBlock = argv[2];
|
||||
spawnDataBlock = (const char*)argv[2];
|
||||
if (argc >= 4)
|
||||
spawnName = argv[3];
|
||||
spawnName = (const char*)argv[3];
|
||||
if (argc >= 5)
|
||||
spawnProperties = argv[4];
|
||||
spawnProperties = (const char*)argv[4];
|
||||
if (argc >= 6)
|
||||
spawnScript = argv[5];
|
||||
spawnScript = (const char*)argv[5];
|
||||
|
||||
SimObject* spawnObject = Sim::spawnObject(spawnClass, spawnDataBlock, spawnName, spawnProperties, spawnScript);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
#ifndef _MODULE_H_
|
||||
#include "core/module.h"
|
||||
#endif
|
||||
#ifndef _CONSOLE_H_
|
||||
#include "console/console.h"
|
||||
#endif
|
||||
|
||||
// Forward Refs
|
||||
class SimSet;
|
||||
|
|
@ -122,9 +125,15 @@ namespace Sim
|
|||
SimDataBlockGroup *getDataBlockGroup();
|
||||
SimGroup* getRootGroup();
|
||||
|
||||
SimObject* findObject(ConsoleValueRef&);
|
||||
SimObject* findObject(SimObjectId);
|
||||
SimObject* findObject(const char* name);
|
||||
SimObject* findObject(const char* fileName, S32 declarationLine);
|
||||
template<class T> inline bool findObject(ConsoleValueRef &ref,T*&t)
|
||||
{
|
||||
t = dynamic_cast<T*>(findObject(ref));
|
||||
return t != NULL;
|
||||
}
|
||||
template<class T> inline bool findObject(SimObjectId iD,T*&t)
|
||||
{
|
||||
t = dynamic_cast<T*>(findObject(iD));
|
||||
|
|
|
|||
|
|
@ -28,30 +28,28 @@
|
|||
// Stupid globals not declared in a header
|
||||
extern ExprEvalState gEvalState;
|
||||
|
||||
SimConsoleEvent::SimConsoleEvent(S32 argc, const char **argv, bool onObject)
|
||||
SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject)
|
||||
{
|
||||
mOnObject = onObject;
|
||||
mArgc = argc;
|
||||
U32 totalSize = 0;
|
||||
S32 i;
|
||||
for(i = 0; i < argc; i++)
|
||||
totalSize += dStrlen(argv[i]) + 1;
|
||||
totalSize += sizeof(char *) * argc;
|
||||
|
||||
mArgv = (char **) dMalloc(totalSize);
|
||||
char *argBase = (char *) &mArgv[argc];
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
mArgv = new ConsoleValueRef[argc];
|
||||
for (int i=0; i<argc; i++)
|
||||
{
|
||||
mArgv[i] = argBase;
|
||||
dStrcpy(mArgv[i], argv[i]);
|
||||
argBase += dStrlen(argv[i]) + 1;
|
||||
mArgv[i].value = new ConsoleValue();
|
||||
mArgv[i].value->type = ConsoleValue::TypeInternalString;
|
||||
mArgv[i].value->init();
|
||||
mArgv[i].value->setStringValue((const char*)argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SimConsoleEvent::~SimConsoleEvent()
|
||||
{
|
||||
dFree(mArgv);
|
||||
for (int i=0; i<mArgc; i++)
|
||||
{
|
||||
delete mArgv[i].value;
|
||||
}
|
||||
delete[] mArgv;
|
||||
}
|
||||
|
||||
void SimConsoleEvent::process(SimObject* object)
|
||||
|
|
@ -60,12 +58,14 @@ void SimConsoleEvent::process(SimObject* object)
|
|||
// Con::printf("Executing schedule: %d", sequenceCount);
|
||||
// #endif
|
||||
if(mOnObject)
|
||||
Con::execute(object, mArgc, const_cast<const char**>( mArgv ));
|
||||
Con::execute(object, mArgc, mArgv );
|
||||
else
|
||||
{
|
||||
// Grab the function name. If '::' doesn't exist, then the schedule is
|
||||
// on a global function.
|
||||
char* func = dStrstr( mArgv[0], (char*)"::" );
|
||||
char funcName[256];
|
||||
dStrncpy(funcName, (const char*)mArgv[0], 256);
|
||||
char* func = dStrstr( funcName, (char*)"::" );
|
||||
if( func )
|
||||
{
|
||||
// Set the first colon to NULL, so we can reference the namespace.
|
||||
|
|
@ -77,18 +77,18 @@ void SimConsoleEvent::process(SimObject* object)
|
|||
func += 2;
|
||||
|
||||
// Lookup the namespace and function entry.
|
||||
Namespace* ns = Namespace::find( StringTable->insert( mArgv[0] ) );
|
||||
Namespace* ns = Namespace::find( StringTable->insert( funcName ) );
|
||||
if( ns )
|
||||
{
|
||||
Namespace::Entry* nse = ns->lookup( StringTable->insert( func ) );
|
||||
if( nse )
|
||||
// Execute.
|
||||
nse->execute( mArgc, (const char**)mArgv, &gEvalState );
|
||||
nse->execute( mArgc, mArgv, &gEvalState );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
Con::execute(mArgc, const_cast<const char**>( mArgv ));
|
||||
Con::execute(mArgc, mArgv );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ const char *SimConsoleThreadExecCallback::waitForResult()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, const char **argv, bool onObject, SimConsoleThreadExecCallback *callback) :
|
||||
SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback) :
|
||||
SimConsoleEvent(argc, argv, onObject), cb(callback)
|
||||
{
|
||||
}
|
||||
|
|
@ -131,9 +131,9 @@ void SimConsoleThreadExecEvent::process(SimObject* object)
|
|||
{
|
||||
const char *retVal;
|
||||
if(mOnObject)
|
||||
retVal = Con::execute(object, mArgc, const_cast<const char**>( mArgv ));
|
||||
retVal = Con::execute(object, mArgc, mArgv);
|
||||
else
|
||||
retVal = Con::execute(mArgc, const_cast<const char**>( mArgv ));
|
||||
retVal = Con::execute(mArgc, mArgv);
|
||||
|
||||
if(cb)
|
||||
cb->handleCallback(retVal);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
// Forward Refs
|
||||
class SimObject;
|
||||
class Semaphore;
|
||||
class ConsoleValue;
|
||||
|
||||
/// Represents a queued event in the sim.
|
||||
///
|
||||
|
|
@ -82,6 +83,8 @@ public:
|
|||
virtual void process(SimObject *object)=0;
|
||||
};
|
||||
|
||||
class ConsoleValueRef;
|
||||
|
||||
/// Implementation of schedule() function.
|
||||
///
|
||||
/// This allows you to set a console function to be
|
||||
|
|
@ -90,7 +93,7 @@ class SimConsoleEvent : public SimEvent
|
|||
{
|
||||
protected:
|
||||
S32 mArgc;
|
||||
char **mArgv;
|
||||
ConsoleValueRef *mArgv;
|
||||
bool mOnObject;
|
||||
public:
|
||||
|
||||
|
|
@ -107,7 +110,7 @@ public:
|
|||
///
|
||||
/// @see Con::execute(S32 argc, const char *argv[])
|
||||
/// @see Con::execute(SimObject *object, S32 argc, const char *argv[])
|
||||
SimConsoleEvent(S32 argc, const char **argv, bool onObject);
|
||||
SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject);
|
||||
|
||||
~SimConsoleEvent();
|
||||
virtual void process(SimObject *object);
|
||||
|
|
@ -131,7 +134,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
|
|||
SimConsoleThreadExecCallback *cb;
|
||||
|
||||
public:
|
||||
SimConsoleThreadExecEvent(S32 argc, const char **argv, bool onObject, SimConsoleThreadExecCallback *callback);
|
||||
SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback);
|
||||
|
||||
virtual void process(SimObject *object);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -328,6 +328,11 @@ SimObject* findObject(const char* fileName, S32 declarationLine)
|
|||
return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
|
||||
}
|
||||
|
||||
SimObject* findObject(ConsoleValueRef &ref)
|
||||
{
|
||||
return findObject((const char*)ref);
|
||||
}
|
||||
|
||||
SimObject* findObject(const char* name)
|
||||
{
|
||||
PROFILE_SCOPE(SimFindObject);
|
||||
|
|
@ -367,6 +372,8 @@ SimObject* findObject(const char* name)
|
|||
return NULL;
|
||||
return obj->findObject(temp);
|
||||
}
|
||||
else if (c < '0' || c > '9')
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
S32 len;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ SimObject::~SimObject()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SimObject::processArguments(S32 argc, const char**argv)
|
||||
bool SimObject::processArguments(S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
return argc == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ class SimObject: public ConsoleObject
|
|||
|
||||
virtual ~SimObject();
|
||||
|
||||
virtual bool processArguments(S32 argc, const char **argv); ///< Process constructor options. (ie, new SimObject(1,2,3))
|
||||
virtual bool processArguments(S32 argc, ConsoleValueRef *argv); ///< Process constructor options. (ie, new SimObject(1,2,3))
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ S32 QSORT_CALLBACK SimObjectList::_callbackSort( const void *a, const void *b )
|
|||
static char idB[64];
|
||||
dSprintf( idB, sizeof( idB ), "%d", objB->getId() );
|
||||
|
||||
return dAtoi( Con::executef( smSortScriptCallbackFn, idA, idB ) );
|
||||
return dAtoi( Con::executef( (const char*)smSortScriptCallbackFn, idA, idB ) );
|
||||
}
|
||||
|
||||
void SimObjectList::scriptSort( const String &scriptCallback )
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ SimPersistSet::SimPersistSet()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SimPersistSet::processArguments( S32 argc, const char** argv )
|
||||
bool SimPersistSet::processArguments( S32 argc, ConsoleValueRef *argv )
|
||||
{
|
||||
for( U32 i = 0; i < argc; ++ i )
|
||||
{
|
||||
|
|
@ -54,7 +54,7 @@ bool SimPersistSet::processArguments( S32 argc, const char** argv )
|
|||
Torque::UUID uuid;
|
||||
if( !uuid.fromString( argv[ i ] ) )
|
||||
{
|
||||
Con::errorf( "SimPersistSet::processArguments - could not read UUID at index %i: %s", i, argv[ i ] );
|
||||
Con::errorf( "SimPersistSet::processArguments - could not read UUID at index %i: %s", i, (const char*)argv[ i ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class SimPersistSet : public SimSet
|
|||
// SimSet.
|
||||
virtual void addObject( SimObject* );
|
||||
virtual void write( Stream &stream, U32 tabStop, U32 flags = 0 );
|
||||
virtual bool processArguments( S32 argc, const char** argv );
|
||||
virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
|
||||
|
||||
DECLARE_CONOBJECT( SimPersistSet );
|
||||
DECLARE_CATEGORY( "Console" );
|
||||
|
|
|
|||
|
|
@ -228,11 +228,11 @@ void SimSet::scriptSort( const String &scriptCallbackFn )
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SimSet::callOnChildren( const String &method, S32 argc, const char *argv[], bool executeOnChildGroups )
|
||||
void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups )
|
||||
{
|
||||
// Prep the arguments for the console exec...
|
||||
// Make sure and leave args[1] empty.
|
||||
const char* args[21];
|
||||
ConsoleValueRef args[21];
|
||||
args[0] = method.c_str();
|
||||
for (S32 i = 0; i < argc; i++)
|
||||
args[i + 2] = argv[i];
|
||||
|
|
@ -834,7 +834,7 @@ SimGroup* SimGroup::deepClone()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SimGroup::processArguments(S32, const char **)
|
||||
bool SimGroup::processArguments(S32, ConsoleValueRef *argv)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -909,7 +909,7 @@ ConsoleMethod( SimSet, add, void, 3, 0,
|
|||
if(obj)
|
||||
object->addObject( obj );
|
||||
else
|
||||
Con::printf("Set::add: Object \"%s\" doesn't exist", argv[ i ] );
|
||||
Con::printf("Set::add: Object \"%s\" doesn't exist", (const char*)argv[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,7 +934,7 @@ ConsoleMethod( SimSet, remove, void, 3, 0,
|
|||
if(obj && object->find(object->begin(),object->end(),obj) != object->end())
|
||||
object->removeObject(obj);
|
||||
else
|
||||
Con::printf("Set::remove: Object \"%s\" does not exist in set", argv[i]);
|
||||
Con::printf("Set::remove: Object \"%s\" does not exist in set", (const char*)argv[i]);
|
||||
object->unlock();
|
||||
}
|
||||
}
|
||||
|
|
@ -973,7 +973,7 @@ ConsoleMethod( SimSet, callOnChildren, void, 3, 0,
|
|||
"@note This method recurses into all SimSets that are children to the set.\n\n"
|
||||
"@see callOnChildrenNoRecurse" )
|
||||
{
|
||||
object->callOnChildren( argv[2], argc - 3, argv + 3 );
|
||||
object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -985,7 +985,7 @@ ConsoleMethod( SimSet, callOnChildrenNoRecurse, void, 3, 0,
|
|||
"@note This method does not recurse into child SimSets.\n\n"
|
||||
"@see callOnChildren" )
|
||||
{
|
||||
object->callOnChildren( argv[2], argc - 3, argv + 3, false );
|
||||
object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3, false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1121,7 +1121,7 @@ DefineEngineMethod( SimSet, pushToBack, void, ( SimObject* obj ),,
|
|||
ConsoleMethod( SimSet, sort, void, 3, 3, "( string callbackFunction ) Sort the objects in the set using the given comparison function.\n"
|
||||
"@param callbackFunction Name of a function that takes two object arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal." )
|
||||
{
|
||||
object->scriptSort( argv[2] );
|
||||
object->scriptSort( (const char*)argv[2] );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ class SimSet: public SimObject
|
|||
|
||||
/// @}
|
||||
|
||||
void callOnChildren( const String &method, S32 argc, const char *argv[], bool executeOnChildGroups = true );
|
||||
void callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups = true );
|
||||
|
||||
/// Return the number of objects in this set as well as all sets that are contained
|
||||
/// in this set and its children.
|
||||
|
|
@ -434,7 +434,7 @@ class SimGroup: public SimSet
|
|||
virtual SimObject* findObject(const char* name);
|
||||
virtual void onRemove();
|
||||
|
||||
virtual bool processArguments( S32 argc, const char** argv );
|
||||
virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
|
||||
|
||||
DECLARE_CONOBJECT( SimGroup );
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,22 +20,180 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/stringStack.h"
|
||||
|
||||
void StringStack::getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame /* = false */)
|
||||
{
|
||||
U32 startStack = mFrameOffsets[mNumFrames-1] + 1;
|
||||
U32 argCount = getMin(mStartStackSize - startStack, (U32)MaxArgs - 1);
|
||||
|
||||
*in_argv = mArgV;
|
||||
mArgV[0] = name;
|
||||
void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame /* = false */)
|
||||
{
|
||||
U32 startStack = mStackFrames[mFrame-1];
|
||||
U32 argCount = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
|
||||
|
||||
*in_argv = mArgv;
|
||||
mArgv[0] = name;
|
||||
|
||||
for(U32 i = 0; i < argCount; i++)
|
||||
mArgV[i+1] = mBuffer + mStartOffsets[startStack + i];
|
||||
for(U32 i = 0; i < argCount; i++) {
|
||||
ConsoleValueRef *ref = &mArgv[i+1];
|
||||
ref->value = &mStack[startStack + i];
|
||||
ref->stringStackValue = NULL;
|
||||
}
|
||||
argCount++;
|
||||
|
||||
*argc = argCount;
|
||||
|
||||
if(popStackFrame)
|
||||
popFrame();
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleValueStack::ConsoleValueStack() :
|
||||
mFrame(0),
|
||||
mStackPos(0)
|
||||
{
|
||||
for (int i=0; i<ConsoleValueStack::MaxStackDepth; i++) {
|
||||
mStack[i].init();
|
||||
mStack[i].type = ConsoleValue::TypeInternalString;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleValueStack::~ConsoleValueStack()
|
||||
{
|
||||
}
|
||||
|
||||
void ConsoleValueStack::pushVar(ConsoleValue *variable)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (variable->type)
|
||||
{
|
||||
case ConsoleValue::TypeInternalInt:
|
||||
mStack[mStackPos++].setIntValue((S32)variable->getIntValue());
|
||||
case ConsoleValue::TypeInternalFloat:
|
||||
mStack[mStackPos++].setFloatValue((F32)variable->getFloatValue());
|
||||
default:
|
||||
mStack[mStackPos++].setStackStringValue(variable->getStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleValueStack::pushValue(ConsoleValue &variable)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (variable.type)
|
||||
{
|
||||
case ConsoleValue::TypeInternalInt:
|
||||
mStack[mStackPos++].setIntValue((S32)variable.getIntValue());
|
||||
case ConsoleValue::TypeInternalFloat:
|
||||
mStack[mStackPos++].setFloatValue((F32)variable.getFloatValue());
|
||||
default:
|
||||
mStack[mStackPos++].setStringValue(variable.getStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleValue *ConsoleValueStack::pushString(const char *value)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
|
||||
|
||||
mStack[mStackPos++].setStringValue(value);
|
||||
return &mStack[mStackPos-1];
|
||||
}
|
||||
|
||||
ConsoleValue *ConsoleValueStack::pushStackString(const char *value)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
|
||||
|
||||
mStack[mStackPos++].setStackStringValue(value);
|
||||
return &mStack[mStackPos-1];
|
||||
}
|
||||
|
||||
ConsoleValue *ConsoleValueStack::pushUINT(U32 value)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK pushUINT %i", mStackPos, value);
|
||||
|
||||
mStack[mStackPos++].setIntValue(value);
|
||||
return &mStack[mStackPos-1];
|
||||
}
|
||||
|
||||
ConsoleValue *ConsoleValueStack::pushFLT(float value)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK pushFLT %f", mStackPos, value);
|
||||
|
||||
mStack[mStackPos++].setFloatValue(value);
|
||||
return &mStack[mStackPos-1];
|
||||
}
|
||||
|
||||
static ConsoleValue gNothing;
|
||||
|
||||
ConsoleValue* ConsoleValueStack::pop()
|
||||
{
|
||||
if (mStackPos == 0) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return &gNothing;
|
||||
}
|
||||
|
||||
return &mStack[--mStackPos];
|
||||
}
|
||||
|
||||
void ConsoleValueStack::pushFrame()
|
||||
{
|
||||
//Con::printf("CSTK pushFrame");
|
||||
mStackFrames[mFrame++] = mStackPos;
|
||||
}
|
||||
|
||||
void ConsoleValueStack::resetFrame()
|
||||
{
|
||||
if (mFrame == 0) {
|
||||
mStackPos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
U32 start = mStackFrames[mFrame-1];
|
||||
//for (U32 i=start; i<mStackPos; i++) {
|
||||
//mStack[i].clear();
|
||||
//}
|
||||
mStackPos = start;
|
||||
//Con::printf("CSTK resetFrame to %i", mStackPos);
|
||||
}
|
||||
|
||||
void ConsoleValueStack::popFrame()
|
||||
{
|
||||
//Con::printf("CSTK popFrame");
|
||||
if (mFrame == 0) {
|
||||
// Go back to start
|
||||
mStackPos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
U32 start = mStackFrames[mFrame-1];
|
||||
//for (U32 i=start; i<mStackPos; i++) {
|
||||
//mStack[i].clear();
|
||||
//}
|
||||
mStackPos = start;
|
||||
mFrame--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/// Core stack for interpreter operations.
|
||||
///
|
||||
/// This class provides some powerful semantics for working with strings, and is
|
||||
|
|
@ -185,6 +187,11 @@ struct StringStack
|
|||
return mBuffer + mStart;
|
||||
}
|
||||
|
||||
inline const char *getPreviousStringValue()
|
||||
{
|
||||
return mBuffer + mStartOffsets[mStartStackSize-1];
|
||||
}
|
||||
|
||||
/// Advance the start stack, placing a zero length string on the top.
|
||||
///
|
||||
/// @note You should use StringStack::push, not this, if you want to
|
||||
|
|
@ -275,4 +282,43 @@ struct StringStack
|
|||
void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
|
||||
};
|
||||
|
||||
|
||||
// New console value stack
|
||||
class ConsoleValueStack
|
||||
{
|
||||
enum {
|
||||
MaxStackDepth = 1024,
|
||||
MaxArgs = 20,
|
||||
ReturnBufferSpace = 512
|
||||
};
|
||||
|
||||
public:
|
||||
ConsoleValueStack();
|
||||
~ConsoleValueStack();
|
||||
|
||||
void pushVar(ConsoleValue *variable);
|
||||
void pushValue(ConsoleValue &value);
|
||||
ConsoleValue* pop();
|
||||
|
||||
ConsoleValue *pushString(const char *value);
|
||||
ConsoleValue *pushStackString(const char *value);
|
||||
ConsoleValue *pushUINT(U32 value);
|
||||
ConsoleValue *pushFLT(float value);
|
||||
|
||||
void pushFrame();
|
||||
void popFrame();
|
||||
|
||||
void resetFrame();
|
||||
|
||||
void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);
|
||||
|
||||
ConsoleValue mStack[MaxStackDepth];
|
||||
U32 mStackFrames[MaxStackDepth];
|
||||
|
||||
U32 mFrame;
|
||||
U32 mStackPos;
|
||||
|
||||
ConsoleValueRef mArgv[MaxArgs];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -494,9 +494,9 @@ ConsoleMethod( FileObject, writeObject, void, 3, 4, "FileObject.writeObject(SimO
|
|||
return;
|
||||
}
|
||||
|
||||
char *objName = NULL;
|
||||
const char *objName = NULL;
|
||||
if( argc == 4 )
|
||||
objName = (char*)argv[3];
|
||||
objName = (const char*)argv[3];
|
||||
|
||||
object->writeObject( obj, (const U8*)objName );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,15 +43,21 @@ static Process* _theOneProcess = NULL; ///< the one instance of the Process clas
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Process::requestShutdown()
|
||||
void Process::requestShutdown(S32 status)
|
||||
{
|
||||
Process::get()._RequestShutdown = true;
|
||||
Process::get()._ReturnStatus = status;
|
||||
}
|
||||
|
||||
S32 Process::getReturnStatus()
|
||||
{
|
||||
return Process::get()._ReturnStatus;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Process::Process()
|
||||
: _RequestShutdown( false )
|
||||
: _RequestShutdown( false ), _ReturnStatus( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
static bool processEvents();
|
||||
|
||||
/// Ask the processEvents() function to shutdown.
|
||||
static void requestShutdown();
|
||||
static void requestShutdown(S32 status = 0);
|
||||
|
||||
|
||||
static void notifyInit(Delegate<bool()> del, F32 order = PROCESS_DEFAULT_ORDER)
|
||||
|
|
@ -149,6 +149,9 @@ public:
|
|||
/// Trigger the registered shutdown functions
|
||||
static bool shutdown();
|
||||
|
||||
/// get the current return status code we've been asked to end with.
|
||||
static S32 getReturnStatus();
|
||||
|
||||
private:
|
||||
friend class StandardMainLoop;
|
||||
|
||||
|
|
@ -167,6 +170,7 @@ private:
|
|||
Signal<bool()> _signalShutdown;
|
||||
|
||||
bool _RequestShutdown;
|
||||
S32 _ReturnStatus;
|
||||
};
|
||||
|
||||
/// Register a command line handling function.
|
||||
|
|
|
|||
|
|
@ -944,12 +944,22 @@ bool ReadFile(const Path &inPath, void *&outData, U32 &outSize, bool inNullTermi
|
|||
if ( inNullTerminate )
|
||||
{
|
||||
outData = new char [outSize+1];
|
||||
if( !outData )
|
||||
{
|
||||
// out of memory
|
||||
return false;
|
||||
}
|
||||
sizeRead = fileR->read(outData, outSize);
|
||||
static_cast<char *>(outData)[outSize] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
outData = new char [outSize];
|
||||
if( !outData )
|
||||
{
|
||||
// out of memory
|
||||
return false;
|
||||
}
|
||||
sizeRead = fileR->read(outData, outSize);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ bool BasicClouds::onAdd()
|
|||
mTexScaleSC = mShader->getShaderConstHandle( "$texScale" );
|
||||
mTexDirectionSC = mShader->getShaderConstHandle( "$texDirection" );
|
||||
mTexOffsetSC = mShader->getShaderConstHandle( "$texOffset" );
|
||||
mDiffuseMapSC = mShader->getShaderConstHandle( "$diffuseMap" );
|
||||
|
||||
// Create StateBlocks
|
||||
GFXStateBlockDesc desc;
|
||||
|
|
@ -312,7 +313,7 @@ void BasicClouds::renderObject( ObjectRenderInst *ri, SceneRenderState *state, B
|
|||
mShaderConsts->setSafe( mTexDirectionSC, mTexDirection[i] * mTexSpeed[i] );
|
||||
mShaderConsts->setSafe( mTexOffsetSC, mTexOffset[i] );
|
||||
|
||||
GFX->setTexture( 0, mTexture[i] );
|
||||
GFX->setTexture( mDiffuseMapSC->getSamplerRegister(), mTexture[i] );
|
||||
GFX->setVertexBuffer( mVB[i] );
|
||||
|
||||
GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, smVertCount, 0, smTriangleCount );
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ protected:
|
|||
GFXShaderConstHandle *mTexScaleSC;
|
||||
GFXShaderConstHandle *mTexDirectionSC;
|
||||
GFXShaderConstHandle *mTexOffsetSC;
|
||||
GFXShaderConstHandle *mDiffuseMapSC;
|
||||
|
||||
GFXVertexBufferHandle<GFXVertexPT> mVB[TEX_COUNT];
|
||||
GFXPrimitiveBufferHandle mPB;
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ bool CloudLayer::onAdd()
|
|||
mCoverageSC = mShader->getShaderConstHandle( "$cloudCoverage" );
|
||||
mExposureSC = mShader->getShaderConstHandle( "$cloudExposure" );
|
||||
mBaseColorSC = mShader->getShaderConstHandle( "$cloudBaseColor" );
|
||||
mNormalHeightMapSC = mShader->getShaderConstHandle( "$normalHeightMap" );
|
||||
|
||||
// Create StateBlocks
|
||||
GFXStateBlockDesc desc;
|
||||
|
|
@ -365,7 +366,7 @@ void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, Ba
|
|||
|
||||
mShaderConsts->setSafe( mExposureSC, mExposure );
|
||||
|
||||
GFX->setTexture( 0, mTexture );
|
||||
GFX->setTexture( mNormalHeightMapSC->getSamplerRegister(), mTexture );
|
||||
GFX->setVertexBuffer( mVB );
|
||||
GFX->setPrimitiveBuffer( mPB );
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ protected:
|
|||
GFXShaderConstHandle *mCoverageSC;
|
||||
GFXShaderConstHandle *mExposureSC;
|
||||
GFXShaderConstHandle *mEyePosWorldSC;
|
||||
GFXShaderConstHandle *mNormalHeightMapSC;
|
||||
|
||||
GFXVertexBufferHandle<GFXCloudVertex> mVB;
|
||||
GFXPrimitiveBufferHandle mPB;
|
||||
|
|
|
|||
|
|
@ -1241,7 +1241,7 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, setNodePosition, void, 3, 3, "" )
|
|||
|
||||
if ( (count != 3) )
|
||||
{
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1268,7 +1268,7 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, setNodeNormal, void, 3, 3, "" )
|
|||
|
||||
if ( (count != 3) )
|
||||
{
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1306,4 +1306,4 @@ ConsoleMethod( GuiMeshRoadEditorCtrl, regenerate, void, 2, 2, "" )
|
|||
ConsoleMethod( GuiMeshRoadEditorCtrl, matchTerrainToRoad, void, 2, 2, "" )
|
||||
{
|
||||
object->matchTerrainToRoad();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,7 @@ ConsoleMethod( GuiRiverEditorCtrl, setNodePosition, void, 3, 3, "" )
|
|||
|
||||
if ( (count != 3) )
|
||||
{
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1475,7 +1475,7 @@ ConsoleMethod( GuiRiverEditorCtrl, setNodeNormal, void, 3, 3, "" )
|
|||
|
||||
if ( (count != 3) )
|
||||
{
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1508,4 +1508,4 @@ ConsoleMethod( GuiRiverEditorCtrl, regenerate, void, 2, 2, "" )
|
|||
River *river = object->getSelectedRiver();
|
||||
if ( river )
|
||||
river->regenerate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1082,7 +1082,7 @@ ConsoleMethod( GuiRoadEditorCtrl, setNodePosition, void, 3, 3, "" )
|
|||
|
||||
if ( (count != 3) )
|
||||
{
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", argv[3]);
|
||||
Con::printf("Failed to parse node information \"px py pz\" from '%s'", (const char*)argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "collision/concretePolyList.h"
|
||||
#include "T3D/physics/physicsPlugin.h"
|
||||
#include "T3D/physics/physicsBody.h"
|
||||
#include "T3D/physics/physicsCollision.h"
|
||||
#include "environment/nodeListManager.h"
|
||||
|
||||
#define MIN_METERS_PER_SEGMENT 1.0f
|
||||
|
|
@ -1722,6 +1723,8 @@ void MeshRoad::_generateSlices()
|
|||
|
||||
void MeshRoad::_generateSegments()
|
||||
{
|
||||
SAFE_DELETE( mPhysicsRep );
|
||||
|
||||
mSegments.clear();
|
||||
|
||||
for ( U32 i = 0; i < mSlices.size() - 1; i++ )
|
||||
|
|
@ -1736,8 +1739,22 @@ void MeshRoad::_generateSegments()
|
|||
|
||||
if ( PHYSICSMGR )
|
||||
{
|
||||
SAFE_DELETE( mPhysicsRep );
|
||||
//mPhysicsRep = PHYSICSMGR->createBody();
|
||||
ConcretePolyList polylist;
|
||||
if ( buildPolyList( PLC_Collision, &polylist, getWorldBox(), getWorldSphere() ) )
|
||||
{
|
||||
polylist.triangulate();
|
||||
|
||||
PhysicsCollision *colShape = PHYSICSMGR->createCollision();
|
||||
colShape->addTriangleMesh( polylist.mVertexList.address(),
|
||||
polylist.mVertexList.size(),
|
||||
polylist.mIndexList.address(),
|
||||
polylist.mIndexList.size() / 3,
|
||||
MatrixF::Identity );
|
||||
|
||||
PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
|
||||
mPhysicsRep = PHYSICSMGR->createBody();
|
||||
mPhysicsRep->init( colShape, 0, 0, this, world );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ void WaterObject::inspectPostApply()
|
|||
setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
|
||||
}
|
||||
|
||||
bool WaterObject::processArguments( S32 argc, const char **argv )
|
||||
bool WaterObject::processArguments( S32 argc, ConsoleValueRef *argv )
|
||||
{
|
||||
if( typeid( *this ) == typeid( WaterObject ) )
|
||||
{
|
||||
|
|
@ -780,7 +780,7 @@ void WaterObject::drawUnderwaterFilter( SceneRenderState *state )
|
|||
GFX->setWorldMatrix( newMat );
|
||||
|
||||
// set up render states
|
||||
GFX->disableShaders();
|
||||
GFX->setupGenericShaders();
|
||||
GFX->setStateBlock( mUnderwaterSB );
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public:
|
|||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual void inspectPostApply();
|
||||
virtual bool processArguments(S32 argc, const char **argv);
|
||||
virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
|
||||
|
||||
// NetObject
|
||||
virtual U32 packUpdate( NetConnection * conn, U32 mask, BitStream *stream );
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ void Forest::saveDataFile( const char *path )
|
|||
|
||||
ConsoleMethod( Forest, saveDataFile, bool, 2, 3, "saveDataFile( [path] )" )
|
||||
{
|
||||
object->saveDataFile( argc == 3 ? argv[2] : NULL );
|
||||
object->saveDataFile( argc == 3 ? (const char*)argv[2] : NULL );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -378,4 +378,4 @@ ConsoleMethod(Forest, regenCells, void, 2, 2, "()")
|
|||
ConsoleMethod(Forest, clear, void, 2, 2, "()" )
|
||||
{
|
||||
object->clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ protected:
|
|||
// }
|
||||
|
||||
virtual GFXShader* createShader();
|
||||
void disableShaders();
|
||||
|
||||
/// Device helper function
|
||||
virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const = 0;
|
||||
|
|
@ -271,7 +272,6 @@ public:
|
|||
|
||||
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
|
||||
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version; }
|
||||
virtual void disableShaders();
|
||||
virtual void setShader( GFXShader *shader );
|
||||
virtual U32 getNumSamplers() const { return mNumSamplers; }
|
||||
virtual U32 getNumRenderTargets() const { return mNumRenderTargets; }
|
||||
|
|
|
|||
|
|
@ -1101,11 +1101,13 @@ void GFXD3D9Shader::_getShaderConstants( ID3DXConstantTable *table,
|
|||
desc.constType = GFXSCT_Sampler;
|
||||
desc.arraySize = constantDesc.RegisterIndex;
|
||||
samplerDescriptions.push_back( desc );
|
||||
mShaderConsts.push_back(desc);
|
||||
break;
|
||||
case D3DXPT_SAMPLERCUBE :
|
||||
desc.constType = GFXSCT_SamplerCube;
|
||||
desc.arraySize = constantDesc.RegisterIndex;
|
||||
samplerDescriptions.push_back( desc );
|
||||
mShaderConsts.push_back(desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1371,7 +1373,7 @@ GFXShaderConstBufferRef GFXD3D9Shader::allocConstBuffer()
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a shader constant handle for name, if the variable doesn't exist NULL is returned.
|
||||
/// Returns a shader constant handle for name
|
||||
GFXShaderConstHandle* GFXD3D9Shader::getShaderConstHandle(const String& name)
|
||||
{
|
||||
HandleMap::Iterator i = mHandles.find(name);
|
||||
|
|
@ -1390,6 +1392,20 @@ GFXShaderConstHandle* GFXD3D9Shader::getShaderConstHandle(const String& name)
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a shader constant handle for name, if the variable doesn't exist NULL is returned.
|
||||
GFXShaderConstHandle* GFXD3D9Shader::findShaderConstHandle(const String& name)
|
||||
{
|
||||
HandleMap::Iterator i = mHandles.find(name);
|
||||
if ( i != mHandles.end() )
|
||||
{
|
||||
return i->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const Vector<GFXShaderConstDesc>& GFXD3D9Shader::getShaderConstDesc() const
|
||||
{
|
||||
return mShaderConsts;
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ public:
|
|||
virtual GFXShaderConstBufferRef allocConstBuffer();
|
||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
|
||||
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
|
||||
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
|
||||
virtual bool getDisassembly( String &outStr ) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ bool GFXD3D9TextureManager::_loadTexture( GFXTextureObject *inTex, void *raw )
|
|||
break;
|
||||
case GFXFormatR8G8B8A8:
|
||||
case GFXFormatR8G8B8X8:
|
||||
case GFXFormatB8G8R8A8:
|
||||
bytesPerPix = 4;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,8 +205,8 @@ bool GFXD3D9TextureObject::copyToBmp(GBitmap* bmp)
|
|||
// check format limitations
|
||||
// at the moment we only support RGBA for the source (other 4 byte formats should
|
||||
// be easy to add though)
|
||||
AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
|
||||
if (mFormat != GFXFormatR8G8B8A8)
|
||||
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8, "copyToBmp: invalid format");
|
||||
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8)
|
||||
return false;
|
||||
|
||||
PROFILE_START(GFXD3D9TextureObject_copyToBmp);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ void GFXD3D9EnumTranslate::init()
|
|||
GFXD3D9TextureFormat[GFXFormatR8G8B8] = D3DFMT_R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR8G8B8A8] = D3DFMT_A8R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR8G8B8X8] = D3DFMT_X8R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatB8G8R8A8] = D3DFMT_A8R8G8B8;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G6B5] = D3DFMT_R5G6B5;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G5B5A1] = D3DFMT_A1R5G5B5;
|
||||
GFXD3D9TextureFormat[GFXFormatR5G5B5X1] = D3DFMT_X1R5G5B5;
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ GFXDevice::~GFXDevice()
|
|||
mNewCubemap[i] = NULL;
|
||||
}
|
||||
|
||||
mCurrentRT = NULL;
|
||||
|
||||
// Release all the unreferenced textures in the cache.
|
||||
mTextureManager->cleanupCache();
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue