irei1as Posted July 27, 2016 Share Posted July 27, 2016 (edited) Small code change to make the decals from bullet shots to dissapear if the object under it dissapears (or moves away or the shape changes and under the shots there is nothing anymore).I'm not sure if it works for multiplayer and it may be heavy on resources if there are a lot of decals active.(Related to http://forums.torque3d.org/viewtopic.php?f=12&t=733 )Example_ A Red cube becomes a smaller green shape after a few bullets impact.Before the code change some decals keep hanging:http://i.imgur.com/RoWzqdB.pngWith this code change the decals without base disappear:http://i.imgur.com/XkkwlBR.png(Note: The decals need to have lifetime. Permanent decals keep hanging.)--Code changes--In decalInstance.h add after DecalData *mDataBlock; this line: S32 surfaceObject; Then, also in that file, replace DecalInstance() : mId(-1) {} with DecalInstance() : mId(-1), surfaceObject(0) {} In projectile.cpp find: // Client (impact) decal. if ( mDataBlock->decal ) gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal); And replace it with: // Client (impact) decal. DecalInstance * decalReturn = NULL; if ( mDataBlock->decal ) decalReturn = gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal); if(decalReturn) { RayInfo rInfo; Point3F oldPosition = p; Point3F newPosition = p - (n*0.05); // Raycast the abstract PhysicsWorld if a PhysicsPlugin exists. bool hit = false; //disableCollision(); //let's ignore bullet physics and go the poor castRay hit = gClientContainer.castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo); //enableCollision(); //if(rInfo.object has some quality that enables this check) { if(hit) decalReturn->surfaceObject = (rInfo.object)->getId(); //else, surfaceObject keeps being 0 //} ----- closing of if(rInfo.object has some quality...) } --------------------------------- In decalManager.cpp find: if ( dinst->mVisibility <= 0.0f ) { mDecalQueue.erase_fast( i ); removeDecal( dinst ); i--; continue; } } And add after that: if(dinst->surfaceObject) { if(!Sim::findObject(dinst->surfaceObject)) { //the object that was under the decal does not exist anymore mDecalQueue.erase_fast( i ); removeDecal( dinst ); i--; continue; } RayInfo rInfo; Point3F oldPosition = dinst->mPosition; Point3F newPosition = dinst->mPosition - (dinst->mNormal*0.05); bool hit = false; //disableCollision(); //let's ignore bullet physics and go the poor castRay in the client hit = gClientContainer.castRay(oldPosition, newPosition, (PlayerObjectType | VehicleObjectType) | (TerrainObjectType | StaticShapeObjectType), &rInfo); //enableCollision(); if(!hit || ((rInfo.object)->getId() != dinst->surfaceObject)) { //the object that was under the decal moved or transformed and the decal is in the air mDecalQueue.erase_fast( i ); removeDecal( dinst ); i--; continue; } } They should end as:source\T3D\decal\decalInstance.h : http://pastebin.com/43QiN2dfsource\T3D\projectile.cpp : http://pastebin.com/B170LDAmsource\T3D\decal\decalManager.cpp : http://pastebin.com/r1U5fJ5F Edited July 29, 2016 by irei1as Quote Link to comment Share on other sites More sharing options...
rlranft Posted July 27, 2016 Share Posted July 27, 2016 Hmm, that's a good question - I thought these decals were handled client-side, but in source it references gDecalManager so perhaps these are server-side and replicated.... Quote Link to comment Share on other sites More sharing options...
Azaezel Posted July 27, 2016 Share Posted July 27, 2016 https://github.com/GarageGames/Torque3D/pull/1459 yes. replicated. Quote Link to comment Share on other sites More sharing options...
flysouth Posted July 28, 2016 Share Posted July 28, 2016 Thanks for this speedy fix, although I think that it would also be good if ShapeBase also had a decalType like TSStatic so that one could decide a decal type if any. Then if it was set to "none" a decal wou;d never be placed on it.Do fixes like this automatically get put in to future engine releases? Quote Link to comment Share on other sites More sharing options...
Azaezel Posted July 28, 2016 Share Posted July 28, 2016 already in. that was pointing at the area where client replication occurs. Quote Link to comment Share on other sites More sharing options...
irei1as Posted July 29, 2016 Author Share Posted July 29, 2016 Do fixes like this automatically get put in to future engine releases?The fix @Azaezel points is already in, of course, but if you mean this resource... I don't think it's all-purpose enough to be included, it's kinda heavy with all those castRay and I'm not sure if it's 100% bug-free.You really should fully test it before you add it (specially multiplayer if you plan to use it with that).But, hey, if enough people check it and they think it's worth it I'm ok with a pull request to add it to the main code.As side note, let me add a few images to the first post so it's a bit clearer what the code does. Quote Link to comment Share on other sites More sharing options...
Azaezel Posted July 29, 2016 Share Posted July 29, 2016 @irei1as could see at least checking if surfaceObject still exists if you'd wanna throw over a minimalist interpretation without the castrays. you're right about tree-searching for a lot of decals potentially getting a bit hairy, but i'd think a simple 'this still valid' test would be ok preformance wise. Quote Link to comment Share on other sites More sharing options...
flysouth Posted July 29, 2016 Share Posted July 29, 2016 @Azaezel already in. that was pointing at the area where client replication occurs. are you saying the decalType is already in shapebase? if so how do you access it? Quote Link to comment Share on other sites More sharing options...
marauder2k9 Posted March 19, 2017 Share Posted March 19, 2017 do u think this could be modified to have a decal follow the movement of an object? Quote Link to comment Share on other sites More sharing options...
irei1as Posted March 21, 2017 Author Share Posted March 21, 2017 do u think this could be modified to have a decal follow the movement of an object? If the object has no internal animations it's very easy, like a static object moving with a tween.Add the matrix transform of the parent object (the object receiving the decal) as a variable of the decal. Then if the object position changes (you have the id of the object to check) you make a transform of the decal according to that.The problem is if the object has animations, like the soldier moving his feet or arms.That's because it's not easy to know where in the geometry the hit will be in any other frame.Checking how the nodes moves may be a starting point but that needs a C++ change for the nodes to show the transform in real time.This is what I have related to this for the 3.8 version. Sadly I can't use the new code for the newest version.Inside source/T3D/shapeBase.h add before the end of the definition of class ShapeBase: public: MatrixF getNodeTransformN(const String &nodeName); MatrixF getNodeTransform(const S32 nodeIdx); Inside source/T3D/shapeBase.cpp just at the end: MatrixF ShapeBase::getNodeTransformN(const String &nodeName) { S32 nodeIdx = mShapeInstance->getShape()->findNode(nodeName); return getNodeTransform(nodeIdx); } MatrixF ShapeBase::getNodeTransform(const S32 nodeIdx) { MatrixF returnValue = MatrixF::Identity; if(nodeIdx != -1) { if (isServerObject() && mShapeInstance) mShapeInstance->animateNodeSubtrees(true); returnValue = mShapeInstance->mNodeTransforms[nodeIdx]; } MatrixF objectTransform = getTransform(); Point3F nodeObjPos = returnValue.getPosition(); nodeObjPos.convolve( getScale() ); returnValue.setPosition(nodeObjPos); returnValue.mulL(objectTransform); return returnValue; } DefineEngineMethod( ShapeBase, getNodeTransform, TransformF, (const char* nodeName),, "Get the transform of a named node in the shape.\n" "@param nodeName Name of the node to check.\n" "@return The current transform of the node.\n" ) { return TransformF(object->getNodeTransformN(nodeName)); } --------------------------------------------------------------------------------------------------------------------- In source\T3D\shapeImage.cpp look inside of void ShapeBase::getMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat ) for MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni]; And add these lines before: if (isServerObject() && mShapeInstance) mShapeInstance->animateNodeSubtrees(true); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.