EnergyProjectile for TGEA 1.8.1+
by CdnGater · 05/03/2009 (6:50 am) · 38 comments
This is a first cut at a generic EnergyProjectile that is flexible enough to provide a number of different effects. Just drop the code into the T3D directory in the source, compile and then play with it. Configuring this to be used is like configuring any other weapon, except use EnergyProjectile instead of just the standard Porjectile.
Edit: I did not like the way the beams were being rendered. This way it much better. Also added a screenshot, nothing fancy just to show a blaster effect.
#include "console/consoleTypes.h"
#include "core/stream/bitStream.h"
#include "sceneGraph/sceneState.h"
#include "sceneGraph/sceneGraph.h"
#include "T3D/shapeBase.h"
#include "ts/tsShapeInstance.h"
#include "gfx/primBuilder.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxTransformSaver.h"
#include "math/mRandom.h"
#include "math/mathIO.h"
#include "math/mathUtils.h"
#include "renderInstance/renderPassManager.h"
#include "T3D/projectile.h"
class ExplosionData;
class ShapeBase;
class TSShapeInstance;
class TSThread;
//--------------------------------------------------------------------------
class EnergyProjectileData : public ProjectileData
{
typedef ProjectileData Parent;
public:
bool beamEnabled;
bool beamPulse;
F32 beamStartRadius;
F32 beamMidRadius;
F32 beamEndRadius;
F32 beamFrontSegmentLength;
F32 beamBackSegmentLength;
StringTableEntry beamMaterialList;
bool sparkEnabled;
StringTableEntry sparkMaterialList;
F32 sparkRadius;
F32 sparkStep;
F32 sparkRotationStep;
S32 interval;
EnergyProjectileData();
void packData(BitStream*);
void unpackData(BitStream*);
static void initPersistFields();
DECLARE_CONOBJECT(EnergyProjectileData);
};
DECLARE_CONSOLETYPE(EnergyProjectileData)
//--------------------------------------------------------------------------
class EnergyProjectile : public Projectile
{
typedef Projectile Parent;
EnergyProjectileData* mDataBlock;
protected:
GFXTexHandle mBeamTextureHandles[20];
MaterialList mBeamMaterialList;
GFXTexHandle mSparkTextureHandles[20];
MaterialList mSparkMaterialList;
S32 mBeamNumTextures;
S32 mBeamIndex;
S32 mSparkNumTextures;
S32 mSparkIndex;
F32 mSparkRadius;
S32 mLastTime;
F32 mRange;
F32 mSparkRotation;
Point3F mEndPosition;
Point3F mMuzzlePosition;
Point3F mMuzzleVector;
Point3F mMuzzleVelocity;
void loadDml();
bool onAdd();
bool onNewDataBlock(GameBaseData*);
U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream);
void unpackUpdate(NetConnection *conn, BitStream *stream);
void processTick(const Move* move);
bool prepRenderImage(SceneState*, const U32, const U32, const bool);
void renderObject(ObjectRenderInst *ri, BaseMatInstance*);
void RenderBeamSegment( Point3F pStart, Point3F pEnd, F32 startRadius, F32 endRadius, F32 vStart, F32 vEnd );
GFXStateBlockRef mBlendInvSrcAlphaSB;
GFXStateBlockRef mBlendSB;
ObjectRenderInst::RenderDelegate mRenderDelegate;
public:
static void initPersistFields();
EnergyProjectile();
~EnergyProjectile();
DECLARE_CONOBJECT(EnergyProjectile);
};
IMPLEMENT_CO_DATABLOCK_V1(EnergyProjectileData);
IMPLEMENT_CO_NETOBJECT_V1(EnergyProjectile);
//--------------------------------------------------------------------------
//
EnergyProjectileData::EnergyProjectileData()
{
ProjectileData::ProjectileData();
beamEnabled = false;
beamPulse = true;
beamStartRadius = 0.0;
beamMidRadius = 0.0;
beamEndRadius = 0.0;
beamFrontSegmentLength = 0.0;
beamBackSegmentLength = 0.0;
beamMaterialList = NULL;
sparkEnabled = false;
sparkMaterialList = NULL;
sparkRadius = 0.0;
sparkStep = 0.0;
sparkRotationStep = 0.0f;
interval = 0;
}
//--------------------------------------------------------------------------
IMPLEMENT_CONSOLETYPE(EnergyProjectileData)
IMPLEMENT_GETDATATYPE(EnergyProjectileData)
IMPLEMENT_SETDATATYPE(EnergyProjectileData)
void EnergyProjectileData::initPersistFields()
{
Parent::initPersistFields();
addNamedField(beamEnabled, TypeBool, EnergyProjectileData);
addNamedField(beamPulse, TypeBool, EnergyProjectileData);
addNamedField(beamStartRadius, TypeF32, EnergyProjectileData);
addNamedField(beamMidRadius, TypeF32, EnergyProjectileData);
addNamedField(beamEndRadius, TypeF32, EnergyProjectileData);
addNamedField(beamFrontSegmentLength, TypeF32, EnergyProjectileData);
addNamedField(beamBackSegmentLength, TypeF32, EnergyProjectileData);
addNamedField(beamMaterialList, TypeFilename, EnergyProjectileData);
addNamedField(sparkEnabled, TypeBool, EnergyProjectileData);
addNamedField(sparkMaterialList, TypeFilename, EnergyProjectileData);
addNamedField(sparkRadius, TypeF32, EnergyProjectileData);
addNamedField(sparkStep, TypeF32, EnergyProjectileData);
addNamedField(sparkRotationStep, TypeF32, EnergyProjectileData);
addNamedField(interval, TypeS32, EnergyProjectileData);
}
//--------------------------------------------------------------------------
void EnergyProjectileData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeFlag(beamEnabled);
stream->writeFlag(beamPulse);
stream->writeFloat(beamStartRadius/20.0, 8);
stream->writeFloat(beamMidRadius/20.0, 8);
stream->writeFloat(beamEndRadius/20.0, 8);
stream->writeFloat(beamFrontSegmentLength/20.0, 8);
stream->writeFloat(beamBackSegmentLength/20.0, 8);
stream->writeString(beamMaterialList);
stream->writeFlag(sparkEnabled);
stream->writeString(sparkMaterialList);
stream->writeFloat(sparkRadius/20.0, 8);
stream->writeFloat(sparkStep, 8);
stream->writeFloat(sparkRotationStep, 8);
stream->writeInt(interval, 32);
}
void EnergyProjectileData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
beamEnabled = stream->readFlag();
beamPulse = stream->readFlag();
beamStartRadius = stream->readFloat(8) * 20;
beamMidRadius = stream->readFloat(8) * 20;
beamEndRadius = stream->readFloat(8) * 20;
beamFrontSegmentLength = stream->readFloat(8) * 20;
beamBackSegmentLength = stream->readFloat(8) * 20;
beamMaterialList = StringTable->insert(stream->readSTString());
sparkEnabled = stream->readFlag();
sparkMaterialList = StringTable->insert(stream->readSTString());
sparkRadius = stream->readFloat(8) * 20;
sparkStep = stream->readFloat(8);
sparkRotationStep = stream->readFloat(8);
interval = stream->readInt(32);
}
//--------------------------------------------------------------------------
EnergyProjectile::EnergyProjectile()
{
mLastTime = 0;
mBeamIndex = 0;
mSparkIndex = 0;
mSparkRadius = 0.0;
mSparkRotation = 0.0;
mRange = 0;
mRenderDelegate.bind(this, &EnergyProjectile::renderObject);
}
EnergyProjectile::~EnergyProjectile()
{
}
//--------------------------------------------------------------------------
void EnergyProjectile::initPersistFields()
{
Parent::initPersistFields();
addField("range", TypeF32, Offset(mRange, EnergyProjectile));
}
//--------------------------------------------------------------------------
U32 EnergyProjectile::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(con, mask, stream);
if (stream->writeFlag(mask & GameBase::InitialUpdateMask))
{
// Initial update
stream->write(mRange);
}
return retMask;
}
void EnergyProjectile::unpackUpdate(NetConnection* con, BitStream* stream)
{
Parent::unpackUpdate(con, stream);
if (stream->readFlag())
{
// initial update
stream->read(&mRange);
}
}
//--------------------------------------------------------------------------
void EnergyProjectile::loadDml()
{
S32 x;
mBeamNumTextures = 0;
mSparkNumTextures = 0;
FileStream *stream = NULL;
if (mDataBlock->beamEnabled && mDataBlock->beamMaterialList[0])
{
stream = FileStream::createAndOpen( mDataBlock->beamMaterialList, Torque::FS::File::Read );
if(stream)
{
char path[1024], *p;
dStrcpy(path, mDataBlock->beamMaterialList);
if ((p = dStrrchr(path, '/')) != NULL)
*p = 0;
mBeamMaterialList.read(*stream);
stream->close();
delete stream;
mBeamMaterialList.load(path);
for(x = 0; x < mBeamMaterialList.size(); ++x, ++mBeamNumTextures)
mBeamTextureHandles[x] = mBeamMaterialList.getMaterial(x);
}
}
if (mDataBlock->sparkEnabled && mDataBlock->sparkMaterialList[0])
{
stream = FileStream::createAndOpen( mDataBlock->sparkMaterialList, Torque::FS::File::Read );
if(stream)
{
char path[1024], *p;
dStrcpy(path, mDataBlock->sparkMaterialList);
if ((p = dStrrchr(path, '/')) != NULL)
*p = 0;
mSparkMaterialList.read(*stream);
stream->close();
delete stream;
mSparkMaterialList.load(path);
for(x = 0; x < mSparkMaterialList.size(); ++x, ++mSparkNumTextures)
mSparkTextureHandles[x] = mSparkMaterialList.getMaterial(x);
}
}
}
//--------------------------------------------------------------------------
bool EnergyProjectile::onAdd()
{
if(!Parent::onAdd())
return false;
if (!isServerObject())
{
loadDml();
mSparkRadius = mDataBlock->sparkRadius;
mMuzzlePosition = mInitialPosition;
mMuzzleVelocity = mCurrVelocity;
}
return true;
}
bool EnergyProjectile::onNewDataBlock(GameBaseData* dptr)
{
mDataBlock = dynamic_cast<EnergyProjectileData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr))
return false;
return true;
}
void EnergyProjectile::processTick(const Move* move)
{
GameBase::processTick(move);
mCurrTick++;
// See if we can get out of here the easy way ...
if (isServerObject() && mCurrTick >= mDataBlock->lifetime)
{
deleteObject();
return;
}
else if (mHidden == true)
return;
if (mDataBlock->beamEnabled && mDataBlock->beamPulse)
{
if (mSourceObject)
{
MatrixF muzzleTrans;
mSourceObject->getMuzzleTransform(mSourceObjectSlot, &muzzleTrans);
muzzleTrans.getColumn(3, &mMuzzlePosition);
muzzleTrans.getColumn(1, &mMuzzleVector);
mEndPosition = mMuzzleVector * mRange;
mEndPosition += mMuzzlePosition;
mSourceObject->disableCollision();
RayInfo rInfo;
if (getContainer()->castRay(mMuzzlePosition, mEndPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo) == true)
{
mEndPosition = rInfo.point;
}
mSourceObject->enableCollision();
mMuzzleVelocity = mMuzzleVector * mDataBlock->muzzleVelocity;;
}
mCurrPosition = mMuzzlePosition + mMuzzleVelocity * (F32(mCurrTick) * (F32(TickMs) / 1000.0f));
mCurrVelocity = mMuzzleVelocity;
}
// ... otherwise, we have to do some simulation work.
RayInfo rInfo;
Point3F oldPosition;
Point3F newPosition;
oldPosition = mCurrPosition;
newPosition = oldPosition + mCurrVelocity * (F32(TickMs) / 1000.0f);
if (bool(mSourceObject))
mSourceObject->disableCollision();
if (getContainer()->castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo) == true)
{
if(isServerObject() && (rInfo.object->getType() & csmStaticCollisionMask) == 0)
setMaskBits(BounceMask);
if(mCurrTick > mDataBlock->armingDelay)
{
MatrixF xform(true);
xform.setColumn(3, rInfo.point);
setTransform(xform);
mCurrPosition = rInfo.point;
mCurrVelocity = Point3F(0, 0, 0);
U32 objectType = rInfo.object->getType();
if(mSourceObject)
mSourceObject->enableCollision();
onCollision(rInfo.point, rInfo.normal, rInfo.object);
explode(rInfo.point, rInfo.normal, objectType );
}
else
{
if(mDataBlock->isBallistic)
{
Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);;
mCurrVelocity = bounceVel;
Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal);
mCurrVelocity -= tangent * mDataBlock->bounceFriction;
mCurrVelocity *= mDataBlock->bounceElasticity;
F32 timeLeft = 1.0f - rInfo.t;
oldPosition = rInfo.point + rInfo.normal * 0.05f;
newPosition = oldPosition + (mCurrVelocity * ((timeLeft/1000.0f) * TickMs));
}
}
}
if (bool(mSourceObject))
mSourceObject->enableCollision();
if(isClientObject())
{
emitParticles(mCurrPosition, newPosition, mCurrVelocity, TickMs);
updateSound();
}
mCurrDeltaBase = newPosition;
mCurrBackDelta = mCurrPosition - newPosition;
mCurrPosition = newPosition;
MatrixF xform(true);
xform.setColumn(3, mCurrPosition);
setTransform(xform);
}
//--------------------------------------------------------------------------
bool EnergyProjectile::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
// Return if last state.
if (isLastState(state, stateKey)) return false;
// Set Last State.
setLastState(state, stateKey);
if (mHidden == true || mFadeValue <= (1.0/255.0))
return false;
// Is Object Rendered?
if (state->isObjectRendered(this))
{
ObjectRenderInst *ri = gRenderInstManager->allocInst<ObjectRenderInst>();
ri->mRenderDelegate = mRenderDelegate;
ri->state = state;
ri->type = RenderPassManager::RIT_ObjectTranslucent;
ri->translucent = true;
ri->calcSortPoint(this, state->getCameraPosition());
gRenderInstManager->addInst( ri );
}
return false;
}
void EnergyProjectile::renderObject(ObjectRenderInst *ri, BaseMatInstance* overrideMat)
{
SceneState* state = ri->state;
MatrixF projection = GFX->getProjectionMatrix();
RectI viewport = GFX->getViewport();
GFX->setViewport(viewport);
GFX->setProjectionMatrix(projection);
// set up the graphics
if (mBlendInvSrcAlphaSB.isNull())
{
GFXStateBlockDesc desc;
desc.setCullMode( GFXCullNone );
desc.setZEnable(false);
desc.zWriteEnable = false;
desc.samplersDefined = true;
desc.samplers[0].textureColorOp = GFXTOPModulate;
desc.samplers[1].textureColorOp = GFXTOPDisable;
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
mBlendInvSrcAlphaSB = GFX->createStateBlock(desc);
desc.samplers[0].textureColorOp = GFXTOPDisable;
mBlendSB = GFX->createStateBlock(desc);
}
GFX->setStateBlock(mBlendInvSrcAlphaSB);
S32 thisTime = Sim::getCurrentTime();
S32 timeDelta = thisTime - mLastTime;
if (timeDelta > mDataBlock->interval)
{
if (mBeamNumTextures > 0)
{
mBeamIndex ++;
if (mBeamIndex >= mBeamNumTextures)
mBeamIndex = 0;
}
if (mSparkNumTextures > 0)
{
mSparkIndex ++;
if (mSparkIndex >= mSparkNumTextures)
mSparkIndex = 0;
}
mSparkRadius += mDataBlock->sparkStep;
mSparkRotation += mDataBlock->sparkRotationStep;
mLastTime = thisTime;
}
// Select the objects' texture.
GFX->disableShaders();
GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
if (mDataBlock->beamEnabled && mBeamNumTextures > 0)
{
// Set Colour/Alpha.
GFX->setTexture(0, mBeamTextureHandles[mBeamIndex]);
if (mDataBlock->beamPulse)
{
RenderBeamSegment(mMuzzlePosition, mCurrPosition, mDataBlock->beamStartRadius, mDataBlock->beamMidRadius, 0.0, 0.5 );
RenderBeamSegment(mCurrPosition, mEndPosition, mDataBlock->beamMidRadius, mDataBlock->beamEndRadius, 0.5, 1.0 );
}
else
{
Point3F dirV = mCurrVelocity;
dirV.normalize();
F32 clientDist = (mInitialPosition - mCurrPosition).len();
F32 beamFrontLength = mDataBlock->beamFrontSegmentLength;
if (beamFrontLength > clientDist)
beamFrontLength = clientDist;
F32 beamBackLength = mDataBlock->beamBackSegmentLength;
if (beamBackLength > clientDist)
beamBackLength = clientDist;
Point3F posFrontMod = dirV * beamFrontLength;
Point3F posBackMod = dirV * beamBackLength;
RenderBeamSegment(mCurrPosition - posBackMod, mCurrPosition, mDataBlock->beamStartRadius, mDataBlock->beamMidRadius, 0.0, 0.5 );
RenderBeamSegment(mCurrPosition, mCurrPosition + posFrontMod, mDataBlock->beamMidRadius, mDataBlock->beamEndRadius, 0.5, 1.0 );
}
}
if (mDataBlock->sparkEnabled && mSparkNumTextures > 0 && mSparkRadius > 0.0f)
{
// Initialize points with basic info
Point3F points[4];
points[0] = Point3F(-mSparkRadius, 0.0, -mSparkRadius);
points[1] = Point3F( mSparkRadius, 0.0, -mSparkRadius);
points[2] = Point3F( mSparkRadius, 0.0, mSparkRadius);
points[3] = Point3F(-mSparkRadius, 0.0, mSparkRadius);
GFX->setTexture(0, mSparkTextureHandles[mSparkIndex]);
// Get info we need to adjust points
MatrixF camView = GFX->getWorldMatrix();
camView.transpose();
F32 sy, cy;
mSinCos(mDegToRad(mSparkRotation), sy, cy);
// Finalize points
for(int i = 0; i < 4; i++)
{
// rotate
points[i].set(cy * points[i].x - sy * points[i].z, 0.0, sy * points[i].x + cy * points[i].z);
// align with camera
camView.mulP(points[i]);
// offset
points[i] += mCurrPosition;
}
PrimBuild::color4f(1,1,1,1);
PrimBuild::begin( GFXTriangleFan, 4 );
PrimBuild::texCoord2f(0, 0);
PrimBuild::vertex3fv(points[0]);
PrimBuild::texCoord2f(1, 0);
PrimBuild::vertex3fv(points[1]);
PrimBuild::texCoord2f(1, 1);
PrimBuild::vertex3fv(points[2]);
PrimBuild::texCoord2f(0, 1);
PrimBuild::vertex3fv(points[3]);
PrimBuild::end();
}
GFX->disableShaders();
}
void EnergyProjectile::RenderBeamSegment( Point3F pStart, Point3F pEnd, F32 startRadius, F32 endRadius, F32 vStart, F32 vEnd )
{
Point3F dirV = mCurrVelocity;
dirV.normalize();
MatrixF orient = MathUtils::createOrientFromDir( dirV );
Point3F sPt1, sPt2, ePt1, ePt2;
PrimBuild::color4f(1,1,1,1);
{
sPt1 = Point3F(startRadius,0,0);
sPt2 = Point3F(-startRadius,0,0);
orient.mulV( sPt1 );
sPt1 += pStart;
orient.mulV( sPt2 );
sPt2 += pStart;
ePt1 = Point3F(endRadius,0,0);
ePt2 = Point3F(-endRadius,0,0);
orient.mulV( ePt1 );
ePt1 += pEnd;
orient.mulV( ePt2 );
ePt2 += pEnd;
PrimBuild::begin(GFXTriangleFan, 4);
PrimBuild::texCoord2f(0, vStart);
PrimBuild::vertex3f(sPt1.x, sPt1.y, sPt1.z);
PrimBuild::texCoord2f(1, vStart);
PrimBuild::vertex3f(sPt2.x, sPt2.y, sPt2.z);
PrimBuild::texCoord2f(1, vEnd);
PrimBuild::vertex3f(ePt2.x, ePt2.y, ePt2.z);
PrimBuild::texCoord2f(0, vEnd);
PrimBuild::vertex3f(ePt1.x, ePt1.y, ePt1.z);
PrimBuild::end();
}
{
sPt1 = Point3F(0,0,startRadius);
sPt2 = Point3F(0,0,-startRadius);
orient.mulV( sPt1 );
sPt1 += pStart;
orient.mulV( sPt2 );
sPt2 += pStart;
ePt1 = Point3F(0,0,endRadius);
ePt2 = Point3F(0,0,-endRadius);
orient.mulV( ePt1 );
ePt1 += pEnd;
orient.mulV( ePt2 );
ePt2 += pEnd;
PrimBuild::begin(GFXTriangleFan, 4);
PrimBuild::texCoord2f(0, vStart);
PrimBuild::vertex3f(sPt1.x, sPt1.y, sPt1.z);
PrimBuild::texCoord2f(1, vStart);
PrimBuild::vertex3f(sPt2.x, sPt2.y, sPt2.z);
PrimBuild::texCoord2f(1, vEnd);
PrimBuild::vertex3f(ePt2.x, ePt2.y, ePt2.z);
PrimBuild::texCoord2f(0, vEnd);
PrimBuild::vertex3f(ePt1.x, ePt1.y, ePt1.z);
PrimBuild::end();
}
{
sPt1 = Point3F(startRadius,0,startRadius);
sPt2 = Point3F(-startRadius,0,-startRadius);
orient.mulV( sPt1 );
sPt1 += pStart;
orient.mulV( sPt2 );
sPt2 += pStart;
ePt1 = Point3F(endRadius,0,endRadius);
ePt2 = Point3F(-endRadius,0,-endRadius);
orient.mulV( ePt1 );
ePt1 += pEnd;
orient.mulV( ePt2 );
ePt2 += pEnd;
PrimBuild::begin(GFXTriangleFan, 4);
PrimBuild::texCoord2f(0, vStart);
PrimBuild::vertex3f(sPt1.x, sPt1.y, sPt1.z);
PrimBuild::texCoord2f(1, vStart);
PrimBuild::vertex3f(sPt2.x, sPt2.y, sPt2.z);
PrimBuild::texCoord2f(1, vEnd);
PrimBuild::vertex3f(ePt2.x, ePt2.y, ePt2.z);
PrimBuild::texCoord2f(0, vEnd);
PrimBuild::vertex3f(ePt1.x, ePt1.y, ePt1.z);
PrimBuild::end();
}
{
sPt1 = Point3F(startRadius,0,-startRadius);
sPt2 = Point3F(-startRadius,0,startRadius);
orient.mulV( sPt1 );
sPt1 += pStart;
orient.mulV( sPt2 );
sPt2 += pStart;
ePt1 = Point3F(endRadius,0,-endRadius);
ePt2 = Point3F(-endRadius,0,endRadius);
orient.mulV( ePt1 );
ePt1 += pEnd;
orient.mulV( ePt2 );
ePt2 += pEnd;
PrimBuild::begin(GFXTriangleFan, 4);
PrimBuild::texCoord2f(0, vStart);
PrimBuild::vertex3f(sPt1.x, sPt1.y, sPt1.z);
PrimBuild::texCoord2f(1, vStart);
PrimBuild::vertex3f(sPt2.x, sPt2.y, sPt2.z);
PrimBuild::texCoord2f(1, vEnd);
PrimBuild::vertex3f(ePt2.x, ePt2.y, ePt2.z);
PrimBuild::texCoord2f(0, vEnd);
PrimBuild::vertex3f(ePt1.x, ePt1.y, ePt1.z);
PrimBuild::end();
}
}Edit: I did not like the way the beams were being rendered. This way it much better. Also added a screenshot, nothing fancy just to show a blaster effect.
About the author
#2
Added a screenshot as requested. Also I didn't like the way I was rendering the beams so changed that, this way is much better now.
Don't think I can realy do any video at the moment, without spending time to add this to the stock TGEA, and I realy don't have the time for that. But do expect to see it in videos when I get around to producing some at a later date.
05/03/2009 (5:47 pm)
Added a screenshot as requested. Also I didn't like the way I was rendering the beams so changed that, this way is much better now.
Don't think I can realy do any video at the moment, without spending time to add this to the stock TGEA, and I realy don't have the time for that. But do expect to see it in videos when I get around to producing some at a later date.
#3
This could be a blast with my projectile resource, thanks a ton for an excellent addition.
05/03/2009 (11:05 pm)
Well Simon I really like what you have done with this. I really wish it had some sample script (i.e. dataBlock) and a demo screenshot,or video.This could be a blast with my projectile resource, thanks a ton for an excellent addition.
#4
First: Laser Beam
Second: Plasma Ball with Tail
Third: Blaster
Fourth: Expanding Plasma Ball
Warning, programmer art!
05/04/2009 (10:17 am)
The things I do for you people.First: Laser Beam
Second: Plasma Ball with Tail
Third: Blaster
Fourth: Expanding Plasma Ball
Warning, programmer art!
#5
05/04/2009 (1:29 pm)
nice
#6
05/04/2009 (7:38 pm)
Thanks for sharing this, it looks very cool and I'll be trying this out as soon as I get some time.
#7
05/05/2009 (12:14 am)
Extremely cool!!! I can't wait to try this out.
#8
05/05/2009 (12:55 am)
It seems you might have modified your base projectile class since the energy projectile is calling on mInitialPosition which is not in the stock code. I am assuming that you created a variable to save mCurrPosition which is originally the initial position.
#9
05/05/2009 (1:31 am)
One more thing, any chance for a few sample datablocks to give an idea how to approach a good set of values?
#10
05/05/2009 (3:06 am)
That is good work, I've been meaning to get round to creating rays. Thanks! :)
#11
In Projectile.h find
and change it to
Now open Projectile.cpp.
Find the function Projectile::Projectile, add anywhere in the function
Find the function Projectile::onAdd, and find
change it to
Find the function Projectile::unpackUpdate and then look for
change it to
Here are the specific settings from the datablocks that are in the demo, please note I have not included the standard projectile settings, because they are standard. Also the paths to the dml are from my project, and you will have to change them for yours.
Would I consider these good values? Probably not. I am just coding, and when I get around to creating the actual weapons, then I will be back making proper textures, tweeking settings until they are good values for my project.
05/05/2009 (5:03 am)
That's what I get for using a heavily modified code base. You are correct about the mInitialPosition.In Projectile.h find
U32 mCollideHitType; bool onAdd();
and change it to
U32 mCollideHitType; Point3F mInitialPosition; bool onAdd();
Now open Projectile.cpp.
Find the function Projectile::Projectile, add anywhere in the function
mInitialPosition.set(0, 0, 0);
Find the function Projectile::onAdd, and find
addToScene(); return true;
change it to
addToScene(); mInitialPosition = mCurrPosition; return true;
Find the function Projectile::unpackUpdate and then look for
mCurrDeltaBase = pos;
mCurrBackDelta = mCurrPosition - pos;
mCurrPosition = pos;
setPosition(mCurrPosition);change it to
mInitialPosition = pos;
mCurrDeltaBase = pos;
mCurrBackDelta = mCurrPosition - pos;
mCurrPosition = pos;
setPosition(mCurrPosition);Here are the specific settings from the datablocks that are in the demo, please note I have not included the standard projectile settings, because they are standard. Also the paths to the dml are from my project, and you will have to change them for yours.
Would I consider these good values? Probably not. I am just coding, and when I get around to creating the actual weapons, then I will be back making proper textures, tweeking settings until they are good values for my project.
datablock EnergyProjectileData(LaserBeam) beamEnabled = true; beamPulse = true; beamStartRadius = 0.05; beamMidRadius = 0.05; beamEndRadius = 0.05; beamFrontSegmentLength = 2; beamBackSegmentLength = 2; beamMaterialList = "data/shapes/weapons/laserbeam/beam.dml"; sparkEnabled = false; sparkMaterialList = "data/shapes/weapons/laserbeam/spark.dml"; sparkRadius = 0.3; sparkStep = 0.0; sparkRotationStep = 0.0; interval = 5;
datablock EnergyProjectileData(BlasterBolt) beamEnabled = true; beamPulse = false; beamStartRadius = 0.2; beamMidRadius = 0.3; beamEndRadius = 0.2; beamFrontSegmentLength = 5; beamBackSegmentLength = 10; beamMaterialList = "data/shapes/weapons/laserbeam/beam.dml"; sparkEnabled = false; sparkMaterialList = "data/shapes/weapons/laserbeam/spark.dml"; sparkRadius = 0.3; sparkStep = 0.0; sparkRotationStep = 0.0; interval = 5;
datablock EnergyProjectileData(ExpandingPlasmaBall) beamEnabled = false; beamPulse = true; beamStartRadius = 0.4; beamMidRadius = 0.4; beamEndRadius = 0.4; beamFrontSegmentLength = 2; beamBackSegmentLength = 6; beamMaterialList = "data/shapes/weapons/laserbeam/beam.dml"; sparkEnabled = true; sparkMaterialList = "data/shapes/weapons/laserbeam/spark.dml"; sparkRadius = 0.1; sparkStep = 0.1; sparkRotationStep = 0.1; interval = 5;
datablock EnergyProjectileData(PlasmaBallWithTail) beamEnabled = true; beamPulse = false; beamStartRadius = 0.1; beamMidRadius = 0.4; beamEndRadius = 0.1; beamFrontSegmentLength = 0.1; beamBackSegmentLength = 5; beamMaterialList = "data/shapes/weapons/laserbeam/beam.dml"; sparkEnabled = true; sparkMaterialList = "data/shapes/weapons/laserbeam/spark.dml"; sparkRadius = 0.5; sparkStep = 0.0; sparkRotationStep = 0.1; interval = 5;
#12
05/05/2009 (2:28 pm)
Thanks Simon. I can't wait to start testing it out.
#13
I got the engine to compile with the new energyProjectile.cpp added and the code changes to projectile.h and projectile.cpp, so it would seem to be ready for testing, but I cannot test cuz I don't have the materials...
05/06/2009 (11:39 am)
Your datablocks are incomplete and you didn't include the material list or textures! I got the engine to compile with the new energyProjectile.cpp added and the code changes to projectile.h and projectile.cpp, so it would seem to be ready for testing, but I cannot test cuz I don't have the materials...
#14
bin/server/scripts/weapons/gun_1a.cs (652): Unable to instantiate non-conobject class EnergyProjectile.
Here is my datablock:
EDIT:
OMFG, I feel stupid! LOL! I forgot to replace my .exe with the new one....
So no error now, but I am NOT seeing the new energy projectile...
05/06/2009 (11:52 am)
I stuck in some random materials for testing and am getting errors, not with the materials but with the projectile:bin/server/scripts/weapons/gun_1a.cs (652): Unable to instantiate non-conobject class EnergyProjectile.
Here is my datablock:
datablock EnergyProjectileData(Gun_1aProjectile)
{
//projectileShapeName = "~/data/shapes/weapons/Gun_1a/rocket.dts";
directDamage = 1;
radiusDamage = 0;
damageRadius = 0;
areaImpulse = 0;
explosion = Gun_1aExplosion;
particleEmitter = Gun_1aEmitter;
muzzleVelocity = 100;
velInheritFactor = 0;
armingDelay = 0;
lifetime = 6000;
fadeDelay = 1500;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = true;
gravityMod = 0.10;
hasLight = true;
lightRadius = 0.2;
lightColor = "1 0 0";
beamEnabled = true;
beamPulse = false;
beamStartRadius = 0.2;
beamMidRadius = 0.3;
beamEndRadius = 0.2;
beamFrontSegmentLength = 5;
beamBackSegmentLength = 10;
beamMaterialList = "data/shapes/weapons/gun_1a/beam.dml";
sparkEnabled = false;
sparkMaterialList = "data/shapes/weapons/gun_1a/spark.dml";
sparkRadius = 0.3;
sparkStep = 0.0;
sparkRotationStep = 0.0;
interval = 5;
};EDIT:
OMFG, I feel stupid! LOL! I forgot to replace my .exe with the new one....
So no error now, but I am NOT seeing the new energy projectile...
#15
The material I used is from the laser resource.
Uncomment the projectileShapeName, that is still needed belive it or not.
If the above does not work, try
changing the follow
when you shoot, sidestep, do you see the beampulses?
Any errors in the log? have you made directory structure changes or are you using the stock TGEA? If your using the stock TGEA, the paths for the material is wrong. There is no data at the root directory, Please note, I did say you would have to repath the DMLs.
Maybe you meant the following ?
05/06/2009 (1:02 pm)
The material I used is from the laser resource.
Uncomment the projectileShapeName, that is still needed belive it or not.
If the above does not work, try
changing the follow
muzzleVelocity = 20; beamPulse = true;
when you shoot, sidestep, do you see the beampulses?
Any errors in the log? have you made directory structure changes or are you using the stock TGEA? If your using the stock TGEA, the paths for the material is wrong. There is no data at the root directory, Please note, I did say you would have to repath the DMLs.
Maybe you meant the following ?
beamMaterialList = "~/data/shapes/weapons/gun_1a/beam.dml";
#16
Still nothing... The weapon fires, but I don't see any beam at all...
I created the .dml from a simple .txt file and renamed to .dml. Is this ok? It can use PNG or JPG can't it? I am using PNG.
No errors in console log.
05/06/2009 (2:37 pm)
I un-commented the projectileShapeName, changed muzzleVelocity to 20, set beamPulse to true, and updated my beamMaterialList.Still nothing... The weapon fires, but I don't see any beam at all...
I created the .dml from a simple .txt file and renamed to .dml. Is this ok? It can use PNG or JPG can't it? I am using PNG.
No errors in console log.
#17
to: projectileType = EnergyProjectile;
And the weapon fires, but I no longer see my projectile at all, let alone the 'beam'...
How many textures does you beam use and what do they look like? Could I just use a solid color jpg?
05/06/2009 (2:43 pm)
I also edited my: datablock ShapeBaseImageData(Gun_1aImage)to: projectileType = EnergyProjectile;
And the weapon fires, but I no longer see my projectile at all, let alone the 'beam'...
How many textures does you beam use and what do they look like? Could I just use a solid color jpg?
#18
05/06/2009 (2:43 pm)
@Nicolai - Good I am not the only one with this problem. I am getting the exact same thing as Nicolai. However, I took it a step further and added printf calls to the start of each of the EnergyProjectile functions and none are being called. It is using the datablock for EnergyProjectileData but only as ProjectileData. All code objects unigue to Energy Projectile are being ignored.
#19
I just redownloaded a clean copy of TGEA 1.8.1 and implemented the changes.
and yes You have to do the following as indicated by Nicolai to the Gun image.
I used your datablock as posted, and I see my beams showing up.
I tried something else, I copyed the energy.png from the swarm gun and used that. I could see a very thin blue line.
Try using the texture from this resource
www.garagegames.com/community/resources/view/8006
05/06/2009 (4:41 pm)
OK I am not sure whats going on with your version.I just redownloaded a clean copy of TGEA 1.8.1 and implemented the changes.
and yes You have to do the following as indicated by Nicolai to the Gun image.
projectileType = EnergyProjectile;
I used your datablock as posted, and I see my beams showing up.
I tried something else, I copyed the energy.png from the swarm gun and used that. I could see a very thin blue line.
Try using the texture from this resource
www.garagegames.com/community/resources/view/8006
#20
Just to clarify, I took allllll the code at the very top of this page and stuck in a new file: energyProjectile.cpp
I then opened my game's *.sln file, added an 'existing item' and choose the new energyProjectile.cpp (which I stuck in my "sources/T3D" folder).
I then edited my projectile.cpp and projectile.h files as noted in one of your replies.
I then compiled the engine and copied my new .exe file to my current project.
I then made a copy of my current weapon, gun_1.cs and named it gun_1a.cs. I did a find/replace, and replaced ALL gun_1 with gun_1a.
I then made a copy of my gun_1 shape folder: bin/data/shapes/weapons/gun1 and renamed the folder to: gun_1a
I then edited gun_1a.cs to include the datablock I posted earlier today (the one you said you tried and works).
I go into the game, unmount my current weapon, mount gun_1a, and try firing the weapon... nothing. No errors, no projectile at all...
I would be more than happy to share all of my files if you want to see them.
05/06/2009 (5:50 pm)
Tried that and got absolutely nothing at all...Just to clarify, I took allllll the code at the very top of this page and stuck in a new file: energyProjectile.cpp
I then opened my game's *.sln file, added an 'existing item' and choose the new energyProjectile.cpp (which I stuck in my "sources/T3D" folder).
I then edited my projectile.cpp and projectile.h files as noted in one of your replies.
I then compiled the engine and copied my new .exe file to my current project.
I then made a copy of my current weapon, gun_1.cs and named it gun_1a.cs. I did a find/replace, and replaced ALL gun_1 with gun_1a.
I then made a copy of my gun_1 shape folder: bin/data/shapes/weapons/gun1 and renamed the folder to: gun_1a
I then edited gun_1a.cs to include the datablock I posted earlier today (the one you said you tried and works).
I go into the game, unmount my current weapon, mount gun_1a, and try firing the weapon... nothing. No errors, no projectile at all...
I would be more than happy to share all of my files if you want to see them.
Torque Owner Jason "fireVein" Culwell