added everything
This commit is contained in:
308
engine/lightingSystem/sgDecalProjector.cc
Executable file
308
engine/lightingSystem/sgDecalProjector.cc
Executable file
@@ -0,0 +1,308 @@
|
||||
//-----------------------------------------------
|
||||
// Synapse Gaming - Lighting System
|
||||
// Copyright <20> Synapse Gaming 2003
|
||||
// Written by John Kabus
|
||||
//-----------------------------------------------
|
||||
#include "lightingSystem/sgLighting.h"
|
||||
#include "lightingSystem/sgDecalProjector.h"
|
||||
#include "sim/decalManager.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "sceneGraph/sceneState.h"
|
||||
|
||||
extern bool gEditingMission;
|
||||
|
||||
|
||||
class sgDecalProjector : public GameBase
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
DecalData *mDataBlock;
|
||||
bool onNewDataBlock(GameBaseData* dptr);
|
||||
protected:
|
||||
bool sgInitNeeded;
|
||||
bool sgProjection;
|
||||
Point3F sgProjectionPoint;
|
||||
Point3F sgProjectionNormal;
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
void sgResetProjection();
|
||||
void sgProject();
|
||||
public:
|
||||
sgDecalProjector();
|
||||
void inspectPostApply();
|
||||
void setTransform(const MatrixF &mat);
|
||||
bool prepRenderImage(SceneState* state, const U32 stateKey,
|
||||
const U32 startZone, const bool modifyBaseZoneState);
|
||||
void renderObject(SceneState *state, SceneRenderImage *image);
|
||||
U32 packUpdate(NetConnection *con, U32 mask, BitStream *stream);
|
||||
void unpackUpdate(NetConnection *con, BitStream *stream);
|
||||
DECLARE_CONOBJECT(sgDecalProjector);
|
||||
};
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(sgDecalProjector);
|
||||
|
||||
sgDecalProjector::sgDecalProjector()
|
||||
{
|
||||
mTypeMask |= StaticObjectType | StaticTSObjectType | StaticRenderedObjectType;
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
mDataBlock = NULL;
|
||||
sgProjection = false;
|
||||
sgProjectionPoint = Point3F(0.0f, 0.0f, 0.0f);
|
||||
sgProjectionNormal = Point3F(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// for after load relinking...
|
||||
sgInitNeeded = true;
|
||||
}
|
||||
|
||||
bool sgDecalProjector::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
mObjBox.min.set( -0.5, -0.5, -0.5 );
|
||||
mObjBox.max.set( 0.5, 0.5, 0.5 );
|
||||
resetWorldBox();
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
addToScene();
|
||||
return true;
|
||||
}
|
||||
|
||||
void sgDecalProjector::onRemove()
|
||||
{
|
||||
if(isClientObject())
|
||||
gDecalManager->ageDecal(getId());
|
||||
|
||||
removeFromScene();
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
bool sgDecalProjector::onNewDataBlock(GameBaseData* dptr)
|
||||
{
|
||||
mDataBlock = dynamic_cast<DecalData *>(dptr);
|
||||
return Parent::onNewDataBlock(dptr);
|
||||
}
|
||||
|
||||
bool sgDecalProjector::prepRenderImage(SceneState* state, const U32 stateKey,
|
||||
const U32 startZone, const bool modifyBaseZoneState)
|
||||
{
|
||||
if(!gEditingMission)
|
||||
return false;
|
||||
if(isLastState(state, stateKey))
|
||||
return false;
|
||||
|
||||
setLastState(state, stateKey);
|
||||
|
||||
if(state->isObjectRendered(this))
|
||||
{
|
||||
SceneRenderImage* image = new SceneRenderImage;
|
||||
image->obj = this;
|
||||
image->isTranslucent = true;
|
||||
image->sortType = SceneRenderImage::EndSort;
|
||||
state->insertRenderImage(image);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sgDecalProjector::renderObject(SceneState *state, SceneRenderImage *image)
|
||||
{
|
||||
if(gEditingMission)
|
||||
{
|
||||
// render the directional line...
|
||||
glBlendFunc(GL_ONE,GL_ZERO);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
Point3F vector = SG_STATIC_SPOT_VECTOR_NORMALIZED * 10.0f;
|
||||
Point3F origin = Point3F(0, 0, 0);
|
||||
Point3F point = vector;
|
||||
mObjToWorld.mulP(origin);
|
||||
mObjToWorld.mulP(point);
|
||||
glColor3f(0, 1, 0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(origin);
|
||||
glVertex3fv(point);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void sgDecalProjector::sgResetProjection()
|
||||
{
|
||||
sgProjection = false;
|
||||
sgProjectionPoint = Point3F(0.0f, 0.0f, 0.0f);
|
||||
sgProjectionNormal = Point3F(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if(isClientObject())
|
||||
return;
|
||||
|
||||
Point3F pos = getPosition();
|
||||
Point3F normal = SG_STATIC_SPOT_VECTOR_NORMALIZED * 100.0f;
|
||||
getTransform().mulV(normal);
|
||||
|
||||
RayInfo info;
|
||||
if(!gServerContainer.castRay(pos, (pos + normal),
|
||||
InteriorObjectType | TerrainObjectType, &info))
|
||||
{
|
||||
Con::errorf("Error in _sgDropDecal: no drop object found.");
|
||||
return;
|
||||
}
|
||||
|
||||
sgProjection = true;
|
||||
sgProjectionPoint = info.point;
|
||||
sgProjectionNormal = info.normal;
|
||||
|
||||
setMaskBits(0xffffffff);
|
||||
}
|
||||
|
||||
void sgDecalProjector::sgProject()
|
||||
{
|
||||
if((isServerObject()) || (!mDataBlock))
|
||||
return;
|
||||
|
||||
// use the instead of getId()...
|
||||
// id's are flaky in zones...
|
||||
U32 ownerid = U32(this);
|
||||
|
||||
gDecalManager->ageDecal(ownerid);
|
||||
|
||||
if(!sgProjection)
|
||||
return;
|
||||
|
||||
Point3F tandir;
|
||||
getTransform().getColumn(0, &tandir);
|
||||
|
||||
gDecalManager->addDecal(sgProjectionPoint, tandir, sgProjectionNormal, getScale(), mDataBlock, ownerid);
|
||||
}
|
||||
|
||||
void sgDecalProjector::setTransform(const MatrixF & mat)
|
||||
{
|
||||
Parent::setTransform(mat);
|
||||
sgResetProjection();
|
||||
setMaskBits(0xffffffff);
|
||||
}
|
||||
|
||||
U32 sgDecalProjector::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
||||
{
|
||||
U32 res = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
if(sgInitNeeded && isServerObject())
|
||||
{
|
||||
sgInitNeeded = false;
|
||||
sgResetProjection();
|
||||
}
|
||||
|
||||
stream->writeAffineTransform(mObjToWorld);
|
||||
|
||||
if(stream->writeFlag(sgProjection))
|
||||
{
|
||||
// this is a joke right (no Point3F support)?!?
|
||||
stream->write(sgProjectionPoint.x);
|
||||
stream->write(sgProjectionPoint.y);
|
||||
stream->write(sgProjectionPoint.z);
|
||||
stream->write(sgProjectionNormal.x);
|
||||
stream->write(sgProjectionNormal.y);
|
||||
stream->write(sgProjectionNormal.z);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void sgDecalProjector::unpackUpdate(NetConnection *con, BitStream *stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
MatrixF ObjectMatrix;
|
||||
stream->readAffineTransform(&ObjectMatrix);
|
||||
setTransform(ObjectMatrix);
|
||||
|
||||
sgProjection = stream->readFlag();
|
||||
if(sgProjection)
|
||||
{
|
||||
// this is a joke right (no Point3F support)?!?
|
||||
stream->read(&sgProjectionPoint.x);
|
||||
stream->read(&sgProjectionPoint.y);
|
||||
stream->read(&sgProjectionPoint.z);
|
||||
stream->read(&sgProjectionNormal.x);
|
||||
stream->read(&sgProjectionNormal.y);
|
||||
stream->read(&sgProjectionNormal.z);
|
||||
}
|
||||
|
||||
sgProject();
|
||||
}
|
||||
|
||||
void sgDecalProjector::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
sgResetProjection();
|
||||
setMaskBits(0xffffffff);
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
|
||||
ConsoleFunction(_sgCreateDecal, void, 6, 6, "(Point3F pos, Point3F tandir, Point3F norm, "
|
||||
"Point3F scale, decalDataBlock) - this method must be called on the client side!")
|
||||
{
|
||||
// is this the client side?
|
||||
// doesn't work...
|
||||
//if(gDecalManager->isServerObject())
|
||||
// return;
|
||||
|
||||
Point3F pos = Point3F(0, 0, 0);
|
||||
Point3F tandir = Point3F(1, 0, 0);
|
||||
Point3F normal = Point3F(0, 0, 1);
|
||||
Point3F scale = Point3F(1, 1, 1);
|
||||
DecalData *decaldata = NULL;
|
||||
|
||||
dSscanf(argv[1],"%f %f %f",&pos.x,&pos.y,&pos.z);
|
||||
dSscanf(argv[2],"%f %f %f",&tandir.x,&tandir.y,&tandir.z);
|
||||
dSscanf(argv[3],"%f %f %f",&normal.x,&normal.y,&normal.z);
|
||||
dSscanf(argv[4],"%f %f %f",&scale.x,&scale.y,&scale.z);
|
||||
|
||||
decaldata = dynamic_cast<DecalData *>(Sim::findObject(argv[5]));
|
||||
|
||||
if(!decaldata)
|
||||
return;
|
||||
|
||||
gDecalManager->addDecal(pos, tandir, normal, scale, decaldata);
|
||||
}
|
||||
|
||||
ConsoleFunction(_sgDropDecal, void, 6, 6, "(Point3F pos, Point3F tandir, Point3F norm, "
|
||||
"Point3F scale, decalDataBlock) - this method must be called on the client side! "
|
||||
"This method drops a decal onto the interior or "
|
||||
"terrain directly below the given position.")
|
||||
{
|
||||
// is this the client side?
|
||||
// doesn't work...
|
||||
//if(!gDecalManager->isGhost())
|
||||
// return;
|
||||
|
||||
Point3F pos = Point3F(0, 0, 0);
|
||||
Point3F tandir = Point3F(1, 0, 0);
|
||||
Point3F normal = Point3F(0, 0, 1);
|
||||
Point3F scale = Point3F(1, 1, 1);
|
||||
DecalData *decaldata = NULL;
|
||||
|
||||
dSscanf(argv[1],"%f %f %f",&pos.x,&pos.y,&pos.z);
|
||||
dSscanf(argv[2],"%f %f %f",&tandir.x,&tandir.y,&tandir.z);
|
||||
dSscanf(argv[3],"%f %f %f",&normal.x,&normal.y,&normal.z);
|
||||
dSscanf(argv[4],"%f %f %f",&scale.x,&scale.y,&scale.z);
|
||||
|
||||
decaldata = dynamic_cast<DecalData *>(Sim::findObject(argv[5]));
|
||||
|
||||
if(!decaldata)
|
||||
return;
|
||||
|
||||
RayInfo info;
|
||||
if(!gClientContainer.castRay(pos, (pos + Point3F(0, 0, -100)),
|
||||
InteriorObjectType | TerrainObjectType, &info))
|
||||
{
|
||||
Con::errorf("Error in _sgDropDecal: no drop object found.");
|
||||
return;
|
||||
}
|
||||
|
||||
pos = info.point;
|
||||
normal = info.normal;
|
||||
|
||||
gDecalManager->addDecal(pos, tandir, normal, scale, decaldata);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user