mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Merge branch 'development' of https://github.com/TorqueGameEngines/Torque3D into Enumnanigans
This commit is contained in:
commit
72c67e196a
394 changed files with 49666 additions and 46898 deletions
|
|
@ -51,7 +51,7 @@ torqueAddSourceDirectories("app" "app/net")
|
|||
# Handle console
|
||||
torqueAddSourceDirectories("console")
|
||||
torqueAddSourceDirectories("console/torquescript")
|
||||
|
||||
set(TORQUE_INCLUDE_DIRECTORIES ${TORQUE_INCLUDE_DIRECTORIES} "ts/vhacd")
|
||||
# Handle Platform
|
||||
torqueAddSourceDirectories("platform" "platform/threads" "platform/async"
|
||||
"platform/input" "platform/output")
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ class ParticleEmitter : public GameBase
|
|||
void addParticle(const Point3F &pos, const Point3F &axis, const Point3F &vel, const Point3F &axisx, const U32 age_offset);
|
||||
|
||||
|
||||
inline void setupBillboard( Particle *part,
|
||||
void setupBillboard( Particle *part,
|
||||
Point3F *basePts,
|
||||
const MatrixF &camView,
|
||||
const LinearColorF &ambientColor,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct Move
|
|||
bool trigger[MaxTriggerKeys];
|
||||
|
||||
Move();
|
||||
|
||||
virtual ~Move() {};
|
||||
virtual void pack(BitStream *stream, const Move * move = NULL);
|
||||
virtual void unpack(BitStream *stream, const Move * move = NULL);
|
||||
virtual void clamp();
|
||||
|
|
|
|||
|
|
@ -272,37 +272,35 @@ void GroundPlane::buildConvex( const Box3F& box, Convex* convex )
|
|||
return;
|
||||
|
||||
// See if we already have a convex in the working set.
|
||||
BoxConvex *boxConvex = NULL;
|
||||
PlaneConvex *planeConvex = NULL;
|
||||
CollisionWorkingList &wl = convex->getWorkingList();
|
||||
CollisionWorkingList *itr = wl.wLink.mNext;
|
||||
for ( ; itr != &wl; itr = itr->wLink.mNext )
|
||||
{
|
||||
if ( itr->mConvex->getType() == BoxConvexType &&
|
||||
if ( itr->mConvex->getType() == PlaneConvexType &&
|
||||
itr->mConvex->getObject() == this )
|
||||
{
|
||||
boxConvex = (BoxConvex*)itr->mConvex;
|
||||
planeConvex = (PlaneConvex*)itr->mConvex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !boxConvex )
|
||||
if ( !planeConvex)
|
||||
{
|
||||
boxConvex = new BoxConvex;
|
||||
mConvexList->registerObject( boxConvex );
|
||||
boxConvex->init( this );
|
||||
planeConvex = new PlaneConvex;
|
||||
mConvexList->registerObject(planeConvex);
|
||||
planeConvex->init( this );
|
||||
|
||||
convex->addToWorkingList( boxConvex );
|
||||
convex->addToWorkingList(planeConvex);
|
||||
}
|
||||
|
||||
// Update our convex to best match the queried box
|
||||
if ( boxConvex )
|
||||
if (planeConvex)
|
||||
{
|
||||
Point3F queryCenter = box.getCenter();
|
||||
|
||||
boxConvex->mCenter = Point3F( queryCenter.x, queryCenter.y, -GROUND_PLANE_BOX_HEIGHT_HALF );
|
||||
boxConvex->mSize = Point3F( box.getExtents().x,
|
||||
box.getExtents().y,
|
||||
GROUND_PLANE_BOX_HEIGHT_HALF );
|
||||
planeConvex->mCenter = Point3F( queryCenter.x, queryCenter.y, 0 );
|
||||
planeConvex->mSize = Point3F( box.getExtents().x, box.getExtents().y, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4014,9 +4014,9 @@ void Player::updateActionThread()
|
|||
mActionAnimation.callbackTripped = true;
|
||||
}
|
||||
|
||||
if ((mActionAnimation.action == PlayerData::NullAnimation) ||
|
||||
((!mActionAnimation.waitForEnd || mActionAnimation.atEnd) &&
|
||||
(!mActionAnimation.holdAtEnd && (mActionAnimation.delayTicks -= !mMountPending) <= 0)))
|
||||
if (mActionAnimation.action == PlayerData::NullAnimation || !mActionAnimation.waitForEnd || //either no animation or not waiting till the end
|
||||
((mActionAnimation.atEnd && !mActionAnimation.holdAtEnd) && //or not holding that state and
|
||||
(mActionAnimation.delayTicks -= mMountPending) <= 0)) //not waiting to mount
|
||||
{
|
||||
pickActionAnimation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -495,6 +495,9 @@ void ProximityMine::processTick( const Move* move )
|
|||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// just break out, unknown state, covers warnings for not fulfilling all possiblities in enum.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,8 +407,9 @@ U32 SFXEmitter::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
|||
stream->writeAffineTransform(mObjToWorld);
|
||||
|
||||
// track
|
||||
if (stream->writeFlag(mask & DirtyUpdateMask))
|
||||
if (stream->writeFlag(mask & DirtyUpdateMask)){
|
||||
PACK_ASSET(con, Sound);
|
||||
}
|
||||
//if (stream->writeFlag(mDirty.test(Track)))
|
||||
// sfxWrite( stream, mTrack );
|
||||
|
||||
|
|
|
|||
|
|
@ -215,3 +215,100 @@ const MatrixF& OrthoBoxConvex::getTransform() const
|
|||
return mOrthoMatrixCache;
|
||||
}
|
||||
|
||||
Point3F PlaneConvex::getVertex(S32 v)
|
||||
{
|
||||
Point3F p = mCenter;
|
||||
p.x += (v & 1) ? mSize.x : -mSize.x;
|
||||
p.y += (v & 2) ? mSize.y : -mSize.y;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void PlaneConvex::emitEdge(S32 v1, S32 v2, const MatrixF& mat, ConvexFeature* cf)
|
||||
{
|
||||
S32 vc = cf->mVertexList.size();
|
||||
cf->mVertexList.increment(2);
|
||||
Point3F* vp = cf->mVertexList.begin();
|
||||
mat.mulP(getVertex(v1), &vp[vc]);
|
||||
mat.mulP(getVertex(v2), &vp[vc + 1]);
|
||||
|
||||
cf->mEdgeList.increment();
|
||||
ConvexFeature::Edge& edge = cf->mEdgeList.last();
|
||||
edge.vertex[0] = vc;
|
||||
edge.vertex[1] = vc + 1;
|
||||
}
|
||||
|
||||
void PlaneConvex::emitFace(const MatrixF& mat, ConvexFeature* cf) {
|
||||
// Assuming sFace contains a single face definition for the plane
|
||||
Face& face = sFace[4];
|
||||
|
||||
// Emit vertices
|
||||
S32 vc = cf->mVertexList.size();
|
||||
cf->mVertexList.increment(4);
|
||||
Point3F* vp = cf->mVertexList.begin();
|
||||
for (S32 v = 0; v < 4; v++) {
|
||||
mat.mulP(getVertex(face.vertex[v]), &vp[vc + v]);
|
||||
}
|
||||
|
||||
// Emit edges
|
||||
cf->mEdgeList.increment(4);
|
||||
ConvexFeature::Edge* edge = cf->mEdgeList.end() - 4;
|
||||
for (S32 e = 0; e < 4; e++) {
|
||||
edge[e].vertex[0] = vc + e;
|
||||
edge[e].vertex[1] = vc + ((e + 1) & 3);
|
||||
}
|
||||
|
||||
// Emit 2 triangle faces
|
||||
cf->mFaceList.increment(2);
|
||||
ConvexFeature::Face* ef = cf->mFaceList.end() - 2;
|
||||
mat.getColumn(face.axis, &ef->normal);
|
||||
ef[1].normal = ef[0].normal;
|
||||
ef[1].vertex[0] = ef[0].vertex[0] = vc;
|
||||
ef[1].vertex[1] = ef[0].vertex[2] = vc + 2;
|
||||
ef[0].vertex[1] = vc + 1;
|
||||
ef[1].vertex[2] = vc + 3;
|
||||
}
|
||||
|
||||
Point3F PlaneConvex::support(const VectorF& v) const {
|
||||
Point3F p = mCenter;
|
||||
p.x += (v.x >= 0) ? mSize.x : -mSize.x;
|
||||
p.y += (v.y >= 0) ? mSize.y : -mSize.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
void PlaneConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf)
|
||||
{
|
||||
cf->material = 0;
|
||||
cf->mObject = mObject;
|
||||
|
||||
// Emit edges
|
||||
for (S32 i = 0; i < 4; ++i) {
|
||||
S32 next = (i + 1) % 4;
|
||||
emitEdge(i, next, mat, cf);
|
||||
}
|
||||
|
||||
emitFace(mat, cf);
|
||||
}
|
||||
|
||||
void PlaneConvex::getPolyList(AbstractPolyList* list)
|
||||
{
|
||||
list->setTransform(&getTransform(), getScale());
|
||||
list->setObject(getObject());
|
||||
|
||||
U32 base = list->addPoint(mCenter + Point3F(-mSize.x, -mSize.y, -mSize.z));
|
||||
list->addPoint(mCenter + Point3F(mSize.x, -mSize.y, -mSize.z));
|
||||
list->addPoint(mCenter + Point3F(-mSize.x, mSize.y, -mSize.z));
|
||||
list->addPoint(mCenter + Point3F(mSize.x, mSize.y, -mSize.z));
|
||||
|
||||
list->begin(0, 0);
|
||||
|
||||
list->vertex(base + sFace[4].vertex[3]);
|
||||
list->vertex(base + sFace[4].vertex[2]);
|
||||
list->vertex(base + sFace[4].vertex[1]);
|
||||
list->vertex(base + sFace[4].vertex[0]);
|
||||
|
||||
list->plane(base + sFace[4].vertex[2],
|
||||
base + sFace[4].vertex[1],
|
||||
base + sFace[4].vertex[0]);
|
||||
list->end();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,16 +48,32 @@ public:
|
|||
void getPolyList(AbstractPolyList* list) override;
|
||||
};
|
||||
|
||||
|
||||
class OrthoBoxConvex: public BoxConvex
|
||||
class OrthoBoxConvex : public BoxConvex
|
||||
{
|
||||
typedef BoxConvex Parent;
|
||||
mutable MatrixF mOrthoMatrixCache;
|
||||
|
||||
public:
|
||||
public:
|
||||
OrthoBoxConvex() { mOrthoMatrixCache.identity(); }
|
||||
|
||||
const MatrixF& getTransform() const override;
|
||||
};
|
||||
|
||||
class PlaneConvex : public Convex
|
||||
{
|
||||
Point3F getVertex(S32 v);
|
||||
void emitEdge(S32 v1, S32 v2, const MatrixF& mat, ConvexFeature* cf);
|
||||
void emitFace(const MatrixF& mat, ConvexFeature* cf);
|
||||
public:
|
||||
Point3F mCenter;
|
||||
VectorF mSize;
|
||||
|
||||
PlaneConvex() { mType = PlaneConvexType; }
|
||||
void init(SceneObject* obj) { mObject = obj; }
|
||||
|
||||
Point3F support(const VectorF& v) const override;
|
||||
void getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf) override;
|
||||
void getPolyList(AbstractPolyList* list) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -150,13 +150,13 @@ void ConcretePolyList::render()
|
|||
GFXStateBlockRef sb = GFX->createStateBlock( solidZDisable );
|
||||
GFX->setStateBlock( sb );
|
||||
|
||||
PrimBuild::color3i( 255, 0, 255 );
|
||||
|
||||
Poly *p;
|
||||
Point3F *pnt;
|
||||
|
||||
for ( p = mPolyList.begin(); p < mPolyList.end(); p++ )
|
||||
{
|
||||
PrimBuild::color3i(255, 0, 255);
|
||||
|
||||
PrimBuild::begin( GFXLineStrip, p->vertexCount + 1 );
|
||||
|
||||
for ( U32 i = 0; i < p->vertexCount; i++ )
|
||||
|
|
@ -169,6 +169,31 @@ void ConcretePolyList::render()
|
|||
PrimBuild::vertex3fv( pnt );
|
||||
|
||||
PrimBuild::end();
|
||||
|
||||
// Calculate the center of the polygon
|
||||
Point3F centroid(0, 0, 0);
|
||||
for (U32 i = 0; i < p->vertexCount; i++)
|
||||
{
|
||||
pnt = &mVertexList[mIndexList[p->vertexStart + i]];
|
||||
centroid += *pnt;
|
||||
}
|
||||
centroid /= p->vertexCount;
|
||||
|
||||
// Calculate the end point of the normal line
|
||||
Point3F norm = p->plane.getNormal();
|
||||
|
||||
U8 red = static_cast<U8>((norm.x + 1.0f) * 0.5f * 255);
|
||||
U8 green = static_cast<U8>((norm.y + 1.0f) * 0.5f * 255);
|
||||
U8 blue = static_cast<U8>((norm.z + 1.0f) * 0.5f * 255);
|
||||
|
||||
PrimBuild::color3i(red, green, blue);
|
||||
Point3F normalEnd = centroid + norm;
|
||||
|
||||
// Draw the normal line
|
||||
PrimBuild::begin(GFXLineList, 2);
|
||||
PrimBuild::vertex3fv(centroid);
|
||||
PrimBuild::vertex3fv(normalEnd);
|
||||
PrimBuild::end();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,4 +245,4 @@ void ConcretePolyList::triangulate()
|
|||
|
||||
mPolyList = polyList;
|
||||
mIndexList = indexList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ enum ConvexType {
|
|||
TSPolysoupConvexType,
|
||||
MeshRoadConvexType,
|
||||
ConvexShapeCollisionConvexType,
|
||||
ForestConvexType
|
||||
ForestConvexType,
|
||||
PlaneConvexType
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ public:
|
|||
return s == StringTable->EmptyString() ? 0 : dAtoi(s);
|
||||
if (type == ConsoleValueType::cvString)
|
||||
return dStrcmp(s, "") == 0 ? 0 : dAtoi(s);
|
||||
|
||||
return dAtoi(getConsoleData());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2806,11 +2806,11 @@ DefineEngineFunction(getTimestamp, const char*, (), ,
|
|||
#ifdef TORQUE_TOOLS
|
||||
DefineEngineFunction(systemCommand, S32, (const char* commandLineAction, const char* callBackFunction), (""), "")
|
||||
{
|
||||
if (commandLineAction != "")
|
||||
if (commandLineAction && commandLineAction[0] != '\0')
|
||||
{
|
||||
S32 result = system(commandLineAction);
|
||||
|
||||
if (callBackFunction != "" && callBackFunction[0])
|
||||
if (callBackFunction && callBackFunction[0] != '\0')
|
||||
{
|
||||
if (Con::isFunction(callBackFunction))
|
||||
Con::executef(callBackFunction, result);
|
||||
|
|
|
|||
|
|
@ -553,7 +553,7 @@ static void exportScope(const EngineExportScope* scope, SimXMLDocument* xml, boo
|
|||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(true, "Unknown EngineExportKind: " + exportInfo->getExportKind());
|
||||
AssertFatal(false, avar("Unknown EngineExportKind: %d", exportInfo->getExportKind()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace Con
|
|||
{
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, &string);
|
||||
va_start(args, string);
|
||||
dVsprintf(buffer, sizeof(buffer), string, args);
|
||||
va_end(args);
|
||||
|
||||
|
|
|
|||
|
|
@ -1301,7 +1301,8 @@ case 5:
|
|||
/* rule 5 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 120 "CMDscan.l"
|
||||
{ yycolumn = 1;
|
||||
{
|
||||
yycolumn = 1;
|
||||
lines.push_back(String::ToString("%s", yytext+1));
|
||||
if (lines.size() > Con::getIntVariable("$scriptErrorLineCount", 10))
|
||||
lines.erase(lines.begin());
|
||||
|
|
@ -1311,162 +1312,162 @@ YY_RULE_SETUP
|
|||
YY_BREAK
|
||||
case 6:
|
||||
YY_RULE_SETUP
|
||||
#line 127 "CMDscan.l"
|
||||
#line 128 "CMDscan.l"
|
||||
{ return(Sc_ScanString(STRATOM)); }
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 128 "CMDscan.l"
|
||||
#line 129 "CMDscan.l"
|
||||
{ return(Sc_ScanString(TAGATOM)); }
|
||||
YY_BREAK
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 129 "CMDscan.l"
|
||||
#line 130 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opEQ, yylineno ); return opEQ; }
|
||||
YY_BREAK
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 130 "CMDscan.l"
|
||||
#line 131 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opNE, yylineno ); return opNE; }
|
||||
YY_BREAK
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 131 "CMDscan.l"
|
||||
#line 132 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opGE, yylineno ); return opGE; }
|
||||
YY_BREAK
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 132 "CMDscan.l"
|
||||
#line 133 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opLE, yylineno ); return opLE; }
|
||||
YY_BREAK
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 133 "CMDscan.l"
|
||||
#line 134 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opAND, yylineno ); return opAND; }
|
||||
YY_BREAK
|
||||
case 13:
|
||||
YY_RULE_SETUP
|
||||
#line 134 "CMDscan.l"
|
||||
#line 135 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opOR, yylineno ); return opOR; }
|
||||
YY_BREAK
|
||||
case 14:
|
||||
YY_RULE_SETUP
|
||||
#line 135 "CMDscan.l"
|
||||
#line 136 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opCOLONCOLON, yylineno ); return opCOLONCOLON; }
|
||||
YY_BREAK
|
||||
case 15:
|
||||
YY_RULE_SETUP
|
||||
#line 136 "CMDscan.l"
|
||||
#line 137 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMINUSMINUS, yylineno ); return opMINUSMINUS; }
|
||||
YY_BREAK
|
||||
case 16:
|
||||
YY_RULE_SETUP
|
||||
#line 137 "CMDscan.l"
|
||||
#line 138 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opPLUSPLUS, yylineno ); return opPLUSPLUS; }
|
||||
YY_BREAK
|
||||
case 17:
|
||||
YY_RULE_SETUP
|
||||
#line 138 "CMDscan.l"
|
||||
#line 139 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSTREQ, yylineno ); return opSTREQ; }
|
||||
YY_BREAK
|
||||
case 18:
|
||||
YY_RULE_SETUP
|
||||
#line 139 "CMDscan.l"
|
||||
#line 140 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSTRNE, yylineno ); return opSTRNE; }
|
||||
YY_BREAK
|
||||
case 19:
|
||||
YY_RULE_SETUP
|
||||
#line 140 "CMDscan.l"
|
||||
#line 141 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSHL, yylineno ); return opSHL; }
|
||||
YY_BREAK
|
||||
case 20:
|
||||
YY_RULE_SETUP
|
||||
#line 141 "CMDscan.l"
|
||||
#line 142 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSHR, yylineno ); return opSHR; }
|
||||
YY_BREAK
|
||||
case 21:
|
||||
YY_RULE_SETUP
|
||||
#line 142 "CMDscan.l"
|
||||
#line 143 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opPLASN, yylineno ); return opPLASN; }
|
||||
YY_BREAK
|
||||
case 22:
|
||||
YY_RULE_SETUP
|
||||
#line 143 "CMDscan.l"
|
||||
#line 144 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMIASN, yylineno ); return opMIASN; }
|
||||
YY_BREAK
|
||||
case 23:
|
||||
YY_RULE_SETUP
|
||||
#line 144 "CMDscan.l"
|
||||
#line 145 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMLASN, yylineno ); return opMLASN; }
|
||||
YY_BREAK
|
||||
case 24:
|
||||
YY_RULE_SETUP
|
||||
#line 145 "CMDscan.l"
|
||||
#line 146 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opDVASN, yylineno ); return opDVASN; }
|
||||
YY_BREAK
|
||||
case 25:
|
||||
YY_RULE_SETUP
|
||||
#line 146 "CMDscan.l"
|
||||
#line 147 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMODASN, yylineno ); return opMODASN; }
|
||||
YY_BREAK
|
||||
case 26:
|
||||
YY_RULE_SETUP
|
||||
#line 147 "CMDscan.l"
|
||||
#line 148 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opANDASN, yylineno ); return opANDASN; }
|
||||
YY_BREAK
|
||||
case 27:
|
||||
YY_RULE_SETUP
|
||||
#line 148 "CMDscan.l"
|
||||
#line 149 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opXORASN, yylineno ); return opXORASN; }
|
||||
YY_BREAK
|
||||
case 28:
|
||||
YY_RULE_SETUP
|
||||
#line 149 "CMDscan.l"
|
||||
#line 150 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opORASN, yylineno ); return opORASN; }
|
||||
YY_BREAK
|
||||
case 29:
|
||||
YY_RULE_SETUP
|
||||
#line 150 "CMDscan.l"
|
||||
#line 151 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSLASN, yylineno ); return opSLASN; }
|
||||
YY_BREAK
|
||||
case 30:
|
||||
YY_RULE_SETUP
|
||||
#line 151 "CMDscan.l"
|
||||
#line 152 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSRASN, yylineno ); return opSRASN; }
|
||||
YY_BREAK
|
||||
case 31:
|
||||
YY_RULE_SETUP
|
||||
#line 152 "CMDscan.l"
|
||||
#line 153 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opINTNAME, yylineno ); return opINTNAME; }
|
||||
YY_BREAK
|
||||
case 32:
|
||||
YY_RULE_SETUP
|
||||
#line 153 "CMDscan.l"
|
||||
#line 154 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opINTNAMER, yylineno ); return opINTNAMER; }
|
||||
YY_BREAK
|
||||
case 33:
|
||||
YY_RULE_SETUP
|
||||
#line 154 "CMDscan.l"
|
||||
#line 155 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( '\n', yylineno ); return '@'; }
|
||||
YY_BREAK
|
||||
case 34:
|
||||
YY_RULE_SETUP
|
||||
#line 155 "CMDscan.l"
|
||||
#line 156 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( '\t', yylineno ); return '@'; }
|
||||
YY_BREAK
|
||||
case 35:
|
||||
YY_RULE_SETUP
|
||||
#line 156 "CMDscan.l"
|
||||
#line 157 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( ' ', yylineno ); return '@'; }
|
||||
YY_BREAK
|
||||
case 36:
|
||||
YY_RULE_SETUP
|
||||
#line 157 "CMDscan.l"
|
||||
#line 158 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 0, yylineno ); return '@'; }
|
||||
YY_BREAK
|
||||
case 37:
|
||||
YY_RULE_SETUP
|
||||
#line 158 "CMDscan.l"
|
||||
#line 159 "CMDscan.l"
|
||||
{ /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */
|
||||
int c = 0, l;
|
||||
for ( ; ; )
|
||||
|
|
@ -1488,222 +1489,222 @@ YY_RULE_SETUP
|
|||
}
|
||||
YY_BREAK
|
||||
case 38:
|
||||
#line 178 "CMDscan.l"
|
||||
case 39:
|
||||
#line 179 "CMDscan.l"
|
||||
case 40:
|
||||
case 39:
|
||||
#line 180 "CMDscan.l"
|
||||
case 41:
|
||||
case 40:
|
||||
#line 181 "CMDscan.l"
|
||||
case 42:
|
||||
case 41:
|
||||
#line 182 "CMDscan.l"
|
||||
case 43:
|
||||
case 42:
|
||||
#line 183 "CMDscan.l"
|
||||
case 44:
|
||||
case 43:
|
||||
#line 184 "CMDscan.l"
|
||||
case 45:
|
||||
case 44:
|
||||
#line 185 "CMDscan.l"
|
||||
case 46:
|
||||
case 45:
|
||||
#line 186 "CMDscan.l"
|
||||
case 47:
|
||||
case 46:
|
||||
#line 187 "CMDscan.l"
|
||||
case 48:
|
||||
case 47:
|
||||
#line 188 "CMDscan.l"
|
||||
case 49:
|
||||
case 48:
|
||||
#line 189 "CMDscan.l"
|
||||
case 50:
|
||||
case 49:
|
||||
#line 190 "CMDscan.l"
|
||||
case 51:
|
||||
case 50:
|
||||
#line 191 "CMDscan.l"
|
||||
case 52:
|
||||
case 51:
|
||||
#line 192 "CMDscan.l"
|
||||
case 53:
|
||||
case 52:
|
||||
#line 193 "CMDscan.l"
|
||||
case 54:
|
||||
case 53:
|
||||
#line 194 "CMDscan.l"
|
||||
case 55:
|
||||
case 54:
|
||||
#line 195 "CMDscan.l"
|
||||
case 56:
|
||||
case 55:
|
||||
#line 196 "CMDscan.l"
|
||||
case 57:
|
||||
case 56:
|
||||
#line 197 "CMDscan.l"
|
||||
case 58:
|
||||
case 57:
|
||||
#line 198 "CMDscan.l"
|
||||
case 59:
|
||||
case 58:
|
||||
#line 199 "CMDscan.l"
|
||||
case 60:
|
||||
case 59:
|
||||
#line 200 "CMDscan.l"
|
||||
case 60:
|
||||
#line 201 "CMDscan.l"
|
||||
case 61:
|
||||
YY_RULE_SETUP
|
||||
#line 200 "CMDscan.l"
|
||||
#line 201 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( CMDtext[ 0 ], yylineno ); return CMDtext[ 0 ]; }
|
||||
YY_BREAK
|
||||
case 62:
|
||||
YY_RULE_SETUP
|
||||
#line 201 "CMDscan.l"
|
||||
#line 202 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwIN, yylineno ); return(rwIN); }
|
||||
YY_BREAK
|
||||
case 63:
|
||||
YY_RULE_SETUP
|
||||
#line 202 "CMDscan.l"
|
||||
#line 203 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCASEOR, yylineno ); return(rwCASEOR); }
|
||||
YY_BREAK
|
||||
case 64:
|
||||
YY_RULE_SETUP
|
||||
#line 203 "CMDscan.l"
|
||||
#line 204 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwBREAK, yylineno ); return(rwBREAK); }
|
||||
YY_BREAK
|
||||
case 65:
|
||||
YY_RULE_SETUP
|
||||
#line 204 "CMDscan.l"
|
||||
#line 205 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwRETURN, yylineno ); return(rwRETURN); }
|
||||
YY_BREAK
|
||||
case 66:
|
||||
YY_RULE_SETUP
|
||||
#line 205 "CMDscan.l"
|
||||
#line 206 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwELSE, yylineno ); return(rwELSE); }
|
||||
YY_BREAK
|
||||
case 67:
|
||||
YY_RULE_SETUP
|
||||
#line 206 "CMDscan.l"
|
||||
#line 207 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwASSERT, yylineno ); return(rwASSERT); }
|
||||
YY_BREAK
|
||||
case 68:
|
||||
YY_RULE_SETUP
|
||||
#line 207 "CMDscan.l"
|
||||
#line 208 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwWHILE, yylineno ); return(rwWHILE); }
|
||||
YY_BREAK
|
||||
case 69:
|
||||
YY_RULE_SETUP
|
||||
#line 208 "CMDscan.l"
|
||||
#line 209 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDO, yylineno ); return(rwDO); }
|
||||
YY_BREAK
|
||||
case 70:
|
||||
YY_RULE_SETUP
|
||||
#line 209 "CMDscan.l"
|
||||
#line 210 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwIF, yylineno ); return(rwIF); }
|
||||
YY_BREAK
|
||||
case 71:
|
||||
YY_RULE_SETUP
|
||||
#line 210 "CMDscan.l"
|
||||
#line 211 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOREACHSTR, yylineno ); return(rwFOREACHSTR); }
|
||||
YY_BREAK
|
||||
case 72:
|
||||
YY_RULE_SETUP
|
||||
#line 211 "CMDscan.l"
|
||||
#line 212 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOREACH, yylineno ); return(rwFOREACH); }
|
||||
YY_BREAK
|
||||
case 73:
|
||||
YY_RULE_SETUP
|
||||
#line 212 "CMDscan.l"
|
||||
#line 213 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOR, yylineno ); return(rwFOR); }
|
||||
YY_BREAK
|
||||
case 74:
|
||||
YY_RULE_SETUP
|
||||
#line 213 "CMDscan.l"
|
||||
#line 214 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCONTINUE, yylineno ); return(rwCONTINUE); }
|
||||
YY_BREAK
|
||||
case 75:
|
||||
YY_RULE_SETUP
|
||||
#line 214 "CMDscan.l"
|
||||
#line 215 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDEFINE, yylineno ); return(rwDEFINE); }
|
||||
YY_BREAK
|
||||
case 76:
|
||||
YY_RULE_SETUP
|
||||
#line 215 "CMDscan.l"
|
||||
#line 216 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDECLARE, yylineno ); return(rwDECLARE); }
|
||||
YY_BREAK
|
||||
case 77:
|
||||
YY_RULE_SETUP
|
||||
#line 216 "CMDscan.l"
|
||||
#line 217 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, yylineno ); return(rwDECLARESINGLETON); }
|
||||
YY_BREAK
|
||||
case 78:
|
||||
YY_RULE_SETUP
|
||||
#line 217 "CMDscan.l"
|
||||
#line 218 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDATABLOCK, yylineno ); return(rwDATABLOCK); }
|
||||
YY_BREAK
|
||||
case 79:
|
||||
YY_RULE_SETUP
|
||||
#line 218 "CMDscan.l"
|
||||
#line 219 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCASE, yylineno ); return(rwCASE); }
|
||||
YY_BREAK
|
||||
case 80:
|
||||
YY_RULE_SETUP
|
||||
#line 219 "CMDscan.l"
|
||||
#line 220 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwSWITCHSTR, yylineno ); return(rwSWITCHSTR); }
|
||||
YY_BREAK
|
||||
case 81:
|
||||
YY_RULE_SETUP
|
||||
#line 220 "CMDscan.l"
|
||||
#line 221 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwSWITCH, yylineno ); return(rwSWITCH); }
|
||||
YY_BREAK
|
||||
case 82:
|
||||
YY_RULE_SETUP
|
||||
#line 221 "CMDscan.l"
|
||||
#line 222 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDEFAULT, yylineno ); return(rwDEFAULT); }
|
||||
YY_BREAK
|
||||
case 83:
|
||||
YY_RULE_SETUP
|
||||
#line 222 "CMDscan.l"
|
||||
#line 223 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwPACKAGE, yylineno ); return(rwPACKAGE); }
|
||||
YY_BREAK
|
||||
case 84:
|
||||
YY_RULE_SETUP
|
||||
#line 223 "CMDscan.l"
|
||||
#line 224 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwNAMESPACE, yylineno ); return(rwNAMESPACE); }
|
||||
YY_BREAK
|
||||
case 85:
|
||||
YY_RULE_SETUP
|
||||
#line 224 "CMDscan.l"
|
||||
#line 225 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 1, yylineno ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 86:
|
||||
YY_RULE_SETUP
|
||||
#line 225 "CMDscan.l"
|
||||
#line 226 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 0, yylineno ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 87:
|
||||
YY_RULE_SETUP
|
||||
#line 226 "CMDscan.l"
|
||||
#line 227 "CMDscan.l"
|
||||
{ return(Sc_ScanVar()); }
|
||||
YY_BREAK
|
||||
case 88:
|
||||
YY_RULE_SETUP
|
||||
#line 228 "CMDscan.l"
|
||||
#line 229 "CMDscan.l"
|
||||
{ return Sc_ScanIdent(); }
|
||||
YY_BREAK
|
||||
case 89:
|
||||
YY_RULE_SETUP
|
||||
#line 229 "CMDscan.l"
|
||||
#line 230 "CMDscan.l"
|
||||
return(Sc_ScanHex());
|
||||
YY_BREAK
|
||||
case 90:
|
||||
YY_RULE_SETUP
|
||||
#line 230 "CMDscan.l"
|
||||
#line 231 "CMDscan.l"
|
||||
{ CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), yylineno ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 91:
|
||||
YY_RULE_SETUP
|
||||
#line 231 "CMDscan.l"
|
||||
#line 232 "CMDscan.l"
|
||||
return Sc_ScanNum();
|
||||
YY_BREAK
|
||||
case 92:
|
||||
YY_RULE_SETUP
|
||||
#line 232 "CMDscan.l"
|
||||
#line 233 "CMDscan.l"
|
||||
return(ILLEGAL_TOKEN);
|
||||
YY_BREAK
|
||||
case 93:
|
||||
YY_RULE_SETUP
|
||||
#line 233 "CMDscan.l"
|
||||
#line 234 "CMDscan.l"
|
||||
return(ILLEGAL_TOKEN);
|
||||
YY_BREAK
|
||||
case 94:
|
||||
YY_RULE_SETUP
|
||||
#line 234 "CMDscan.l"
|
||||
#line 235 "CMDscan.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 1706 "CMDscan.cpp"
|
||||
#line 1707 "CMDscan.cpp"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
yyterminate();
|
||||
|
||||
|
|
@ -2679,7 +2680,7 @@ void yyfree (void * ptr )
|
|||
|
||||
#define YYTABLES_NAME "yytables"
|
||||
|
||||
#line 234 "CMDscan.l"
|
||||
#line 235 "CMDscan.l"
|
||||
|
||||
|
||||
static const char *scanBuffer;
|
||||
|
|
@ -2741,6 +2742,8 @@ void CMDSetScanBuffer(const char *sb, const char *fn)
|
|||
scanBuffer = sb;
|
||||
fileName = fn;
|
||||
scanIndex = 0;
|
||||
yylineno = 1;
|
||||
lines.clear();
|
||||
}
|
||||
|
||||
int CMDgetc()
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ HEXDIGIT [a-fA-F0-9]
|
|||
("///"([^/\n\r][^\n\r]*)?[\n\r]+)+ { return(Sc_ScanDocBlock()); }
|
||||
"//"[^\n\r]* ;
|
||||
[\r] ;
|
||||
\n.* { yycolumn = 1;
|
||||
\n.* {
|
||||
yycolumn = 1;
|
||||
lines.push_back(String::ToString("%s", yytext+1));
|
||||
if (lines.size() > Con::getIntVariable("$scriptErrorLineCount", 10))
|
||||
lines.erase(lines.begin());
|
||||
|
|
@ -291,6 +292,8 @@ void CMDSetScanBuffer(const char *sb, const char *fn)
|
|||
scanBuffer = sb;
|
||||
fileName = fn;
|
||||
scanIndex = 0;
|
||||
yylineno = 1;
|
||||
lines.clear();
|
||||
}
|
||||
|
||||
int CMDgetc()
|
||||
|
|
|
|||
|
|
@ -200,7 +200,9 @@ U32 IfStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
|
|||
U32 endifIp, elseIp;
|
||||
addBreakLine(codeStream);
|
||||
|
||||
if (testExpr->getPreferredType() == TypeReqUInt)
|
||||
TypeReq testType = testExpr->getPreferredType();
|
||||
|
||||
if (testType == TypeReqUInt)
|
||||
{
|
||||
integer = true;
|
||||
}
|
||||
|
|
@ -209,8 +211,16 @@ U32 IfStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
|
|||
integer = false;
|
||||
}
|
||||
|
||||
ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat);
|
||||
codeStream.emit(integer ? OP_JMPIFNOT : OP_JMPIFFNOT);
|
||||
if (testType == TypeReqString || testType == TypeReqNone)
|
||||
{
|
||||
ip = testExpr->compile(codeStream, ip, TypeReqString);
|
||||
codeStream.emit(OP_JMPNOTSTRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat);
|
||||
codeStream.emit(integer ? OP_JMPIFNOT : OP_JMPIFFNOT);
|
||||
}
|
||||
|
||||
if (elseBlock)
|
||||
{
|
||||
|
|
@ -932,6 +942,7 @@ U32 AssignExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type)
|
|||
case TypeReqString: codeStream.emit(OP_SAVEVAR_STR); break;
|
||||
case TypeReqUInt: codeStream.emit(OP_SAVEVAR_UINT); break;
|
||||
case TypeReqFloat: codeStream.emit(OP_SAVEVAR_FLT); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,15 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
|
|||
ip++;
|
||||
break;
|
||||
}
|
||||
|
||||
ip = code[ip];
|
||||
break;
|
||||
case OP_JMPNOTSTRING:
|
||||
if (stack[_STK--].getBool())
|
||||
{
|
||||
ip++;
|
||||
break;
|
||||
}
|
||||
ip = code[ip];
|
||||
break;
|
||||
case OP_JMPIFF:
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ namespace Compiler
|
|||
|
||||
OP_JMPIFFNOT,
|
||||
OP_JMPIFNOT,
|
||||
OP_JMPNOTSTRING,
|
||||
OP_JMPIFF,
|
||||
OP_JMPIF,
|
||||
OP_JMPIFNOT_NP,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ namespace TorqueScript
|
|||
{
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, &string);
|
||||
va_start(args, string);
|
||||
dVsprintf(buffer, sizeof(buffer), string, args);
|
||||
va_end(args);
|
||||
return evaluate(buffer);
|
||||
|
|
|
|||
|
|
@ -85,18 +85,18 @@ FileObject::FileObject()
|
|||
mFileBuffer = NULL;
|
||||
mBufferSize = 0;
|
||||
mCurPos = 0;
|
||||
stream = NULL;
|
||||
mStream = NULL;
|
||||
}
|
||||
|
||||
FileObject::~FileObject()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(mFileBuffer);
|
||||
SAFE_DELETE(stream);
|
||||
SAFE_DELETE(mStream);
|
||||
}
|
||||
|
||||
void FileObject::close()
|
||||
{
|
||||
SAFE_DELETE(stream);
|
||||
SAFE_DELETE(mStream);
|
||||
SAFE_DELETE_ARRAY(mFileBuffer);
|
||||
mFileBuffer = NULL;
|
||||
mBufferSize = mCurPos = 0;
|
||||
|
|
@ -112,10 +112,10 @@ bool FileObject::openForWrite(const char *fileName, const bool append)
|
|||
if( !buffer[ 0 ] )
|
||||
return false;
|
||||
|
||||
if((stream = FileStream::createAndOpen( fileName, append ? Torque::FS::File::WriteAppend : Torque::FS::File::Write )) == NULL)
|
||||
if((mStream = FileStream::createAndOpen( fileName, append ? Torque::FS::File::WriteAppend : Torque::FS::File::Write )) == NULL)
|
||||
return false;
|
||||
|
||||
stream->setPosition( stream->getStreamSize() );
|
||||
mStream->setPosition(mStream->getStreamSize() );
|
||||
return( true );
|
||||
}
|
||||
|
||||
|
|
@ -225,17 +225,17 @@ void FileObject::peekLine( S32 peekLineOffset, U8* line, S32 length )
|
|||
|
||||
void FileObject::writeLine(const U8 *line)
|
||||
{
|
||||
stream->write(dStrlen((const char *) line), line);
|
||||
stream->write(2, "\r\n");
|
||||
mStream->write(dStrlen((const char *) line), line);
|
||||
mStream->write(2, "\r\n");
|
||||
}
|
||||
|
||||
void FileObject::writeObject( SimObject* object, const U8* objectPrepend )
|
||||
{
|
||||
if( objectPrepend == NULL )
|
||||
stream->write(2, "\r\n");
|
||||
mStream->write(2, "\r\n");
|
||||
else
|
||||
stream->write(dStrlen((const char *) objectPrepend), objectPrepend );
|
||||
object->write( *stream, 0 );
|
||||
mStream->write(dStrlen((const char *) objectPrepend), objectPrepend );
|
||||
object->write( *mStream, 0 );
|
||||
}
|
||||
|
||||
DefineEngineMethod( FileObject, openForRead, bool, ( const char* filename ),,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class FileObject : public SimObject
|
|||
U8 *mFileBuffer;
|
||||
U32 mBufferSize;
|
||||
U32 mCurPos;
|
||||
FileStream *stream;
|
||||
FileStream *mStream;
|
||||
public:
|
||||
FileObject();
|
||||
~FileObject();
|
||||
|
|
@ -50,6 +50,8 @@ public:
|
|||
bool isEOF();
|
||||
void writeLine(const U8 *line);
|
||||
void close();
|
||||
|
||||
bool writeObject(Stream* stream) override { Con::errorf("FileObject:Can Not write a file interface object to a file"); return false; }; //Don't allow writing FileObject *to* files
|
||||
void writeObject( SimObject* object, const U8* objectPrepend = NULL );
|
||||
|
||||
DECLARE_CONOBJECT(FileObject);
|
||||
|
|
|
|||
|
|
@ -259,9 +259,23 @@ extern S32 dStrcmp(const UTF16 *str1, const UTF16 *str2);
|
|||
extern S32 dStrnatcmp( const char* str1, const char* str2 );
|
||||
extern S32 dStrnatcasecmp( const char* str1, const char* str2 );
|
||||
|
||||
inline bool dAtob(const char *str)
|
||||
inline bool dAtob(const char* str)
|
||||
{
|
||||
return !dStricmp(str, "true") || dAtof(str);
|
||||
if (str && str[0] != '\0')
|
||||
{
|
||||
if (dStricmp(str, "0") == 0)
|
||||
return false;
|
||||
if (dStricmp(str, "0.0") == 0)
|
||||
return false;
|
||||
if (dStricmp(str, "0.0f") == 0)
|
||||
return false;
|
||||
if (dStricmp(str, "null") == 0)
|
||||
return false;
|
||||
if (dStricmp(str, "false") == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dStrEqual(const char* str1, const char* str2);
|
||||
|
|
|
|||
|
|
@ -140,19 +140,6 @@ static void create_uuid_state(uuid_state *st)
|
|||
get_pseudo_node_identifier(&st->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* dav_format_opaquelocktoken - generates a text representation
|
||||
* of an opaquelocktoken
|
||||
*/
|
||||
static void format_token(char *target, const xuuid_t *u)
|
||||
{
|
||||
sprintf(target, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
u->time_low, u->time_mid, u->time_hi_and_version,
|
||||
u->clock_seq_hi_and_reserved, u->clock_seq_low,
|
||||
u->node[0], u->node[1], u->node[2],
|
||||
u->node[3], u->node[4], u->node[5]);
|
||||
}
|
||||
|
||||
/* convert a pair of hex digits to an integer value [0,255] */
|
||||
static int dav_parse_hexpair(const char *s)
|
||||
{
|
||||
|
|
@ -414,9 +401,16 @@ namespace Torque
|
|||
|
||||
String UUID::toString() const
|
||||
{
|
||||
char buffer[ 1024 ];
|
||||
format_token( buffer, ( xuuid_t* ) this );
|
||||
return buffer;
|
||||
const xuuid_t* u = (xuuid_t*)this;
|
||||
StringBuilder str;
|
||||
|
||||
str.format("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
u->time_low, u->time_mid, u->time_hi_and_version,
|
||||
u->clock_seq_hi_and_reserved, u->clock_seq_low,
|
||||
u->node[0], u->node[1], u->node[2],
|
||||
u->node[3], u->node[4], u->node[5]);
|
||||
|
||||
return str.end();
|
||||
}
|
||||
|
||||
bool UUID::fromString( const char* str )
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ class TheoraTexture : private IOutputStream< TheoraTextureFrame* >,
|
|||
|
||||
///
|
||||
AsyncState( const ThreadSafeRef< OggInputStream >& oggStream, bool looping = false );
|
||||
|
||||
virtual ~AsyncState() {};
|
||||
/// Return the Theora decoder substream.
|
||||
OggTheoraDecoder* getTheora() const { return mTheoraDecoder; }
|
||||
|
||||
|
|
|
|||
|
|
@ -451,16 +451,16 @@ void GuiInspectorField::setWordData(const S32& wordIndex, const char* data, bool
|
|||
|
||||
StringBuilder newFieldData;
|
||||
const U32 wordCount = StringUnit::getUnitCount(fieldData, " \t\n");
|
||||
for (U32 i = 0; i < wordCount; i++)
|
||||
for (U32 wc = 0; wc < wordCount; wc++)
|
||||
{
|
||||
if (i != 0)
|
||||
if (wc != 0)
|
||||
newFieldData.append(" ");
|
||||
|
||||
if (i == wordIndex)
|
||||
if (wc == wordIndex)
|
||||
newFieldData.append(data);
|
||||
else
|
||||
{
|
||||
newFieldData.append(StringUnit::getUnit(fieldData, i, " \t\n"));
|
||||
newFieldData.append(StringUnit::getUnit(fieldData, wc, " \t\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,4 +144,4 @@ public:
|
|||
void canHitSelectedNodes(bool state = true);
|
||||
};
|
||||
|
||||
#endif _GUISHADEREDITOR_H_
|
||||
#endif //_GUISHADEREDITOR_H_
|
||||
|
|
|
|||
|
|
@ -867,6 +867,9 @@ void WorldEditor::terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizm
|
|||
case AlignNegZ:
|
||||
rot.set(mDegToRad(-90.0f), 0.0f, mDegToRad(180.0f));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MatrixF mat = MathUtils::createOrientFromDir(ri.normal);
|
||||
|
|
@ -1999,7 +2002,7 @@ void WorldEditor::on3DMouseMove(const Gui3DMouseEvent & event)
|
|||
if ( !mHitObject )
|
||||
{
|
||||
SceneObject *hitObj = NULL;
|
||||
if ( collide(event, &hitObj) && !hitObj->isDeleted() && hitObj->isSelectionEnabled() && !objClassIgnored(hitObj) )
|
||||
if ( collide(event, &hitObj) && hitObj && !hitObj->isDeleted() && hitObj->isSelectionEnabled() && !objClassIgnored(hitObj) )
|
||||
{
|
||||
mHitObject = hitObj;
|
||||
}
|
||||
|
|
@ -2060,7 +2063,7 @@ void WorldEditor::on3DMouseDown(const Gui3DMouseEvent & event)
|
|||
}
|
||||
|
||||
SceneObject *hitObj = NULL;
|
||||
if ( collide( event, &hitObj ) && hitObj->isSelectionEnabled() && !objClassIgnored( hitObj ) )
|
||||
if ( collide( event, &hitObj ) && hitObj && hitObj->isSelectionEnabled() && !objClassIgnored( hitObj ) )
|
||||
{
|
||||
mPossibleHitObject = hitObj;
|
||||
mNoMouseDrag = true;
|
||||
|
|
|
|||
|
|
@ -261,16 +261,16 @@ void GlowMapGLSL::processPix(Vector<ShaderComponent*>& componentList, const Mate
|
|||
targ->setType("vec4");
|
||||
targ->setName(getOutputTargetVarName(ShaderFeature::RenderTarget3));
|
||||
targ->setStructName("OUT");
|
||||
output = new GenOp("@ = vec4(@.rgb*@,0);", targ, texOp, glowMul);
|
||||
output = new GenOp("@ = vec4(pow(max(@.rgb*@,0.0),vec3(3.54406804435,3.54406804435,3.54406804435)),0);", targ, texOp, glowMul);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = new GenOp("@ += vec4(@.rgb*@,0);", targ, texOp, glowMul);
|
||||
output = new GenOp("@ += vec4(pow(max(@.rgb*@,0.0),vec3(3.54406804435,3.54406804435,3.54406804435)),0);", targ, texOp, glowMul);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = new GenOp("@ += vec4(@.rgb*@,@.a);", targ, texOp, glowMul, targ);
|
||||
output = new GenOp("@ += vec4(pow(max(@.rgb*@,0.0),vec3(3.54406804435,3.54406804435,3.54406804435)),@.a);", targ, texOp, glowMul, targ);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,16 +264,16 @@ void GlowMapHLSL::processPix(Vector<ShaderComponent*> &componentList, const Mate
|
|||
targ->setType("fragout");
|
||||
targ->setName(getOutputTargetVarName(ShaderFeature::RenderTarget3));
|
||||
targ->setStructName("OUT");
|
||||
output = new GenOp("@ = float4(@.rgb*@,0);", targ, texOp, glowMul);
|
||||
output = new GenOp("@ = float4(pow(max(@.rgb*@,0.0),3.54406804435),0);", targ, texOp, glowMul);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = new GenOp("@ += float4(@.rgb*@,0);", targ, texOp, glowMul);
|
||||
output = new GenOp("@ += float4(pow(max(@.rgb*@,0.0),3.54406804435),0);", targ, texOp, glowMul);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = new GenOp("@ += float4(@.rgb*@,@.a);", targ, texOp, glowMul, targ);
|
||||
output = new GenOp("@ += float4(pow(max(@.rgb*@,0.0),3.54406804435),@.a);", targ, texOp, glowMul, targ);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true );
|
|||
ImplementFeatureType(MFT_ReflectionProbes, MFG_Lighting, 1.0f, true);
|
||||
ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
|
||||
ImplementFeatureType( MFT_GlowMap, MFG_Lighting, 3.0f, true );
|
||||
ImplementFeatureType( MFT_GlowMask, MFG_Lighting, 3.1f, true );
|
||||
ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );
|
||||
ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 5.0f, true );
|
||||
ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 6.0f, false );
|
||||
|
|
@ -65,8 +66,6 @@ ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 8.0f, true );
|
|||
ImplementFeatureType( MFT_VertLit, MFG_Lighting, 9.0f, true );
|
||||
ImplementFeatureType( MFT_MinnaertShading, MFG_Lighting, 10.0f, true );
|
||||
|
||||
|
||||
ImplementFeatureType( MFT_GlowMask, MFG_PostLighting, 1.0f, true );
|
||||
ImplementFeatureType( MFT_Visibility, MFG_PostLighting, 2.0f, true );
|
||||
ImplementFeatureType( MFT_Fog, MFG_PostProcess, 3.0f, true );
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ void ProcessedMaterial::addStateBlockDesc(const GFXStateBlockDesc& sb)
|
|||
mUserDefined = sb;
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateGlow, GFXStateBlockDesc& stateReflect)
|
||||
void ProcessedMaterial::_initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateReflect)
|
||||
{
|
||||
// Translucency
|
||||
stateTranslucent.blendDefined = true;
|
||||
|
|
@ -211,10 +211,6 @@ void ProcessedMaterial::_initStateBlockTemplates(GFXStateBlockDesc& stateTranslu
|
|||
stateTranslucent.alphaTestFunc = GFXCmpGreaterEqual;
|
||||
stateTranslucent.samplersDefined = true;
|
||||
|
||||
// Glow
|
||||
stateGlow.zDefined = true;
|
||||
stateGlow.zWriteEnable = false;
|
||||
|
||||
// Reflect
|
||||
stateReflect.cullDefined = true;
|
||||
stateReflect.cullMode = mMaterial->mDoubleSided ? GFXCullNone : GFXCullCW;
|
||||
|
|
@ -316,11 +312,10 @@ void ProcessedMaterial::_initPassStateBlock( RenderPassData *rpd, GFXStateBlockD
|
|||
void ProcessedMaterial::_initRenderStateStateBlocks( RenderPassData *rpd )
|
||||
{
|
||||
GFXStateBlockDesc stateTranslucent;
|
||||
GFXStateBlockDesc stateGlow;
|
||||
GFXStateBlockDesc stateReflect;
|
||||
GFXStateBlockDesc statePass;
|
||||
|
||||
_initStateBlockTemplates( stateTranslucent, stateGlow, stateReflect );
|
||||
_initStateBlockTemplates( stateTranslucent, stateReflect );
|
||||
_initPassStateBlock( rpd, statePass );
|
||||
|
||||
// Ok, we've got our templates set up, let's combine them together based on state and
|
||||
|
|
@ -333,8 +328,6 @@ void ProcessedMaterial::_initRenderStateStateBlocks( RenderPassData *rpd )
|
|||
stateFinal.addDesc(stateReflect);
|
||||
if (i & RenderPassData::STATE_TRANSLUCENT)
|
||||
stateFinal.addDesc(stateTranslucent);
|
||||
if (i & RenderPassData::STATE_GLOW)
|
||||
stateFinal.addDesc(stateGlow);
|
||||
|
||||
stateFinal.addDesc(statePass);
|
||||
|
||||
|
|
@ -359,9 +352,6 @@ U32 ProcessedMaterial::_getRenderStateIndex( const SceneRenderState *sceneState,
|
|||
// For example sgData.visibility would be bad to use
|
||||
// in here without changing how RenderMeshMgr works.
|
||||
|
||||
if ( sgData.binType == SceneData::GlowBin )
|
||||
currState |= RenderPassData::STATE_GLOW;
|
||||
|
||||
if ( sceneState && sceneState->isReflectPass() )
|
||||
currState |= RenderPassData::STATE_REFLECT;
|
||||
|
||||
|
|
|
|||
|
|
@ -98,9 +98,8 @@ public:
|
|||
{
|
||||
STATE_REFLECT = 1,
|
||||
STATE_TRANSLUCENT = 2,
|
||||
STATE_GLOW = 4,
|
||||
STATE_WIREFRAME = 8,
|
||||
STATE_MAX = 16
|
||||
STATE_WIREFRAME = 4,
|
||||
STATE_MAX = 8
|
||||
};
|
||||
|
||||
///
|
||||
|
|
@ -301,7 +300,7 @@ protected:
|
|||
/// @{
|
||||
|
||||
/// Creates the default state block templates, used by initStateBlocks.
|
||||
virtual void _initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateGlow, GFXStateBlockDesc& stateReflect);
|
||||
virtual void _initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateReflect);
|
||||
|
||||
/// Does the base render state block setting, normally per pass.
|
||||
virtual void _initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc& result);
|
||||
|
|
|
|||
|
|
@ -348,7 +348,6 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum,
|
|||
//
|
||||
if ( features.hasFeature( MFT_UseInstancing ) &&
|
||||
mMaxStages == 1 &&
|
||||
!mMaterial->mGlow[0] &&
|
||||
shaderVersion >= 3.0f )
|
||||
fd.features.addFeature( MFT_UseInstancing );
|
||||
|
||||
|
|
@ -520,6 +519,9 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum,
|
|||
if ( mMaterial->mVertColor[ stageNum ] &&
|
||||
mVertexFormat->hasColor() )
|
||||
fd.features.addFeature( MFT_DiffuseVertColor );
|
||||
|
||||
if (mMaterial->mGlow[stageNum])
|
||||
fd.features.addFeature(MFT_GlowMask);
|
||||
|
||||
// Allow features to add themselves.
|
||||
for ( U32 i = 0; i < FEATUREMGR->getFeatureCount(); i++ )
|
||||
|
|
|
|||
|
|
@ -45,10 +45,6 @@ struct SceneData
|
|||
/// the special bins we care about.
|
||||
RegularBin = 0,
|
||||
|
||||
/// The glow render bin.
|
||||
/// @see RenderGlowMgr
|
||||
GlowBin,
|
||||
|
||||
/// The deferred render bin.
|
||||
/// @RenderDeferredMgr
|
||||
DeferredBin,
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ public:
|
|||
inline void setModuleLocked( const bool status ) { mLocked = status; }
|
||||
inline bool getModuleLocked( void ) const { return mLocked; }
|
||||
inline ModuleManager* getModuleManager( void ) const { return mpModuleManager; }
|
||||
|
||||
using Parent::save;
|
||||
bool save( void );
|
||||
|
||||
/// Declare Console Object.
|
||||
|
|
|
|||
|
|
@ -201,6 +201,9 @@ void duDebugDrawTorque::renderBuffer(Buffer &b)
|
|||
buf[i].data.color.b,
|
||||
buf[i].data.color.a);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
PrimBuild::end();
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ private:
|
|||
void compileCustomState( TamlWriteNode* pTamlWriteNode );
|
||||
void compileCustomNodeState( TamlCustomNode* pCustomNode );
|
||||
|
||||
void write(Stream& stream, U32 tabStop, U32 flags = 0) override { Con::errorf("Taml:Can Not write a file interface object to a file"); }; //Don't allow writing Taml objects *to* files
|
||||
bool write( FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode );
|
||||
SimObject* read( FileStream& stream, const TamlFormatMode formatMode );
|
||||
template<typename T> inline T* read( FileStream& stream, const TamlFormatMode formatMode )
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include "platform/platformRedBook.h"
|
||||
#include "core/strings/unicode.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
class Win32RedBookDevice : public RedBookDevice
|
||||
{
|
||||
|
|
|
|||
|
|
@ -683,7 +683,8 @@ void ProcessedDeferredMaterial::_determineFeatures( U32 stageNum,
|
|||
type == MFT_UseInstancing ||
|
||||
type == MFT_DiffuseVertColor ||
|
||||
type == MFT_DetailMap ||
|
||||
type == MFT_DiffuseMapAtlas)
|
||||
type == MFT_DiffuseMapAtlas||
|
||||
type == MFT_GlowMask)
|
||||
newFeatures.addFeature( type );
|
||||
|
||||
// Add any transform features.
|
||||
|
|
|
|||
|
|
@ -1,282 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "renderInstance/renderGlowMgr.h"
|
||||
#include "renderInstance/renderParticleMgr.h"
|
||||
|
||||
#include "scene/sceneManager.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "materials/matInstance.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
#include "postFx/postEffect.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "gfx/gfxDebugEvent.h"
|
||||
#include "math/util/matrixSet.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT( RenderGlowMgr );
|
||||
|
||||
|
||||
ConsoleDocClass( RenderGlowMgr,
|
||||
"@brief A render bin for the glow pass.\n\n"
|
||||
"When the glow buffer PostEffect is enabled this bin gathers mesh render "
|
||||
"instances with glow materials and renders them to the #glowbuffer offscreen "
|
||||
"render target.\n\n"
|
||||
"This render target is then used by the 'GlowPostFx' PostEffect to blur and "
|
||||
"render the glowing portions of the screen.\n\n"
|
||||
"@ingroup RenderBin\n" );
|
||||
|
||||
const MatInstanceHookType RenderGlowMgr::GlowMaterialHook::Type( "Glow" );
|
||||
|
||||
|
||||
RenderGlowMgr::GlowMaterialHook::GlowMaterialHook( BaseMatInstance *matInst )
|
||||
: mGlowMatInst( NULL )
|
||||
{
|
||||
mGlowMatInst = (MatInstance*)matInst->getMaterial()->createMatInstance();
|
||||
mGlowMatInst->getFeaturesDelegate().bind( &GlowMaterialHook::_overrideFeatures );
|
||||
mGlowMatInst->setUserObject(matInst->getUserObject());
|
||||
mGlowMatInst->init( matInst->getRequestedFeatures(),
|
||||
matInst->getVertexFormat() );
|
||||
}
|
||||
|
||||
RenderGlowMgr::GlowMaterialHook::~GlowMaterialHook()
|
||||
{
|
||||
SAFE_DELETE( mGlowMatInst );
|
||||
}
|
||||
|
||||
void RenderGlowMgr::GlowMaterialHook::_overrideFeatures( ProcessedMaterial *mat,
|
||||
U32 stageNum,
|
||||
MaterialFeatureData &fd,
|
||||
const FeatureSet &features )
|
||||
{
|
||||
// If this isn't a glow pass... then add the glow mask feature.
|
||||
if ( mat->getMaterial() &&
|
||||
!mat->getMaterial()->mGlow[stageNum] )
|
||||
fd.features.addFeature( MFT_GlowMask );
|
||||
|
||||
// Don't allow fog or HDR encoding on
|
||||
// the glow materials.
|
||||
fd.features.removeFeature( MFT_Fog );
|
||||
fd.features.addFeature( MFT_Imposter );
|
||||
}
|
||||
|
||||
RenderGlowMgr::RenderGlowMgr()
|
||||
: RenderTexTargetBinManager( RenderPassManager::RIT_Mesh,
|
||||
1.0f,
|
||||
1.0f,
|
||||
GFXFormatR8G8B8A8,
|
||||
Point2I( 512, 512 ) )
|
||||
{
|
||||
notifyType( RenderPassManager::RIT_Decal );
|
||||
notifyType( RenderPassManager::RIT_DecalRoad );
|
||||
notifyType( RenderPassManager::RIT_Translucent );
|
||||
notifyType( RenderPassManager::RIT_Particle );
|
||||
|
||||
mParticleRenderMgr = NULL;
|
||||
|
||||
mNamedTarget.registerWithName( "glowbuffer" );
|
||||
mTargetSizeType = WindowSize;
|
||||
}
|
||||
|
||||
RenderGlowMgr::~RenderGlowMgr()
|
||||
{
|
||||
}
|
||||
|
||||
PostEffect* RenderGlowMgr::getGlowEffect()
|
||||
{
|
||||
if ( !mGlowEffect )
|
||||
mGlowEffect = dynamic_cast<PostEffect*>( Sim::findObject( "GlowPostFx" ) );
|
||||
|
||||
return mGlowEffect;
|
||||
}
|
||||
|
||||
bool RenderGlowMgr::isGlowEnabled()
|
||||
{
|
||||
return getGlowEffect() && getGlowEffect()->isEnabled();
|
||||
}
|
||||
|
||||
void RenderGlowMgr::addElement( RenderInst *inst )
|
||||
{
|
||||
// Skip out if we don't have the glow post
|
||||
// effect enabled at this time.
|
||||
if ( !isGlowEnabled() )
|
||||
return;
|
||||
|
||||
// TODO: We need to get the scene state here in a more reliable
|
||||
// manner so we can skip glow in a non-diffuse render pass.
|
||||
//if ( !mParentManager->getSceneManager()->getSceneState()->isDiffusePass() )
|
||||
//return RenderBinManager::arSkipped;
|
||||
ParticleRenderInst *particleInst = NULL;
|
||||
if(inst->type == RenderPassManager::RIT_Particle)
|
||||
particleInst = static_cast<ParticleRenderInst*>(inst);
|
||||
if(particleInst && particleInst->glow)
|
||||
{
|
||||
internalAddElement(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip it if we don't have a glowing material.
|
||||
BaseMatInstance *matInst = getMaterial( inst );
|
||||
if ( !matInst || !matInst->hasGlow() )
|
||||
return;
|
||||
|
||||
internalAddElement(inst);
|
||||
}
|
||||
|
||||
void RenderGlowMgr::render( SceneRenderState *state )
|
||||
{
|
||||
PROFILE_SCOPE( RenderGlowMgr_Render );
|
||||
|
||||
if ( !isGlowEnabled() )
|
||||
return;
|
||||
|
||||
const U32 binSize = mElementList.size();
|
||||
|
||||
// If this is a non-diffuse pass or we have no objects to
|
||||
// render then tell the effect to skip rendering.
|
||||
if ( !state->isDiffusePass() || binSize == 0 )
|
||||
{
|
||||
getGlowEffect()->setSkip( true );
|
||||
return;
|
||||
}
|
||||
|
||||
GFXDEBUGEVENT_SCOPE( RenderGlowMgr_Render, ColorI::GREEN );
|
||||
|
||||
GFXTransformSaver saver;
|
||||
|
||||
// Respect the current viewport
|
||||
mNamedTarget.setViewport(GFX->getViewport());
|
||||
|
||||
// Tell the superclass we're about to render, preserve contents
|
||||
const bool isRenderingToTarget = _onPreRender( state, true );
|
||||
|
||||
// Clear all the buffers to black.
|
||||
GFX->clear( GFXClearTarget, ColorI::BLACK, 1.0f, 0);
|
||||
|
||||
// Restore transforms
|
||||
MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
|
||||
matrixSet.restoreSceneViewProjection();
|
||||
|
||||
// init loop data
|
||||
SceneData sgData;
|
||||
sgData.init( state, SceneData::GlowBin );
|
||||
|
||||
for( U32 j=0; j<binSize; )
|
||||
{
|
||||
RenderInst *_ri = mElementList[j].inst;
|
||||
if(_ri->type == RenderPassManager::RIT_Particle)
|
||||
{
|
||||
// Find the particle render manager (if we don't have it)
|
||||
if(mParticleRenderMgr == NULL)
|
||||
{
|
||||
RenderPassManager *rpm = state->getRenderPass();
|
||||
for( U32 i = 0; i < rpm->getManagerCount(); i++ )
|
||||
{
|
||||
RenderBinManager *bin = rpm->getManager(i);
|
||||
if( bin->getRenderInstType() == RenderParticleMgr::RIT_Particles )
|
||||
{
|
||||
mParticleRenderMgr = reinterpret_cast<RenderParticleMgr *>(bin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(_ri);
|
||||
|
||||
GFX->setStateBlock(mParticleRenderMgr->_getHighResStateBlock(ri));
|
||||
mParticleRenderMgr->_getShaderConsts().mShaderConsts->setSafe(mParticleRenderMgr->_getShaderConsts().mModelViewProjSC, *ri->modelViewProj);
|
||||
|
||||
mParticleRenderMgr->renderParticle(ri, state);
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
MeshRenderInst *ri = static_cast<MeshRenderInst*>(_ri);
|
||||
|
||||
setupSGData( ri, sgData );
|
||||
|
||||
BaseMatInstance *mat = ri->matInst;
|
||||
GlowMaterialHook *hook = mat->getHook<GlowMaterialHook>();
|
||||
if ( !hook )
|
||||
{
|
||||
hook = new GlowMaterialHook( ri->matInst );
|
||||
ri->matInst->addHook( hook );
|
||||
}
|
||||
BaseMatInstance *glowMat = hook->getMatInstance();
|
||||
|
||||
U32 matListEnd = j;
|
||||
|
||||
while( glowMat && glowMat->setupPass( state, sgData ) )
|
||||
{
|
||||
U32 a;
|
||||
for( a=j; a<binSize; a++ )
|
||||
{
|
||||
if (mElementList[a].inst->type == RenderPassManager::RIT_Particle)
|
||||
break;
|
||||
|
||||
MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);
|
||||
|
||||
if ( newPassNeeded( ri, passRI ) )
|
||||
break;
|
||||
|
||||
matrixSet.setWorld(*passRI->objectToWorld);
|
||||
matrixSet.setView(*passRI->worldToCamera);
|
||||
matrixSet.setProjection(*passRI->projection);
|
||||
glowMat->setTransforms(matrixSet, state);
|
||||
|
||||
// Setup HW skinning transforms if applicable
|
||||
if (glowMat->usesHardwareSkinning())
|
||||
{
|
||||
glowMat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount);
|
||||
}
|
||||
|
||||
//push along any overriden fields that are instance-specific as well
|
||||
if (passRI->mCustomShaderData.size() > 0)
|
||||
{
|
||||
mat->setCustomShaderData(passRI->mCustomShaderData);
|
||||
}
|
||||
|
||||
glowMat->setSceneInfo(state, sgData);
|
||||
glowMat->setBuffers(passRI->vertBuff, passRI->primBuff);
|
||||
|
||||
if ( passRI->prim )
|
||||
GFX->drawPrimitive( *passRI->prim );
|
||||
else
|
||||
GFX->drawPrimitive( passRI->primBuffIndex );
|
||||
}
|
||||
matListEnd = a;
|
||||
setupSGData( ri, sgData );
|
||||
}
|
||||
|
||||
// force increment if none happened, otherwise go to end of batch
|
||||
j = ( j == matListEnd ) ? j+1 : matListEnd;
|
||||
}
|
||||
|
||||
// Finish up.
|
||||
if ( isRenderingToTarget )
|
||||
_onPostRender();
|
||||
|
||||
// Make sure the effect is gonna render.
|
||||
getGlowEffect()->setSkip( false );
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _RENDERGLOWMGR_H_
|
||||
#define _RENDERGLOWMGR_H_
|
||||
|
||||
#ifndef _TEXTARGETBIN_MGR_H_
|
||||
#include "renderInstance/renderTexTargetBinManager.h"
|
||||
#endif
|
||||
#include <renderInstance/renderParticleMgr.h>
|
||||
|
||||
|
||||
class PostEffect;
|
||||
|
||||
|
||||
///
|
||||
class RenderGlowMgr : public RenderTexTargetBinManager
|
||||
{
|
||||
typedef RenderTexTargetBinManager Parent;
|
||||
|
||||
public:
|
||||
|
||||
RenderGlowMgr();
|
||||
virtual ~RenderGlowMgr();
|
||||
|
||||
/// Returns the glow post effect.
|
||||
PostEffect* getGlowEffect();
|
||||
|
||||
/// Returns true if the glow post effect is
|
||||
/// enabled and the glow buffer should be updated.
|
||||
bool isGlowEnabled();
|
||||
|
||||
// RenderBinManager
|
||||
void addElement( RenderInst *inst ) override;
|
||||
void render( SceneRenderState *state ) override;
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT( RenderGlowMgr );
|
||||
|
||||
protected:
|
||||
|
||||
class GlowMaterialHook : public MatInstanceHook
|
||||
{
|
||||
public:
|
||||
|
||||
GlowMaterialHook( BaseMatInstance *matInst );
|
||||
virtual ~GlowMaterialHook();
|
||||
|
||||
virtual BaseMatInstance *getMatInstance() { return mGlowMatInst; }
|
||||
|
||||
const MatInstanceHookType& getType() const override { return Type; }
|
||||
|
||||
/// Our material hook type.
|
||||
static const MatInstanceHookType Type;
|
||||
|
||||
protected:
|
||||
|
||||
static void _overrideFeatures( ProcessedMaterial *mat,
|
||||
U32 stageNum,
|
||||
MaterialFeatureData &fd,
|
||||
const FeatureSet &features );
|
||||
|
||||
BaseMatInstance *mGlowMatInst;
|
||||
};
|
||||
|
||||
SimObjectPtr<PostEffect> mGlowEffect;
|
||||
RenderParticleMgr *mParticleRenderMgr;
|
||||
};
|
||||
|
||||
|
||||
#endif // _RENDERGLOWMGR_H_
|
||||
|
|
@ -35,7 +35,6 @@
|
|||
#include "renderInstance/renderObjectMgr.h"
|
||||
#include "renderInstance/renderMeshMgr.h"
|
||||
#include "renderInstance/renderTranslucentMgr.h"
|
||||
#include "renderInstance/renderGlowMgr.h"
|
||||
#include "renderInstance/renderTerrainMgr.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "math/util/matrixSet.h"
|
||||
|
|
|
|||
|
|
@ -57,15 +57,14 @@ bool SFXSndStream::_readHeader()
|
|||
bitsPerSample = 8;
|
||||
break;
|
||||
case SF_FORMAT_PCM_16:
|
||||
case SF_FORMAT_VORBIS:
|
||||
bitsPerSample = 16;
|
||||
break;
|
||||
case SF_FORMAT_VORBIS:
|
||||
case SF_FORMAT_PCM_24:
|
||||
bitsPerSample = 24;
|
||||
break;
|
||||
case SF_FORMAT_PCM_32:
|
||||
case SF_FORMAT_FLOAT:
|
||||
bitsPerSample = 32;
|
||||
bitsPerSample = 16;
|
||||
sf_command(sndFile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
|
||||
break;
|
||||
default:
|
||||
// missed, set it to 16 anyway.
|
||||
|
|
@ -105,14 +104,46 @@ void SFXSndStream::reset()
|
|||
|
||||
U32 SFXSndStream::read(U8* buffer, U32 length)
|
||||
{
|
||||
if (!sndFile)
|
||||
{
|
||||
Con::errorf("SFXSndStream - read: Called on uninitialized stream.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 framesToRead = length / mFormat.getBytesPerSample();
|
||||
U32 framesRead = 0;
|
||||
|
||||
framesRead = sf_readf_short(sndFile, (short*)buffer, sfinfo.frames);
|
||||
if (framesRead != sfinfo.frames)
|
||||
switch (sfinfo.format & SF_FORMAT_SUBMASK)
|
||||
{
|
||||
case SF_FORMAT_PCM_S8:
|
||||
case SF_FORMAT_PCM_U8:
|
||||
framesRead = sf_readf_int(sndFile, (int*)buffer, framesToRead);
|
||||
break;
|
||||
case SF_FORMAT_PCM_16:
|
||||
case SF_FORMAT_VORBIS:
|
||||
case SF_FORMAT_PCM_24:
|
||||
case SF_FORMAT_PCM_32:
|
||||
case SF_FORMAT_FLOAT:
|
||||
framesRead = sf_readf_short(sndFile, (short*)buffer, framesToRead);
|
||||
break;
|
||||
default:
|
||||
Con::errorf("SFXSndStream - read: Unsupported format.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (framesRead != framesToRead)
|
||||
{
|
||||
Con::errorf("SFXSndStream - read: %s", sf_strerror(sndFile));
|
||||
}
|
||||
|
||||
// (convert to frames) - number of frames available < MAX_BUFFER? reset
|
||||
if (((getPosition() / mFormat.getBytesPerSample()) - sfinfo.frames) < MAX_BUFFER)
|
||||
{
|
||||
// reset stream
|
||||
setPosition(0);
|
||||
}
|
||||
|
||||
|
||||
return framesRead * mFormat.getBytesPerSample();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,111 +68,6 @@
|
|||
#define ALCchar char
|
||||
#endif
|
||||
|
||||
// Complete list of functions available in AL 1.0 implementations
|
||||
|
||||
typedef void (ALAPIENTRY *LPALENABLE)( ALenum capability );
|
||||
typedef void (ALAPIENTRY *LPALDISABLE)( ALenum capability );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISENABLED)( ALenum capability );
|
||||
typedef const ALchar* (ALAPIENTRY *LPALGETSTRING)( ALenum param );
|
||||
typedef void (ALAPIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data );
|
||||
typedef void (ALAPIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
|
||||
typedef void (ALAPIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
|
||||
typedef void (ALAPIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
|
||||
typedef ALboolean (ALAPIENTRY *LPALGETBOOLEAN)( ALenum param );
|
||||
typedef ALint (ALAPIENTRY *LPALGETINTEGER)( ALenum param );
|
||||
typedef ALfloat (ALAPIENTRY *LPALGETFLOAT)( ALenum param );
|
||||
typedef ALdouble (ALAPIENTRY *LPALGETDOUBLE)( ALenum param );
|
||||
typedef ALenum (ALAPIENTRY *LPALGETERROR)( void );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname );
|
||||
typedef void* (ALAPIENTRY *LPALGETPROCADDRESS)( const ALchar* fname );
|
||||
typedef ALenum (ALAPIENTRY *LPALGETENUMVALUE)( const ALchar* ename );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERF)( ALenum param, ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERI)( ALenum param, ALint value );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources );
|
||||
typedef void (ALAPIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISSOURCE)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPLAY)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCESTOP)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEREWIND)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPAUSE)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||
typedef void (ALAPIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers );
|
||||
typedef void (ALAPIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISBUFFER)( ALuint bid );
|
||||
typedef void (ALAPIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
|
||||
typedef void (ALAPIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALDOPPLERFACTOR)( ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALDOPPLERVELOCITY)( ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel );
|
||||
|
||||
typedef ALCcontext * (ALCAPIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
|
||||
typedef ALCcontext * (ALCAPIENTRY *LPALCGETCURRENTCONTEXT)( void );
|
||||
typedef ALCdevice * (ALCAPIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
|
||||
typedef ALCdevice * (ALCAPIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
|
||||
typedef ALCenum (ALCAPIENTRY *LPALCGETERROR)( ALCdevice *device );
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
|
||||
typedef void * (ALCAPIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
|
||||
typedef ALCenum (ALCAPIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
|
||||
typedef const ALCchar* (ALCAPIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
|
||||
typedef void (ALCAPIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
|
||||
///Changes for effects
|
||||
typedef void (ALAPIENTRY *LPALGENEFFECTS)(ALsizei n, ALuint *effects);
|
||||
typedef void (ALAPIENTRY *LPALDELETEEFFECTS)(ALsizei n, const ALuint *effects);
|
||||
typedef ALboolean (ALAPIENTRY *LPALISEFFECT)(ALuint effect);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTI)(ALuint effect, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTIV)(ALuint effect, ALenum param, const ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTF)(ALuint effect, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTFV)(ALuint effect, ALenum param, const ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTI)(ALuint effect, ALenum param, ALint *value);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTIV)(ALuint effect, ALenum param, ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTF)(ALuint effect, ALenum param, ALfloat *value);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTFV)(ALuint effect, ALenum param, ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALRELEASEALEFFECTS)(ALCdevice *device);
|
||||
typedef void (ALAPIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei n, ALuint *effectslots);
|
||||
typedef void (ALAPIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei n, const ALuint *effectslots);
|
||||
typedef ALboolean (ALAPIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint effectslot);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, const ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, const ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint *value);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat *value);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
|
||||
// Changes for Filters.
|
||||
typedef void (ALAPIENTRY* LPALGENFILTERS)(ALsizei n, ALuint* filter);
|
||||
typedef void (ALAPIENTRY* LPALDELETEFILTERS)(ALsizei n, const ALuint* filters);
|
||||
typedef void (ALAPIENTRY* LPALFILTERI)(ALuint filter , ALenum param, ALint value);
|
||||
// Changes for HRTF
|
||||
typedef const ALCchar* (ALCAPIENTRY* LPALCGETSTRINGISOFT)(ALCdevice* device, ALCenum param, ALint value1);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPALENABLE alEnable;
|
||||
|
|
|
|||
|
|
@ -2519,23 +2519,22 @@ void AlphaTestGLSL::processPix( Vector<ShaderComponent*> &componentList,
|
|||
//****************************************************************************
|
||||
// GlowMask
|
||||
//****************************************************************************
|
||||
|
||||
void GlowMaskGLSL::processPix( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd )
|
||||
{
|
||||
output = NULL;
|
||||
|
||||
// Get the output color... and make it black to mask out
|
||||
// glow passes rendered before us.
|
||||
//
|
||||
// The shader compiler will optimize out all the other
|
||||
// code above that doesn't contribute to the alpha mask.
|
||||
Var *color = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
|
||||
if ( color )
|
||||
output = new GenOp( " @.rgb = vec3(0);\r\n", color );
|
||||
//determine output target
|
||||
ShaderFeature::OutputTarget inTarg, outTarg;
|
||||
inTarg = outTarg = ShaderFeature::DefaultTarget;
|
||||
if (fd.features[MFT_isDeferred])
|
||||
{
|
||||
inTarg = ShaderFeature::RenderTarget1;
|
||||
outTarg = ShaderFeature::RenderTarget3;
|
||||
}
|
||||
Var* inCol = (Var*)LangElement::find(getOutputTargetVarName(inTarg));
|
||||
Var* outCol = (Var*)LangElement::find(getOutputTargetVarName(outTarg));
|
||||
output = new GenOp(" @.rgb += @.rgb*10;\r\n", outCol, inCol);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************
|
||||
// RenderTargetZero
|
||||
//****************************************************************************
|
||||
|
|
|
|||
|
|
@ -552,11 +552,9 @@ public:
|
|||
class GlowMaskGLSL : public ShaderFeatureGLSL
|
||||
{
|
||||
public:
|
||||
|
||||
void processPix( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd ) override;
|
||||
|
||||
Material::BlendOp getBlendOp() override { return Material::None; }
|
||||
|
||||
String getName() override
|
||||
{
|
||||
return "Glow Mask";
|
||||
|
|
|
|||
|
|
@ -2592,23 +2592,22 @@ void AlphaTestHLSL::processPix( Vector<ShaderComponent*> &componentList,
|
|||
//****************************************************************************
|
||||
// GlowMask
|
||||
//****************************************************************************
|
||||
|
||||
void GlowMaskHLSL::processPix( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd )
|
||||
{
|
||||
output = NULL;
|
||||
|
||||
// Get the output color... and make it black to mask out
|
||||
// glow passes rendered before us.
|
||||
//
|
||||
// The shader compiler will optimize out all the other
|
||||
// code above that doesn't contribute to the alpha mask.
|
||||
Var *color = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
|
||||
if ( color )
|
||||
output = new GenOp( " @.rgb = 0;\r\n", color );
|
||||
//determine output target
|
||||
ShaderFeature::OutputTarget inTarg, outTarg;
|
||||
inTarg = outTarg = ShaderFeature::DefaultTarget;
|
||||
if (fd.features[MFT_isDeferred])
|
||||
{
|
||||
inTarg = ShaderFeature::RenderTarget1;
|
||||
outTarg = ShaderFeature::RenderTarget3;
|
||||
}
|
||||
Var* inCol = (Var*)LangElement::find(getOutputTargetVarName(inTarg));
|
||||
Var* outCol = (Var*)LangElement::find(getOutputTargetVarName(outTarg));
|
||||
output = new GenOp(" @.rgb += @.rgb*10;\r\n", outCol, inCol);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************
|
||||
// RenderTargetZero
|
||||
//****************************************************************************
|
||||
|
|
|
|||
|
|
@ -555,11 +555,9 @@ public:
|
|||
class GlowMaskHLSL : public ShaderFeatureHLSL
|
||||
{
|
||||
public:
|
||||
|
||||
void processPix( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd ) override;
|
||||
|
||||
Material::BlendOp getBlendOp() override { return Material::None; }
|
||||
|
||||
String getName() override
|
||||
{
|
||||
return "Glow Mask";
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
// 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"
|
||||
|
|
@ -27,18 +26,13 @@
|
|||
#include "ts/tsShapeConstruct.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
// define macros required for ConvexDecomp headers
|
||||
#if defined( _WIN32 ) && !defined( WIN32 )
|
||||
#define WIN32
|
||||
#elif defined( __MACOSX__ ) && !defined( APPLE )
|
||||
#define APPLE
|
||||
#endif
|
||||
|
||||
#include "convexDecomp/NvFloatMath.h"
|
||||
#include "convexDecomp/NvConvexDecomposition.h"
|
||||
#include "convexDecomp/NvStanHull.h"
|
||||
#define ENABLE_VHACD_IMPLEMENTATION 1
|
||||
#define VHACD_DISABLE_THREADING 0
|
||||
#include "ts/vhacd/VHACD.h"
|
||||
#include <FloatMath.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const Point3F sFacePlanes[] = {
|
||||
Point3F( -1.0f, 0.0f, 0.0f ),
|
||||
Point3F( 1.0f, 0.0f, 0.0f ),
|
||||
|
|
@ -109,18 +103,18 @@ public:
|
|||
|
||||
void fitBox( U32 vertCount, const F32* verts )
|
||||
{
|
||||
CONVEX_DECOMPOSITION::fm_computeBestFitOBB( vertCount, verts, sizeof(F32)*3, (F32*)mBoxSides, (F32*)mBoxTransform );
|
||||
FLOAT_MATH::fm_computeBestFitOBB( vertCount, verts, sizeof(F32)*3, (F32*)mBoxSides, (F32*)mBoxTransform, false );
|
||||
mBoxTransform.transpose();
|
||||
}
|
||||
|
||||
void fitSphere( U32 vertCount, const F32* verts )
|
||||
{
|
||||
mSphereRadius = CONVEX_DECOMPOSITION::fm_computeBestFitSphere( vertCount, verts, sizeof(F32)*3, (F32*)mSphereCenter );
|
||||
mSphereRadius = FLOAT_MATH::fm_computeBestFitSphere( vertCount, verts, sizeof(F32)*3, (F32*)mSphereCenter );
|
||||
}
|
||||
|
||||
void fitCapsule( U32 vertCount, const F32* verts )
|
||||
{
|
||||
CONVEX_DECOMPOSITION::fm_computeBestFitCapsule( vertCount, verts, sizeof(F32)*3, mCapRadius, mCapHeight, (F32*)mCapTransform );
|
||||
FLOAT_MATH::fm_computeBestFitCapsule( vertCount, verts, sizeof(F32)*3, mCapRadius, mCapHeight, (F32*)mCapTransform );
|
||||
mCapTransform.transpose();
|
||||
}
|
||||
};
|
||||
|
|
@ -171,15 +165,15 @@ public:
|
|||
|
||||
// Box
|
||||
void addBox( const Point3F& sides, const MatrixF& mat );
|
||||
void fitOBB();
|
||||
void fitOBB(const char* target);
|
||||
|
||||
// Sphere
|
||||
void addSphere( F32 radius, const Point3F& center );
|
||||
void fitSphere();
|
||||
void fitSphere(const char* target);
|
||||
|
||||
// Capsule
|
||||
void addCapsule( F32 radius, F32 height, const MatrixF& mat );
|
||||
void fitCapsule();
|
||||
void fitCapsule(const char* target);
|
||||
|
||||
// k-DOP
|
||||
void fit10_DOP_X();
|
||||
|
|
@ -189,7 +183,7 @@ public:
|
|||
void fit26_DOP();
|
||||
|
||||
// Convex Hulls
|
||||
void fitConvexHulls( U32 depth, F32 mergeThreshold, F32 concavityThreshold, U32 maxHullVerts,
|
||||
void fitConvexHulls( const char* target, U32 depth, U32 fillType, F32 minPercentage, U32 maxHulls, U32 maxHullVerts,
|
||||
F32 boxMaxError, F32 sphereMaxError, F32 capsuleMaxError );
|
||||
};
|
||||
|
||||
|
|
@ -410,6 +404,7 @@ void MeshFit::addBox( const Point3F& sides, const MatrixF& mat )
|
|||
{
|
||||
Point3F v = mesh->mVerts[i];
|
||||
v.convolve(sides);
|
||||
mat.mulP(v);
|
||||
mesh->mVerts[i] = v;
|
||||
}
|
||||
|
||||
|
|
@ -422,23 +417,27 @@ void MeshFit::addBox( const Point3F& sides, const MatrixF& mat )
|
|||
TSMesh::__TSMeshVertexBase &vdata = mesh->mVertexData.getBase(i);
|
||||
Point3F v = vdata.vert();
|
||||
v.convolve(sides);
|
||||
mat.mulP(v);
|
||||
vdata.vert(v);
|
||||
}
|
||||
}
|
||||
|
||||
mesh->computeBounds();
|
||||
|
||||
mMeshes.increment();
|
||||
mMeshes.last().type = MeshFit::Box;
|
||||
mMeshes.last().transform = mat;
|
||||
mMeshes.last().tsmesh = mesh;
|
||||
}
|
||||
|
||||
void MeshFit::fitOBB()
|
||||
void MeshFit::fitOBB(const char* target)
|
||||
{
|
||||
mMeshes.increment();
|
||||
MatrixF worldtrans;
|
||||
worldtrans.identity();
|
||||
mShape->getNodeWorldTransform(mShape->findNode(target), &worldtrans);
|
||||
mMeshes.last().transform = worldtrans;
|
||||
|
||||
PrimFit primFitter;
|
||||
primFitter.fitBox( mVerts.size(), (F32*)mVerts.address() );
|
||||
addBox( primFitter.mBoxSides, primFitter.mBoxTransform );
|
||||
addBox( primFitter.mBoxSides, worldtrans.inverse() * primFitter.mBoxTransform );
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
|
|
@ -449,27 +448,50 @@ void MeshFit::addSphere( F32 radius, const Point3F& center )
|
|||
if ( !mesh )
|
||||
return;
|
||||
|
||||
for ( S32 i = 0; i < mesh->mVertexData.size(); i++ )
|
||||
{
|
||||
TSMesh::__TSMeshVertexBase &vdata = mesh->mVertexData.getBase(i);
|
||||
Point3F v = vdata.vert();
|
||||
vdata.vert( v * radius );
|
||||
}
|
||||
mesh->computeBounds();
|
||||
MatrixF sphereMat(true);
|
||||
sphereMat.setPosition(center);
|
||||
|
||||
mMeshes.increment();
|
||||
MeshFit::Mesh& lastMesh = mMeshes.last();
|
||||
lastMesh.type = MeshFit::Sphere;
|
||||
lastMesh.transform.identity();
|
||||
lastMesh.transform.setPosition(center);
|
||||
lastMesh.tsmesh = mesh;
|
||||
if (mesh->mVerts.size() > 0)
|
||||
{
|
||||
for (S32 i = 0; i < mesh->mVerts.size(); i++)
|
||||
{
|
||||
Point3F v = mesh->mVerts[i];
|
||||
sphereMat.mulP(v);
|
||||
mesh->mVerts[i] = v * radius;
|
||||
}
|
||||
|
||||
mesh->mVertexData.setReady(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < mesh->mVertexData.size(); i++)
|
||||
{
|
||||
TSMesh::__TSMeshVertexBase& vdata = mesh->mVertexData.getBase(i);
|
||||
Point3F v = vdata.vert();
|
||||
sphereMat.mulP(v);
|
||||
vdata.vert(v * radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mesh->computeBounds();
|
||||
mMeshes.last().type = MeshFit::Sphere;
|
||||
mMeshes.last().tsmesh = mesh;
|
||||
}
|
||||
|
||||
void MeshFit::fitSphere()
|
||||
void MeshFit::fitSphere(const char* target)
|
||||
{
|
||||
mMeshes.increment();
|
||||
MatrixF worldtrans;
|
||||
worldtrans.identity();
|
||||
mShape->getNodeWorldTransform(mShape->findNode(target), &worldtrans);
|
||||
mMeshes.last().transform = worldtrans;
|
||||
|
||||
PrimFit primFitter;
|
||||
primFitter.fitSphere( mVerts.size(), (F32*)mVerts.address() );
|
||||
addSphere( primFitter.mSphereRadius, primFitter.mSphereCenter );
|
||||
worldtrans.inverse();
|
||||
worldtrans.mulP(primFitter.mSphereCenter);
|
||||
addSphere( primFitter.mSphereRadius, primFitter.mSphereCenter);
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
|
|
@ -480,27 +502,52 @@ void MeshFit::addCapsule( F32 radius, F32 height, const MatrixF& mat )
|
|||
if ( !mesh )
|
||||
return;
|
||||
|
||||
MatrixF capTrans = mMeshes.last().transform * mat;
|
||||
// Translate and scale the mesh verts
|
||||
height = mMax( 0, height );
|
||||
F32 offset = ( height / ( 2 * radius ) ) - 0.5f;
|
||||
for ( S32 i = 0; i < mesh->mVertexData.size(); i++ )
|
||||
if (mesh->mVerts.size() > 0)
|
||||
{
|
||||
Point3F v = mesh->mVertexData.getBase(i).vert();
|
||||
v.y += ( ( v.y > 0 ) ? offset : -offset );
|
||||
mesh->mVertexData.getBase(i).vert( v * radius );
|
||||
for (S32 i = 0; i < mesh->mVerts.size(); i++)
|
||||
{
|
||||
Point3F v = mesh->mVerts[i];
|
||||
v.y += ((v.y > 0) ? offset : -offset);
|
||||
capTrans.mulP(v);
|
||||
mesh->mVerts[i] = v * radius;
|
||||
}
|
||||
|
||||
mesh->mVertexData.setReady(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < mesh->mVertexData.size(); i++)
|
||||
{
|
||||
TSMesh::__TSMeshVertexBase& vdata = mesh->mVertexData.getBase(i);
|
||||
Point3F v = vdata.vert();
|
||||
v.y += ((v.y > 0) ? offset : -offset);
|
||||
capTrans.mulP(v);
|
||||
vdata.vert(v * radius);
|
||||
}
|
||||
}
|
||||
|
||||
mesh->computeBounds();
|
||||
|
||||
mMeshes.increment();
|
||||
|
||||
mMeshes.last().type = MeshFit::Capsule;
|
||||
mMeshes.last().transform = mat;
|
||||
mMeshes.last().tsmesh = mesh;
|
||||
}
|
||||
|
||||
void MeshFit::fitCapsule()
|
||||
void MeshFit::fitCapsule(const char* target)
|
||||
{
|
||||
mMeshes.increment();
|
||||
MatrixF worldtrans;
|
||||
worldtrans.identity();
|
||||
mShape->getNodeWorldTransform(mShape->findNode(target), &worldtrans);
|
||||
mMeshes.last().transform = worldtrans;
|
||||
|
||||
PrimFit primFitter;
|
||||
primFitter.fitCapsule( mVerts.size(), (F32*)mVerts.address() );
|
||||
|
||||
addCapsule( primFitter.mCapRadius, primFitter.mCapHeight, primFitter.mCapTransform );
|
||||
}
|
||||
|
||||
|
|
@ -572,6 +619,7 @@ void MeshFit::fitK_DOP( const Vector<Point3F>& planes )
|
|||
// Collect the intersection points of any 3 planes that lie inside
|
||||
// the maximum distances found above
|
||||
Vector<Point3F> points;
|
||||
Vector<U32> pointIndices;
|
||||
for ( S32 i = 0; i < planes.size()-2; i++ )
|
||||
{
|
||||
for ( S32 j = i+1; j < planes.size()-1; j++ )
|
||||
|
|
@ -599,91 +647,147 @@ void MeshFit::fitK_DOP( const Vector<Point3F>& planes )
|
|||
}
|
||||
}
|
||||
|
||||
if ( addPoint )
|
||||
points.push_back( p );
|
||||
if (addPoint)
|
||||
{
|
||||
points.push_back(p);
|
||||
pointIndices.push_back(points.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a convex hull from the point set
|
||||
CONVEX_DECOMPOSITION::HullDesc hd;
|
||||
hd.mVcount = points.size();
|
||||
hd.mVertices = (F32*)points.address();
|
||||
hd.mVertexStride = sizeof(Point3F);
|
||||
hd.mMaxVertices = 64;
|
||||
hd.mSkinWidth = 0.0f;
|
||||
VHACD::IVHACD::Parameters p;
|
||||
p.m_fillMode = VHACD::FillMode::FLOOD_FILL;
|
||||
p.m_maxNumVerticesPerCH = 64;
|
||||
p.m_shrinkWrap = true;
|
||||
p.m_maxRecursionDepth = 64;
|
||||
p.m_minimumVolumePercentErrorAllowed = 10;
|
||||
p.m_resolution = 10000;
|
||||
p.m_maxConvexHulls = 1;
|
||||
|
||||
CONVEX_DECOMPOSITION::HullLibrary hl;
|
||||
CONVEX_DECOMPOSITION::HullResult result;
|
||||
hl.CreateConvexHull( hd, result );
|
||||
VHACD::IVHACD* iface = VHACD::CreateVHACD();
|
||||
|
||||
iface->Compute((F32*)points.address(), points.size(), (U32*)pointIndices.address(), pointIndices.size() / 3, p);
|
||||
|
||||
// safety loop.
|
||||
while (!iface->IsReady())
|
||||
{
|
||||
Platform::sleep(1000);
|
||||
}
|
||||
|
||||
// we only get the 1 in dop?
|
||||
VHACD::IVHACD::ConvexHull ch;
|
||||
iface->GetConvexHull(0, ch);
|
||||
|
||||
// Create TSMesh from convex hull
|
||||
mMeshes.increment();
|
||||
MeshFit::Mesh& lastMesh = mMeshes.last();
|
||||
lastMesh.type = MeshFit::Hull;
|
||||
lastMesh.transform.identity();
|
||||
lastMesh.tsmesh = createTriMesh(result.mOutputVertices, result.mNumOutputVertices,
|
||||
result.mIndices, result.mNumFaces );
|
||||
|
||||
U32* indices = new U32[ch.m_triangles.size() * 3];
|
||||
for (U32 ind = 0; ind < ch.m_triangles.size(); ind++)
|
||||
{
|
||||
indices[ind * 3 + 0] = ch.m_triangles[ind].mI0;
|
||||
indices[ind * 3 + 1] = ch.m_triangles[ind].mI1;
|
||||
indices[ind * 3 + 2] = ch.m_triangles[ind].mI2;
|
||||
}
|
||||
|
||||
F32* resultPts = new F32[ch.m_points.size() * 3];
|
||||
for (U32 pts = 0; pts < ch.m_points.size(); pts++)
|
||||
{
|
||||
resultPts[pts * 3 + 0] = ch.m_points[pts].mX;
|
||||
resultPts[pts * 3 + 1] = ch.m_points[pts].mY;
|
||||
resultPts[pts * 3 + 2] = ch.m_points[pts].mZ;
|
||||
}
|
||||
|
||||
lastMesh.tsmesh = createTriMesh(resultPts, (S32)ch.m_points.size(),
|
||||
indices, (S32)ch.m_triangles.size());
|
||||
lastMesh.tsmesh->computeBounds();
|
||||
|
||||
iface->Release();
|
||||
|
||||
delete[] resultPts;
|
||||
delete[] indices;
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
// Best-fit set of convex hulls
|
||||
void MeshFit::fitConvexHulls( U32 depth, F32 mergeThreshold, F32 concavityThreshold, U32 maxHullVerts,
|
||||
void MeshFit::fitConvexHulls(const char* target, U32 depth, U32 fillType, F32 minPercentage, U32 maxHulls, U32 maxHullVerts,
|
||||
F32 boxMaxError, F32 sphereMaxError, F32 capsuleMaxError )
|
||||
{
|
||||
const F32 SkinWidth = 0.0f;
|
||||
const F32 SplitThreshold = 2.0f;
|
||||
VHACD::IVHACD::Parameters p;
|
||||
p.m_fillMode = (VHACD::FillMode)fillType;
|
||||
p.m_maxNumVerticesPerCH = maxHullVerts;
|
||||
p.m_shrinkWrap = true;
|
||||
p.m_maxRecursionDepth = depth;
|
||||
p.m_minimumVolumePercentErrorAllowed = minPercentage;
|
||||
p.m_resolution = 10000;
|
||||
p.m_maxConvexHulls = maxHulls;
|
||||
|
||||
CONVEX_DECOMPOSITION::iConvexDecomposition *ic = CONVEX_DECOMPOSITION::createConvexDecomposition();
|
||||
VHACD::IVHACD* iface = VHACD::CreateVHACD_ASYNC();
|
||||
|
||||
for ( S32 i = 0; i < mIndices.size(); i += 3 )
|
||||
iface->Compute((F32*)mVerts.address(), mVerts.size(), mIndices.address(), mIndices.size() / 3, p);
|
||||
|
||||
// safety loop.
|
||||
while (!iface->IsReady())
|
||||
{
|
||||
ic->addTriangle( (F32*)mVerts[mIndices[i]],
|
||||
(F32*)mVerts[mIndices[i+1]],
|
||||
(F32*)mVerts[mIndices[i+2]] );
|
||||
Platform::sleep(1000);
|
||||
}
|
||||
|
||||
ic->computeConvexDecomposition(
|
||||
SkinWidth,
|
||||
depth,
|
||||
maxHullVerts,
|
||||
concavityThreshold,
|
||||
mergeThreshold,
|
||||
SplitThreshold,
|
||||
true,
|
||||
false,
|
||||
false );
|
||||
|
||||
// Add a TSMesh for each hull
|
||||
for ( S32 i = 0; i < ic->getHullCount(); i++ )
|
||||
for ( S32 i = 0; i < iface->GetNConvexHulls(); i++ )
|
||||
{
|
||||
CONVEX_DECOMPOSITION::ConvexHullResult result;
|
||||
ic->getConvexHullResult( i, result );
|
||||
|
||||
VHACD::IVHACD::ConvexHull ch;
|
||||
iface->GetConvexHull(i, ch);
|
||||
mMeshes.increment();
|
||||
MeshFit::Mesh& lastMesh = mMeshes.last();
|
||||
eMeshType meshType = MeshFit::Hull;
|
||||
MatrixF worldtrans;
|
||||
worldtrans.identity();
|
||||
mShape->getNodeWorldTransform(mShape->findNode(target), &worldtrans);
|
||||
lastMesh.transform = worldtrans;
|
||||
|
||||
worldtrans.inverse();
|
||||
// Compute error between actual mesh and fitted primitives
|
||||
F32* points = new F32[ch.m_points.size() * 3];
|
||||
for (U32 pt = 0; pt < ch.m_points.size(); pt++)
|
||||
{
|
||||
Point3F point(ch.m_points[pt].mX, ch.m_points[pt].mY, ch.m_points[pt].mZ);
|
||||
worldtrans.mulP(point);
|
||||
points[pt * 3 + 0] = point.x;
|
||||
points[pt * 3 + 1] = point.y;
|
||||
points[pt * 3 + 2] = point.z;
|
||||
}
|
||||
|
||||
U32* indices = new U32[ch.m_triangles.size() * 3];
|
||||
for (U32 ind = 0; ind < ch.m_triangles.size(); ind++)
|
||||
{
|
||||
indices[ind * 3 + 0] = ch.m_triangles[ind].mI0;
|
||||
indices[ind * 3 + 1] = ch.m_triangles[ind].mI1;
|
||||
indices[ind * 3 + 2] = ch.m_triangles[ind].mI2;
|
||||
}
|
||||
|
||||
// Check if we can use a box, sphere or capsule primitive for this hull
|
||||
if (( boxMaxError > 0 ) || ( sphereMaxError > 0 ) || ( capsuleMaxError > 0 ))
|
||||
{
|
||||
// Compute error between actual mesh and fitted primitives
|
||||
F32 meshVolume = CONVEX_DECOMPOSITION::fm_computeMeshVolume( result.mVertices, result.mTcount, result.mIndices );
|
||||
F32 meshVolume = FLOAT_MATH::fm_computeMeshVolume(points, ch.m_triangles.size(), indices);
|
||||
PrimFit primFitter;
|
||||
|
||||
F32 boxError = 100.0f, sphereError = 100.0f, capsuleError = 100.0f;
|
||||
F32 boxError = 100.0f, sphereError = 100.0f, capsuleError = 100.0;
|
||||
if ( boxMaxError > 0 )
|
||||
{
|
||||
primFitter.fitBox( result.mVcount, result.mVertices );
|
||||
primFitter.fitBox(ch.m_points.size(), points);
|
||||
boxError = 100.0f * ( 1.0f - ( meshVolume / primFitter.getBoxVolume() ) );
|
||||
}
|
||||
if ( sphereMaxError > 0 )
|
||||
{
|
||||
primFitter.fitSphere( result.mVcount, result.mVertices );
|
||||
sphereError = 100.0f * ( 1.0f - ( meshVolume / primFitter.getSphereVolume() ) );
|
||||
primFitter.fitSphere(ch.m_points.size(), points);
|
||||
sphereError = 100.0f * ( 1.0f - ( meshVolume / primFitter.getSphereVolume()));
|
||||
}
|
||||
if ( capsuleMaxError > 0 )
|
||||
{
|
||||
primFitter.fitCapsule( result.mVcount, result.mVertices );
|
||||
primFitter.fitCapsule(ch.m_points.size(), points);
|
||||
capsuleError = 100.0f * ( 1.0f - ( meshVolume / primFitter.getCapsuleVolume() ) );
|
||||
}
|
||||
|
||||
|
|
@ -718,16 +822,17 @@ void MeshFit::fitConvexHulls( U32 depth, F32 mergeThreshold, F32 concavityThresh
|
|||
if ( meshType == MeshFit::Hull )
|
||||
{
|
||||
// Create TSMesh from convex hull
|
||||
mMeshes.increment();
|
||||
MeshFit::Mesh& lastMesh = mMeshes.last();
|
||||
lastMesh.type = MeshFit::Hull;
|
||||
lastMesh.transform.identity();
|
||||
lastMesh.tsmesh = createTriMesh(result.mVertices, result.mVcount, result.mIndices, result.mTcount);
|
||||
lastMesh.tsmesh = createTriMesh(points, ch.m_points.size(), indices, ch.m_triangles.size());
|
||||
lastMesh.tsmesh->computeBounds();
|
||||
|
||||
}
|
||||
|
||||
delete[] points;
|
||||
delete[] indices;
|
||||
}
|
||||
|
||||
CONVEX_DECOMPOSITION::releaseConvexDecomposition( ic );
|
||||
iface->Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -831,8 +936,8 @@ DefineTSShapeConstructorMethod( addPrimitive, bool, ( const char* meshName, cons
|
|||
return true;
|
||||
}}
|
||||
|
||||
DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char* type, const char* target, S32 depth, F32 merge, F32 concavity, S32 maxVerts, F32 boxMaxError, F32 sphereMaxError, F32 capsuleMaxError ), ( 4, 30, 30, 32, 0, 0, 0 ),
|
||||
( size, type, target, depth, merge, concavity, maxVerts, boxMaxError, sphereMaxError, capsuleMaxError ), false,
|
||||
DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char* type, const char* target, S32 depth, F32 minPercentage, S32 maxHulls, S32 maxVerts, F32 boxMaxError, F32 sphereMaxError, F32 capsuleMaxError, const char* fillMode), ( "bounds", 4, 10, 30, 32, 0, 0, 0, "flood fill"),
|
||||
( size, type, target, depth, minPercentage, maxHulls, maxVerts, boxMaxError, sphereMaxError, capsuleMaxError, fillMode), false,
|
||||
"Autofit a mesh primitive or set of convex hulls to the shape geometry. Hulls "
|
||||
"may optionally be converted to boxes, spheres and/or capsules based on their "
|
||||
"volume.\n"
|
||||
|
|
@ -840,23 +945,20 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char
|
|||
"@param type one of: box, sphere, capsule, 10-dop x, 10-dop y, 10-dop z, 18-dop, "
|
||||
"26-dop, convex hulls. See the Shape Editor documentation for more details "
|
||||
"about these types.\n"
|
||||
"@param target geometry to fit collision mesh(es) to; either \"bounds\" (for the "
|
||||
"whole shape), or the name of an object in the shape\n"
|
||||
"@param target geometry to fit collision mesh(es) to; either \"bounds\" (for the whole shape), or the name of an object in the shape\n"
|
||||
"@param depth maximum split recursion depth (hulls only)\n"
|
||||
"@param merge volume % threshold used to merge hulls together (hulls only)\n"
|
||||
"@param concavity volume % threshold used to detect concavity (hulls only)\n"
|
||||
"@param minPercentage volume % error threshold (hulls only)\n"
|
||||
"@param maxHulls allowed to be generated (hulls only)\n"
|
||||
"@param maxVerts maximum number of vertices per hull (hulls only)\n"
|
||||
"@param boxMaxError max % volume difference for a hull to be converted to a "
|
||||
"box (hulls only)\n"
|
||||
"@param sphereMaxError max % volume difference for a hull to be converted to "
|
||||
"a sphere (hulls only)\n"
|
||||
"@param capsuleMaxError max % volume difference for a hull to be converted to "
|
||||
"a capsule (hulls only)\n"
|
||||
"@param boxMaxError max % volume difference for a hull to be converted to a box (hulls only)\n"
|
||||
"@param sphereMaxError max % volume difference for a hull to be converted to a sphere (hulls only)\n"
|
||||
"@param capsuleMaxError max % volume difference for a hull to be converted to a capsule (hulls only)\n"
|
||||
"@param fillMode method for filling the voxels in the volume (hulls only)\n"
|
||||
"@return true if successful, false otherwise\n\n"
|
||||
"@tsexample\n"
|
||||
"%this.addCollisionDetail( -1, \"box\", \"bounds\" );\n"
|
||||
"%this.addCollisionDetail( -1, \"convex hulls\", \"bounds\", 4, 30, 30, 32, 0, 0, 0 );\n"
|
||||
"%this.addCollisionDetail( -1, \"convex hulls\", \"bounds\", 4, 30, 30, 32, 50, 50, 50 );\n"
|
||||
"%this.addCollisionDetail( -1, \"convex hulls\", \"bounds\", 4, 10, 30, 32, 0, 0, 0 );\n"
|
||||
"%this.addCollisionDetail( -1, \"convex hulls\", \"bounds\",\"flood fill\", 4, 10, 30, 32, 50, 50, 50 );\n"
|
||||
"@endtsexample\n" )
|
||||
{
|
||||
MeshFit fit( mShape );
|
||||
|
|
@ -869,11 +971,11 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char
|
|||
}
|
||||
|
||||
if ( !dStricmp( type, "box" ) )
|
||||
fit.fitOBB();
|
||||
fit.fitOBB(target);
|
||||
else if ( !dStricmp( type, "sphere" ) )
|
||||
fit.fitSphere();
|
||||
fit.fitSphere(target);
|
||||
else if ( !dStricmp( type, "capsule" ) )
|
||||
fit.fitCapsule();
|
||||
fit.fitCapsule(target);
|
||||
else if ( !dStricmp( type, "10-dop x" ) )
|
||||
fit.fit10_DOP_X();
|
||||
else if ( !dStricmp( type, "10-dop y" ) )
|
||||
|
|
@ -886,7 +988,13 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char
|
|||
fit.fit26_DOP();
|
||||
else if ( !dStricmp( type, "convex hulls" ) )
|
||||
{
|
||||
fit.fitConvexHulls( depth, merge, concavity, maxVerts,
|
||||
|
||||
U32 fillType = 0;
|
||||
if (!dStricmp(fillMode, "surface only"))
|
||||
fillType = 1;
|
||||
if (!dStricmp(fillMode, "raycast fill"))
|
||||
fillType = 2;
|
||||
fit.fitConvexHulls( target, depth, fillType, minPercentage, maxHulls, maxVerts,
|
||||
boxMaxError, sphereMaxError, capsuleMaxError );
|
||||
}
|
||||
else
|
||||
|
|
@ -917,6 +1025,9 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char
|
|||
mShape->getNodeWorldTransform( nodeIndex, &mat );
|
||||
if ( !mat.isIdentity() )
|
||||
setNodeTransform( colNodeName, TransformF::Identity );
|
||||
|
||||
// clean node commands that are related to this target.
|
||||
cleanTargetNodes(colNodeName, target);
|
||||
}
|
||||
|
||||
// Add the meshes to the shape =>
|
||||
|
|
@ -934,22 +1045,32 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char
|
|||
default: objName = "ColConvex"; break;
|
||||
}
|
||||
|
||||
for ( S32 suffix = i; suffix != 0; suffix /= 26 )
|
||||
objName += ('A' + ( suffix % 26 ) );
|
||||
String meshName = objName + String::ToString( "%d", size );
|
||||
S32 suffix = i;
|
||||
while (true)
|
||||
{
|
||||
String tempName = objName;
|
||||
|
||||
for (S32 s = suffix; s != 0; s /= 26) {
|
||||
tempName += ('A' + (s % 26));
|
||||
}
|
||||
|
||||
if (mShape->findName(tempName) == -1)
|
||||
break;
|
||||
|
||||
suffix++;
|
||||
}
|
||||
|
||||
for (S32 s = suffix; s != 0; s /= 26) {
|
||||
objName += ('A' + (s % 26));
|
||||
}
|
||||
|
||||
String meshName = objName + String::ToString("%d", size);
|
||||
|
||||
mShape->addMesh( mesh->tsmesh, meshName );
|
||||
|
||||
// Add a node for this object if needed (non-identity transform)
|
||||
if ( mesh->transform.isIdentity() )
|
||||
{
|
||||
mShape->setObjectNode( objName, colNodeName );
|
||||
}
|
||||
else
|
||||
{
|
||||
addNode( meshName, colNodeName, TransformF( mesh->transform ) );
|
||||
mShape->setObjectNode( objName, meshName );
|
||||
}
|
||||
addNode( meshName, colNodeName, TransformF( mesh->transform ), false, target);
|
||||
mShape->setObjectNode( objName, meshName );
|
||||
}
|
||||
|
||||
mShape->init();
|
||||
|
|
|
|||
|
|
@ -1111,8 +1111,8 @@ DefineTSShapeConstructorMethod(renameNode, bool, (const char* oldName, const cha
|
|||
return true;
|
||||
}}
|
||||
|
||||
DefineTSShapeConstructorMethod(addNode, bool, (const char* name, const char* parentName, TransformF txfm, bool isWorld), (TransformF::Identity, false),
|
||||
(name, parentName, txfm, isWorld), false,
|
||||
DefineTSShapeConstructorMethod(addNode, bool, (const char* name, const char* parentName, TransformF txfm, bool isWorld, const char* target), (TransformF::Identity, false, ""),
|
||||
(name, parentName, txfm, isWorld, target), false,
|
||||
"Add a new node.\n"
|
||||
"@param name name for the new node (must not already exist)\n"
|
||||
"@param parentName name of an existing node to be the parent of the new node. "
|
||||
|
|
@ -1125,7 +1125,7 @@ DefineTSShapeConstructorMethod(addNode, bool, (const char* name, const char* par
|
|||
"@tsexample\n"
|
||||
"%this.addNode( \"Nose\", \"Bip01 Head\", \"0 2 2 0 0 1 0\" );\n"
|
||||
"%this.addNode( \"myRoot\", \"\", \"0 0 4 0 0 1 1.57\" );\n"
|
||||
"%this.addNode( \"Nodes\", \"Bip01 Head\", \"0 2 0 0 0 1 0\", true );\n"
|
||||
"%this.addNode( \"Nodes\", \"Bip01 Head\", \"0 2 0 0 0 1 0\", true,\"Bounds\");\n"
|
||||
"@endtsexample\n")
|
||||
{
|
||||
Point3F pos(txfm.getPosition());
|
||||
|
|
@ -2433,6 +2433,7 @@ void TSShapeConstructor::ChangeSet::add( TSShapeConstructor::ChangeSet::Command&
|
|||
// Detail level commands
|
||||
case CmdRenameDetailLevel: addCommand = addCmd_renameDetailLevel(cmd); break;
|
||||
case CmdRemoveDetailLevel: addCommand = addCmd_removeDetailLevel(cmd); break;
|
||||
case CmdAddCollisionDetail: addCommand = addCmd_addDetailLevel(cmd); break;
|
||||
case CmdSetDetailLevelSize: addCommand = addCmd_setDetailSize(cmd); break;
|
||||
case CmdAddImposter: addCommand = addCmd_addImposter(cmd); break;
|
||||
case CmdRemoveImposter: addCommand = addCmd_removeImposter(cmd); break;
|
||||
|
|
@ -2538,14 +2539,6 @@ bool TSShapeConstructor::ChangeSet::addCmd_renameNode(const TSShapeConstructor::
|
|||
Command& cmd = mCommands[index];
|
||||
switch (cmd.type)
|
||||
{
|
||||
case CmdAddNode:
|
||||
if (namesEqual(cmd.argv[0], newCmd.argv[0]))
|
||||
{
|
||||
cmd.argv[0] = newCmd.argv[1]; // Replace initial name argument
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case CmdRenameNode:
|
||||
if (namesEqual(cmd.argv[1], newCmd.argv[0]))
|
||||
{
|
||||
|
|
@ -3302,6 +3295,28 @@ bool TSShapeConstructor::ChangeSet::addCmd_renameDetailLevel(const TSShapeConstr
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TSShapeConstructor::ChangeSet::addCmd_addDetailLevel(const TSShapeConstructor::ChangeSet::Command& newCmd)
|
||||
{
|
||||
const char* targ = newCmd.argv[2];
|
||||
for (S32 index = mCommands.size() - 1; index >= 0; index--)
|
||||
{
|
||||
Command& cmd = mCommands[index];
|
||||
switch (cmd.type)
|
||||
{
|
||||
case CmdAddCollisionDetail:
|
||||
if (!dStricmp(targ, cmd.argv[2]))
|
||||
{
|
||||
mCommands.erase(index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TSShapeConstructor::ChangeSet::addCmd_removeDetailLevel(const TSShapeConstructor::ChangeSet::Command& newCmd)
|
||||
{
|
||||
// Remove any previous command that references the detail, but stop if a mesh
|
||||
|
|
@ -3480,3 +3495,32 @@ void TSShapeConstructor::onActionPerformed()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TSShapeConstructor::cleanTargetNodes(const char* detail, const char* target)
|
||||
{
|
||||
for (S32 index = mChangeSet.mCommands.size() - 1; index >= 0; index--)
|
||||
{
|
||||
ChangeSet::Command& cmd = mChangeSet.mCommands[index];
|
||||
switch (cmd.type)
|
||||
{
|
||||
case ChangeSet::eCommandType::CmdAddNode:
|
||||
// node name starts with col
|
||||
if (dStrStartsWith(cmd.argv[0], "Col"))
|
||||
{
|
||||
// node has the same detail and same target
|
||||
if (!dStricmp(detail, cmd.argv[1]) && !dStricmp(target, cmd.argv[4]))
|
||||
{
|
||||
// now remove it from shape
|
||||
mShape->removeMesh(cmd.argv[0]);
|
||||
mShape->removeNode(cmd.argv[0]);
|
||||
|
||||
// erase the command
|
||||
mChangeSet.mCommands.erase(index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public:
|
|||
{
|
||||
eCommandType type; // Command type
|
||||
StringTableEntry name; // Command name
|
||||
static const U32 MAX_ARGS = 10;
|
||||
static const U32 MAX_ARGS = 11;
|
||||
String argv[MAX_ARGS]; // Command arguments
|
||||
S32 argc; // Number of arguments
|
||||
Command() : type(CmdInvalid), name(0), argc(0) { }
|
||||
|
|
@ -142,6 +142,7 @@ public:
|
|||
bool addCmd_setBounds(const Command& newCmd);
|
||||
|
||||
bool addCmd_renameDetailLevel(const Command& newCmd);
|
||||
bool addCmd_addDetailLevel(const Command& newCmd);
|
||||
bool addCmd_removeDetailLevel(const Command& newCmd);
|
||||
bool addCmd_setDetailSize(const Command& newCmd);
|
||||
bool addCmd_addImposter(const Command& newCmd);
|
||||
|
|
@ -253,6 +254,7 @@ public:
|
|||
|
||||
/// @name Nodes
|
||||
///@{
|
||||
void cleanTargetNodes(const char* detail, const char* target);
|
||||
S32 getNodeCount();
|
||||
S32 getNodeIndex(const char* name);
|
||||
const char* getNodeName(S32 index);
|
||||
|
|
@ -265,7 +267,7 @@ public:
|
|||
TransformF getNodeTransform(const char* name, bool isWorld = false);
|
||||
bool setNodeTransform(const char* name, TransformF txfm, bool isWorld = false);
|
||||
bool renameNode(const char* oldName, const char* newName);
|
||||
bool addNode(const char* name, const char* parentName, TransformF txfm = TransformF::Identity, bool isWorld = false);
|
||||
bool addNode(const char* name, const char* parentName, TransformF txfm = TransformF::Identity, bool isWorld = false, const char* target = "");
|
||||
bool removeNode(const char* name);
|
||||
///@}
|
||||
|
||||
|
|
@ -315,7 +317,7 @@ public:
|
|||
const char* getImposterSettings(S32 index);
|
||||
S32 addImposter(S32 size, S32 equatorSteps, S32 polarSteps, S32 dl, S32 dim, bool includePoles, F32 polarAngle);
|
||||
bool removeImposter();
|
||||
bool addCollisionDetail(S32 size, const char* type, const char* target, S32 depth = 4, F32 merge = 30.0f, F32 concavity = 30.0f, S32 maxVerts = 32, F32 boxMaxError = 0, F32 sphereMaxError = 0, F32 capsuleMaxError = 0);
|
||||
bool addCollisionDetail(S32 size, const char* type, const char* target, S32 depth = 4, F32 minPercentage = 10.0f, S32 maxHull = 30, S32 maxVerts = 32, F32 boxMaxError = 0, F32 sphereMaxError = 0, F32 capsuleMaxError = 0, const char* fillMode = "flood fill");
|
||||
///@}
|
||||
|
||||
/// @name Sequences
|
||||
|
|
|
|||
8447
Engine/source/ts/vhacd/VHACD.h
Normal file
8447
Engine/source/ts/vhacd/VHACD.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -52,6 +52,7 @@ public:
|
|||
const UTF8 *value(const UTF8 *settingName, const UTF8 *defaultValue = "");
|
||||
void remove(const UTF8 *settingName, bool includeDefaults = false);
|
||||
void clearAllFields();
|
||||
void write(Stream& stream, U32 tabStop, U32 flags = 0) override { Con::errorf("Settings: Can Not write a file interface object to a file"); }; //Don't allow writing Settings objects *to* files
|
||||
bool write();
|
||||
bool read();
|
||||
void readLayer(SimXMLDocument *document, String groupStack = String(""));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue