The first-person cockpit now shows by default and matches gameplay footage (verified on the Madcat). Two decomp-verified reconstructions: EYEPOINT (FUN_004579a8 + caller part_014.c:5525, FUN_004c22c4): - eye offset = siteeyepoint GetBaseOffset (not GetSegmentToEntity, not the upright hack), parented on the PARENT segment DCS (btl4vid.cpp) - live view = affine INVERSE of the eye world matrix (L4VIDRND Execute) -- replaces the hand-rolled LookAtRH whose +Z-forward/+Y-up row guess aimed some mechs into the canopy; combine order fixed to baseOffset * R - chase camera basis + aim boresight re-expressed for the inverse convention (row2 = back); boresight now derives from the view matrix (the stale rows aimed the pick ray at the sky = no target, no discharge) CANOPY (*_COP.BGF, dpl_Punchize geogroups): - every shell is an open strut lattice (38-59% boundary edges, all 12 mechs); rendered single-sided with per-face INWARD winding (l/r torso patches are mirrored, so no global winding works) the struts are the dark frame and the openings show the world - frame colour = the 'softer' ramp near its dark end (texture-less unlit ramp; BLXSKIN.BMF has no texture -- the old "punch texels" theory was wrong) - scoped by filename (meshIsCop); wrong drop-punch + view-cut paths removed - BT_FORCE_MODEL=<name> forces the player mech for per-mech bring-up KB: new context/cockpit-view.md topic; punch split corrected in bgf-format; gotchas 14 (LookAt axis guess) + 15 (per-patch edge namespaces); env gates + eye/punch addresses in decomp-reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7499 lines
241 KiB
C++
7499 lines
241 KiB
C++
#include "mungal4.h"
|
|
|
|
// BT bring-up (task #15/#20): the player mech's live root-bob offset, published
|
|
// per-frame by the game's gait tick (decomp/reconstructed/mech4.cpp); consumed
|
|
// by DPLEyeRenderable::Execute so the cockpit view bobs with the walk cycle.
|
|
// (Authentic path = the gyro-driven eye-joint DCS chain -- deferred.)
|
|
float gBTEyeBobY = 0.0f;
|
|
float gBTEyeSwayX = 0.0f; // lateral weight-shift (the walk "swagger"), same source
|
|
#pragma hdrstop
|
|
|
|
#include "l4vidrnd.h"
|
|
#include "..\munga\vector2d.h"
|
|
#include "..\munga\matrix.h"
|
|
#include "..\munga\mover.h"
|
|
#include "..\munga\player.h"
|
|
#include "l4video.h"
|
|
#include "..\munga\nttmgr.h"
|
|
#include "l4app.h"
|
|
#include "..\RP\VTV.h"
|
|
|
|
// RB 1/14/07
|
|
//#include <dpl\dpl.h>
|
|
//#include <dpl\dpl_2d.h>
|
|
//#include <dpl\dpl_vpx.h>
|
|
//#include <dpl\dplutils.h>
|
|
//#include <dpl\matrix.h>
|
|
|
|
#if defined(TRACE_VIDEO_MECH_CULL_RENDERABLE)
|
|
static BitTrace Video_Mech_Cull_Renderable("Video Mech Cull Renderable");
|
|
#define SET_VIDEO_MECH_CULL_RENDERABLE() Video_Mech_Cull_Renderable.Set()
|
|
#define CLEAR_VIDEO_MECH_CULL_RENDERABLE() Video_Mech_Cull_Renderable.Clear()
|
|
#else
|
|
#define SET_VIDEO_MECH_CULL_RENDERABLE()
|
|
#define CLEAR_VIDEO_MECH_CULL_RENDERABLE()
|
|
#endif
|
|
|
|
//
|
|
// Below allows the use of DPLDelayDCSFlush to be on or off
|
|
//
|
|
#if 1
|
|
# define HACK_DPL_FLUSH_DCS(a)\
|
|
{L4Application *l4_application = Cast_Object(L4Application*, application);\
|
|
Check(l4_application);\
|
|
l4_application->GetVideoRenderer()->DPLDelayDCSFlush(a);}
|
|
# define DPL_FLUSH_DCS(a)\
|
|
{myRenderer->DPLDelayDCSFlush(a);}
|
|
#else
|
|
# define DPL_FLUSH_DCS(a)\
|
|
dpl_FlushDCS(a)
|
|
# define HACK_DPL_FLUSH_DCS(a)\
|
|
dpl_FlushDCS(a)
|
|
#endif
|
|
|
|
//
|
|
// All renderables that need to use "Now()" should use renderer frame time
|
|
// as it should be much quicker (it returns the time at the start of the
|
|
// frame execution. All the renderables should know which renderer they belong
|
|
// to, but since many don't, this macro will supply the time from the default one
|
|
//
|
|
#define GET_CURRENT_FRAME_TIME() \
|
|
{L4Application *l4_application = Cast_Object(L4Application*, application);\
|
|
Check(l4_application);\
|
|
l4_application->GetVideoRenderer()->GetCurrentFrameTime();}
|
|
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
// All the stuff between these big ugly bars is the new video component stuff//
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
//===========================================================================//
|
|
HierarchicalDrawComponent::HierarchicalDrawComponent(RegisteredClass::ClassID classId)
|
|
:Component(classId), isDeathDraw(false)
|
|
{
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
myRenderer = l4_application->GetVideoRenderer();
|
|
m_parent = NULL;
|
|
}
|
|
|
|
HierarchicalDrawComponent::HierarchicalDrawComponent(RegisteredClass::ClassID classId, HierarchicalDrawComponent *parent)
|
|
:Component(classId), isDeathDraw(false), graphicalObject(NULL)
|
|
{
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
myRenderer = l4_application->GetVideoRenderer();
|
|
|
|
m_parent = parent;
|
|
|
|
if (m_parent != NULL)
|
|
{
|
|
m_parent->addChild(this);
|
|
}
|
|
}
|
|
|
|
HierarchicalDrawComponent::~HierarchicalDrawComponent()
|
|
{
|
|
if (m_parent != NULL)
|
|
{
|
|
m_parent->removeChild(this);
|
|
}
|
|
|
|
for (int i=0; i < m_children.size(); i++)
|
|
{
|
|
m_children[i]->clearParent();
|
|
}
|
|
|
|
m_children.clear();
|
|
}
|
|
|
|
void HierarchicalDrawComponent::ExecuteChildren()
|
|
{
|
|
std::vector<HierarchicalDrawComponent *>::iterator iter = m_children.begin();
|
|
|
|
while(iter != m_children.end())
|
|
{
|
|
(*iter)->Execute();
|
|
iter++;
|
|
}
|
|
}
|
|
|
|
std::vector<HierarchicalDrawComponent *>::const_iterator HierarchicalDrawComponent::Enumerate()
|
|
{
|
|
return this->m_children.begin();
|
|
}
|
|
|
|
std::vector<HierarchicalDrawComponent *>::const_iterator HierarchicalDrawComponent::End()
|
|
{
|
|
return this->m_children.end();
|
|
}
|
|
|
|
void HierarchicalDrawComponent::ResetDrawObj()
|
|
{
|
|
this->graphicalObject = NULL;
|
|
}
|
|
|
|
void HierarchicalDrawComponent::Execute()
|
|
{
|
|
ExecuteChildren();
|
|
|
|
if (graphicalObject != NULL)
|
|
{
|
|
if (isDeathDraw || !l4_application->IsDead())
|
|
{
|
|
// GROUND SHADOW (task #49b): tshd proxies go to the dedicated
|
|
// PASS_SHADOW list ONLY -- drawn after the static terrain but
|
|
// before the dynamic opaque bodies, so the mech's feet z-pass
|
|
// over the shadow instead of the biased shadow painting over
|
|
// the feet. (Their drawOps carry alphaTest=1, which would
|
|
// otherwise route them to the late alpha-blend pass.)
|
|
if (graphicalObject->GetIsShadow())
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_SHADOW);
|
|
}
|
|
else
|
|
{
|
|
bool addedToOpaqueList = false, addedToAlphaList = false, addedToDecalList = false, addedToSphereList = false, addedToSkyList = false;
|
|
for (int i=0; i<graphicalObject->GetDrawOpCount(); i++)
|
|
{
|
|
if (graphicalObject->GetDrawOp(i)->alphaTest)
|
|
{
|
|
if (!addedToAlphaList)
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_ALPHABLEND);
|
|
addedToAlphaList = true;
|
|
}
|
|
}
|
|
else if (graphicalObject->GetDrawOp(i)->drawAsDecal)
|
|
{
|
|
if (!addedToDecalList)
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_DECAL);
|
|
addedToDecalList = true;
|
|
}
|
|
}
|
|
else if (graphicalObject->GetDrawOp(i)->drawAsSky)
|
|
{
|
|
if (!addedToSkyList)
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_SKY);
|
|
addedToSkyList = true;
|
|
}
|
|
}
|
|
else if (graphicalObject->GetMesh() == NULL)
|
|
{
|
|
if (!addedToSphereList)
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_SPHERE);
|
|
addedToSphereList = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!addedToOpaqueList)
|
|
{
|
|
myRenderer->AddToPassList(graphicalObject, PASS_OPAQUE);
|
|
addedToOpaqueList = true;
|
|
}
|
|
}
|
|
}
|
|
} // close the non-shadow classification branch (task #49b)
|
|
}
|
|
}
|
|
}
|
|
|
|
void HierarchicalDrawComponent::Render(int pass, const D3DXMATRIX *viewTransform)
|
|
{
|
|
//if (graphicalObject != NULL && (isDeathDraw || l4_application->GetMissionPlayer()->GetPlayerVehicle()->GetSimulationState() != VTV::BurningState))
|
|
//{
|
|
// myRenderer->GetDevice()->SetTransform(D3DTS_WORLD, &myLocalToWorld);
|
|
// graphicalObject->Draw(pass, &myLocalToWorld, viewTransform);
|
|
//}
|
|
|
|
//std::vector<HierarchicalDrawComponent *>::iterator iter = m_children.begin();
|
|
|
|
//while (iter != m_children.end())
|
|
//{
|
|
// (*iter)->Render(pass, viewTransform);
|
|
// iter++;
|
|
//}
|
|
}
|
|
|
|
void HierarchicalDrawComponent::addChild(HierarchicalDrawComponent *child)
|
|
{
|
|
m_children.insert(m_children.end(), child);
|
|
}
|
|
|
|
void HierarchicalDrawComponent::removeChild(HierarchicalDrawComponent *child)
|
|
{
|
|
//Seek and remove
|
|
std::vector<HierarchicalDrawComponent *>::iterator iter = m_children.begin();
|
|
|
|
while(iter != m_children.end())
|
|
{
|
|
if (child == (*iter))
|
|
{
|
|
m_children.erase(iter);
|
|
child->clearParent();
|
|
break;
|
|
}
|
|
iter++;
|
|
}
|
|
}
|
|
|
|
void HierarchicalDrawComponent::clearParent()
|
|
{
|
|
m_parent = NULL;
|
|
}
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~This is a special class to speed up projectiles~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for InnerProjectileRenderable
|
|
//
|
|
InnerProjectileRenderable::InnerProjectileRenderable(
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone // DPL Zone this stuff will live in (for culling)
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID) // Inherited constructor
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
graphicalObject = graphical_object;
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check incoming data
|
|
////
|
|
//Check_Pointer(this_zone);
|
|
//Check_Pointer(graphical_object);
|
|
////
|
|
//// Construct the hiearchy the projectile needs to be renderable
|
|
////
|
|
//myDCS = dpl_NewDCS ();
|
|
//myInstance = dpl_NewInstance();
|
|
//Check_Pointer (myDCS);
|
|
//Check_Pointer (myInstance);
|
|
//dpl_SetDCSZone (myDCS, this_zone);
|
|
//dpl_SetInstanceObject (myInstance, graphical_object);
|
|
//dpl_SetInstanceIntersect (myInstance, dpl_isect_mode_obj );
|
|
//dpl_SetInstanceSectMask (myInstance, NULL );
|
|
//dpl_SetInstanceVisibility (myInstance, 1 );
|
|
//dpl_AddInstanceToDCS (myDCS, myInstance );
|
|
//dpl_AddDCSToScene (myDCS );
|
|
//dpl_FlushInstance (myInstance);
|
|
//dpl_FlushDCS (myDCS);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for InnerProjectileRenderable
|
|
//
|
|
InnerProjectileRenderable::~InnerProjectileRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Delete the instance(s) hanging on the DCS (if any)
|
|
//// NOTE: we may want to iterate through all the instances here using DPL routines
|
|
////
|
|
//dpl_RemoveInstanceFromDCS(myDCS, myInstance);
|
|
//dpl_RemoveDCSFromScene(myDCS);
|
|
//dpl_DeleteInstance(myInstance);
|
|
////
|
|
//// Delete the DCS
|
|
////
|
|
//dpl_DeleteDCS(myDCS);
|
|
//myDCS = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the InnerProjectileRenderable
|
|
//
|
|
Logical
|
|
InnerProjectileRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
Component::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check_Pointer(myInstance);
|
|
Check_Pointer(myDCS);
|
|
return True;
|
|
}
|
|
|
|
void InnerProjectileRenderable::Execute()
|
|
{
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
HierarchicalDrawComponent::Execute();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ProjectileRootRenderable
|
|
//
|
|
ProjectileRootRenderable::ProjectileRootRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone // DPL Zone this stuff will live in (for culling)
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
//
|
|
// Check the incoming pointers
|
|
//
|
|
Check_Pointer(graphical_object);
|
|
//Check_Pointer(this_zone);
|
|
//
|
|
// Get a projectile renderable we can use
|
|
//
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
myInnerProjectile = l4_application->GetVideoRenderer()->GetProjectile(
|
|
graphical_object,
|
|
isDeathZone);
|
|
Check(myInnerProjectile);
|
|
addChild(myInnerProjectile);
|
|
oldLocalToWorld = myEntity->localToWorld;
|
|
transMatrix = myEntity->localToWorld;
|
|
|
|
////This is necessary?
|
|
//myRenderer->mRenderables.Add(this);
|
|
l4_application->GetVideoRenderer()->AddRenderable(this);
|
|
|
|
//
|
|
// Set the DCS matrix and std::flush it
|
|
//
|
|
|
|
//float32* tempMatrix = dpl_GetDCSMatrix( myInnerProjectile->GetDCS());
|
|
//Check_Pointer ( tempMatrix );
|
|
//*(Matrix4x4*)tempMatrix = myEntity->localToWorld;
|
|
//DPL_FLUSH_DCS ( myInnerProjectile->GetDCS());
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ProjectileRootRenderable
|
|
//
|
|
ProjectileRootRenderable::~ProjectileRootRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
//
|
|
// return our inner renderable to the pool
|
|
//
|
|
Point3D infinity(0.0f, 10000.0f, 0.0f);
|
|
transMatrix = infinity;
|
|
//float32* tempMatrix = dpl_GetDCSMatrix(myInnerProjectile->GetDCS());
|
|
//Check_Pointer (tempMatrix);
|
|
//*(Matrix4x4*)tempMatrix = infinity;
|
|
//DPL_FLUSH_DCS ( myInnerProjectile->GetDCS() );
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
l4_application->GetVideoRenderer()->ReleaseProjectile(myInnerProjectile);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ProjectileRootRenderable
|
|
//
|
|
Logical
|
|
ProjectileRootRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
VideoRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(&oldLocalToWorld);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ProjectileRootRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
ProjectileRootRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// If our entity has changed it's localToWorld matrix, update DPL
|
|
//
|
|
if(oldLocalToWorld != myEntity->localToWorld)
|
|
{
|
|
oldLocalToWorld = myEntity->localToWorld;
|
|
transMatrix = oldLocalToWorld;
|
|
}
|
|
////
|
|
//// Call the next lower execute method
|
|
////
|
|
//#if DEBUG_LEVEL > 0
|
|
//VideoRenderable::Execute();
|
|
//#endif
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrix(&transMatrix.ToD3DMatrix());
|
|
VideoRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLObjectWrapper
|
|
//
|
|
DPLObjectWrapper::DPLObjectWrapper(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
const CString &name, // Name of the DPL object to load into the wrapper
|
|
dpl_LOAD_MODE cache_mode // DPL Zone this stuff will live in (for culling)
|
|
):
|
|
VideoRenderable(entity, DPLObjectWrapper::Static)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//
|
|
// Check the incoming pointers
|
|
//
|
|
Check(&name);
|
|
|
|
myDPLObject = d3d_OBJECT::LoadObject(myRenderer->GetDevice(),(char*)name);
|
|
myDPLObjectName = name;
|
|
////
|
|
//// Load the DPL object into the wrapper, try to get the object pointer from
|
|
//// the cache, if it isn't there, do a regular load.
|
|
////
|
|
//if(cache_mode == dpl_load_nocache)
|
|
//{
|
|
// L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// myDPLObject = l4_application->GetVideoRenderer()->GetCachedObject(name);
|
|
// if(!myDPLObject)
|
|
// {
|
|
// myDPLObject = dpl_LoadObject(name, cache_mode);
|
|
// }
|
|
//}
|
|
//else
|
|
//{
|
|
// myDPLObject = dpl_LoadObject(name, cache_mode);
|
|
//}
|
|
//myCacheMode = cache_mode;
|
|
//myDPLObjectName = name;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLObjectWrapper
|
|
//
|
|
DPLObjectWrapper::~DPLObjectWrapper()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Handle the unloading of DPL objects
|
|
////
|
|
//if(myCacheMode == dpl_load_nocache)
|
|
//{
|
|
// //
|
|
// // If this object was not cached, we will eventually return it to the video
|
|
// // renderer's list of unused uncached objects for later use by someone else
|
|
// //
|
|
// L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// l4_application->GetVideoRenderer()->PutCachedObject(myDPLObjectName, myDPLObject);
|
|
//}
|
|
//else
|
|
//{
|
|
// //
|
|
// // Do nothing (should unload the object)
|
|
// //
|
|
// //dpl_UnloadObject(myDPLObject);
|
|
//}
|
|
myDPLObject = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLObjectWrapper
|
|
//
|
|
Logical
|
|
DPLObjectWrapper::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
VideoRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check_Pointer(myDPLObject);
|
|
Check(&myDPLObjectName);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLObjectWrapper
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
DPLObjectWrapper::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// Call the next lower execute method
|
|
//
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~New Class Hiearchy for Renderables~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for VideoRenderable
|
|
//
|
|
VideoRenderable::VideoRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
HierarchicalDrawComponent *parent
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, parent) // Inherited constructor
|
|
{
|
|
//
|
|
// Check incoming data
|
|
//
|
|
Check(entity);
|
|
//
|
|
// Remember the entity and execution type
|
|
//
|
|
myEntity = entity;
|
|
myExecutionType = execution_type;
|
|
//
|
|
// HACK HACK HACK
|
|
// This initializes the video renderable's pointer back to the renderer that
|
|
// owns it so it can get information from that renderer. The renderer pointer
|
|
// really should be passed in as an argument, this is a concession to avoid
|
|
// spending the time to edit all references to the renderer so they support
|
|
// a new argument. This will be fixed later, for now we know there is only
|
|
// on renderer so we grab the application pointer and get the video renderer
|
|
// from it.
|
|
//
|
|
// SB - moved to HierarchicalDrawComponent
|
|
//
|
|
// Register us as static or dynamic
|
|
//
|
|
switch(myExecutionType)
|
|
{
|
|
case Static:
|
|
myEntity->AddStaticVideoComponent(this);
|
|
break;
|
|
case Dynamic:
|
|
// myEntity->AddDynamicVideoComponent(this);
|
|
myEntity->AddStaticVideoComponent(this);
|
|
myRenderer->AddDynamicRenderable(this);
|
|
break;
|
|
case Watcher:
|
|
myEntity->AddStaticVideoComponent(this);
|
|
break;
|
|
case Dependant:
|
|
myEntity->AddStaticVideoComponent(this);
|
|
break;
|
|
default:
|
|
Fail("VideoRenderable--Illegal execution type\n");
|
|
break;
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for VideoRenderable
|
|
//
|
|
VideoRenderable::~VideoRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
//
|
|
// Nothing else to do here
|
|
//
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the VideoRenderable
|
|
//
|
|
Logical
|
|
VideoRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
Component::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(myEntity);
|
|
Check(myRenderer);
|
|
Verify(myExecutionType >= Static && myExecutionType <= Dependant);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the VideoRenderable
|
|
// This method just checks to be sure we are not trying to execute a static
|
|
// renderable, then returns.
|
|
//
|
|
void VideoRenderable::Execute()
|
|
{
|
|
// if we're a static renderable then only execute the
|
|
// children and don't add ourselves to any render lists
|
|
//if (myExecutionType == Static)
|
|
// HierarchicalDrawComponent::ExecuteChildren();
|
|
//else
|
|
HierarchicalDrawComponent::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the ChildLightRenderable
|
|
//
|
|
// This renderable is used to connect a light as a child of an existing DCS
|
|
// the light isn't setup to move on it's own and creates a DCS only for the
|
|
// purpose of offsetting it from it's parent.
|
|
//
|
|
ChildLightRenderable::ChildLightRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
Scalar red, // light color
|
|
Scalar green,
|
|
Scalar blue,
|
|
Scalar inner_radius,
|
|
Scalar outer_radius,
|
|
dpl_LIGHT_TYPE light_type,
|
|
int light_mask
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check the inbound data
|
|
// //
|
|
// Check_Pointer(this_zone);
|
|
// Check_Pointer(parent_DCS);
|
|
// Check(offset_matrix);
|
|
// //
|
|
// // Remember the interesting parameters
|
|
// //
|
|
// myZone = this_zone;
|
|
// myParentDCS = parent_DCS;
|
|
myOffsetMatrix = *offset_matrix;
|
|
// //
|
|
// // Create the dpl DCS and the light that we will be using
|
|
// //
|
|
// myDCS = dpl_NewDCS ();
|
|
// myLight = dpl_NewLight();
|
|
// Check_Pointer(myDCS);
|
|
// Check_Pointer(myLight);
|
|
// //
|
|
// // Setup light type and color
|
|
// //
|
|
// dpl_SetLightType (myLight, light_type );
|
|
// dpl_SetLightColor (myLight, red, green, blue );
|
|
// dpl_SetLightDCS (myLight, myDCS );
|
|
// dpl_SetLightRadii (myLight, inner_radius, outer_radius );
|
|
// dpl_SetLightLightingMask (myLight, light_mask);
|
|
// //
|
|
// // Connect the DCS just created to a parent
|
|
// //
|
|
// dpl_AddDCSToDCS ( myParentDCS, myDCS );
|
|
// //
|
|
// // Set the DCS into the requested zone for culling
|
|
// //
|
|
// dpl_SetDCSZone ( myDCS, this_zone );
|
|
// //
|
|
// // Load up the DCS matrix with the supplied matrix
|
|
// //
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer(tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = myOffsetMatrix;
|
|
// //
|
|
// // Flip the light around to point the correct direction
|
|
// //
|
|
//// dpl_RotateDCS ( myDCS, 180.0f, dpl_Y );
|
|
// //
|
|
// // Flush out the instance and DCS
|
|
// //
|
|
// dpl_FlushLight ( myLight);
|
|
// dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ChildLightRenderable
|
|
//
|
|
ChildLightRenderable::~ChildLightRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Check(this);
|
|
//dpl_DeleteDCS(myDCS);
|
|
//dpl_DeleteLight(myLight);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ChildLightRenderable
|
|
//
|
|
Logical
|
|
ChildLightRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer(myDCS);
|
|
Check_Pointer(myParentDCS);
|
|
Check_Pointer(myLight);
|
|
Check(&myOffsetMatrix);
|
|
return True;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for ChildLightRenderable
|
|
//
|
|
void ChildLightRenderable::Execute()
|
|
{
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&myOffsetMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
//Do something with light?
|
|
VideoRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DCSObjectRenderable
|
|
//
|
|
DCSObjectRenderable::DCSObjectRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
//
|
|
// Check incoming data
|
|
//
|
|
#if DEBUG_LEVEL > 0
|
|
if(graphical_object)
|
|
Check_Pointer(graphical_object); // allowed to be null
|
|
#endif
|
|
Check_Pointer(this_zone);
|
|
//
|
|
// Remember my d3d object, intersect and offset data
|
|
//
|
|
graphicalObject = graphical_object;
|
|
//myDPLZone = this_zone;
|
|
myIntersectMode = intersect_mode;
|
|
myIntersectMask = intersect_mask;
|
|
myDCS = NULL;
|
|
myInstance = NULL;
|
|
//
|
|
// We need to construct a DCS node here and remember it. The next class up is
|
|
// expected to handle the std::flushing and connecting of structure so we just setup
|
|
// the DCS and zone information here, leaving std::flushing to someone else.
|
|
//
|
|
// myDCS = dpl_NewDCS ();
|
|
|
|
Check_Pointer ( myDCS );
|
|
// dpl_SetDCSZone ( myDCS, myDPLZone );
|
|
//
|
|
// Construct the instance(s) and hang them on the DCS. Since we may be building
|
|
// more than one instance, we have to take care of std::flushing them here.
|
|
//
|
|
if(myD3DObject)
|
|
{
|
|
// myInstance = dpl_NewInstance();
|
|
|
|
Check_Pointer ( myInstance);
|
|
// dpl_SetInstanceObject ( myInstance, myDPLObject);
|
|
// dpl_SetInstanceIntersect ( myInstance, myIntersectMode );
|
|
// dpl_SetInstanceSectMask ( myInstance, myIntersectMask );
|
|
// dpl_SetInstanceVisibility ( myInstance, 1 );
|
|
// dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
|
|
// dpl_FlushInstance ( myInstance );
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DCSObjectRenderable
|
|
//
|
|
DCSObjectRenderable::~DCSObjectRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Delete the instance(s) hanging on the DCS (if any)
|
|
//// NOTE: we may want to iterate through all the instances here using DPL routines
|
|
////
|
|
//if(myInstance)
|
|
//{
|
|
// dpl_RemoveInstanceFromDCS(myDCS, myInstance);
|
|
// dpl_DeleteInstance(myInstance);
|
|
//}
|
|
////
|
|
//// Delete the DCS
|
|
////
|
|
//dpl_DeleteDCS(myDCS);
|
|
//myDCS = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DCSObjectRenderable
|
|
//
|
|
Logical
|
|
DCSObjectRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
VideoRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
#if DEBUG_LEVEL > 0
|
|
if(myDPLObject)
|
|
Check_Pointer(myDPLObject);
|
|
if(myInstance)
|
|
Check_Pointer(myInstance);
|
|
#endif
|
|
Check_Pointer(myDPLZone);
|
|
Check_Pointer(myDCS);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DCSObjectRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void DCSObjectRenderable::Execute()
|
|
{
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Call the next lower execute method
|
|
////
|
|
//#if DEBUG_LEVEL > 0
|
|
//VideoRenderable::Execute();
|
|
// #endif
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
|
|
//HierarchicalDrawComponent::Execute();
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DCSInstanceRenderable
|
|
//
|
|
DCSInstanceRenderable::DCSInstanceRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to connect to the instance
|
|
HierarchicalDrawComponent *parent, // the DCS to add the instance to
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
Logical visible // initial visibility setting
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
//
|
|
// Check incoming data
|
|
//
|
|
Check_Pointer(graphical_object);
|
|
Check_Pointer(parent_DCS);
|
|
//
|
|
// Remember my dpl object, intersect and offset data
|
|
//
|
|
graphicalObject = graphical_object;
|
|
myIntersectMode = intersect_mode;
|
|
myIntersectMask = intersect_mask;
|
|
// myDCS = parent_DCS;
|
|
//myInstance = dpl_NewInstance();
|
|
Check_Pointer(myInstance);
|
|
//
|
|
// Construct the instance(s) and hang them on the parent DCS
|
|
//
|
|
//dpl_SetInstanceObject ( myInstance, myDPLObject);
|
|
//dpl_SetInstanceIntersect ( myInstance, myIntersectMode );
|
|
//dpl_SetInstanceSectMask ( myInstance, myIntersectMask );
|
|
//dpl_SetInstanceVisibility ( myInstance, visible );
|
|
//dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
//dpl_FlushInstance ( myInstance );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DCSInstanceRenderable
|
|
//
|
|
DCSInstanceRenderable::~DCSInstanceRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Disconnect the instance from the DCS and delete the instance
|
|
////
|
|
//dpl_RemoveInstanceFromDCS(myDCS, myInstance);
|
|
//dpl_DeleteInstance(myInstance);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DCSInstanceRenderable
|
|
//
|
|
Logical
|
|
DCSInstanceRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
VideoRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check_Pointer(myDPLObject);
|
|
Check_Pointer(myInstance);
|
|
Check_Pointer(myDCS);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DCSInstanceRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
DCSInstanceRenderable::Execute()
|
|
{
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
//HierarchicalDrawComponent::Execute();
|
|
////
|
|
//// Call the next lower execute method
|
|
////
|
|
//#if DEBUG_LEVEL > 0
|
|
//VideoRenderable::Execute();
|
|
//#endif
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
//myRenderer->GetMatrixStack()->MultMatrixLocal(&OrientationMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
VideoRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for RootRenderable
|
|
//
|
|
RootRenderable::RootRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object,
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask // intersection mask for the object
|
|
):
|
|
DCSObjectRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask) // intersection mask for the object
|
|
{
|
|
//
|
|
// All the incoming data will have been checked by DCSObjectRenderable
|
|
// already, so we don't have to check anything locally.
|
|
//
|
|
//
|
|
// Initialize our variables
|
|
//
|
|
oldLocalToWorld = myEntity->localToWorld;
|
|
//
|
|
// Now we finish the work of hooking up and initializing the root renderable
|
|
// Add the DCS to the scene and initialize it's matrix with the localToWorld
|
|
// transformation from our entity
|
|
//
|
|
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
l4_application->GetVideoRenderer()->AddRenderable(this);
|
|
|
|
// dpl_AddDCSToScene ( myDCS );
|
|
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// *(Matrix4x4*)tempMatrix = myEntity->localToWorld;
|
|
|
|
// dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for RootRenderable
|
|
//
|
|
RootRenderable::~RootRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Remove the DCS from the scene, deletion of the DCS and it's instances is
|
|
//// handled by our parent class.
|
|
////
|
|
//dpl_RemoveDCSFromScene(myDCS);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the RootRenderable
|
|
//
|
|
Logical
|
|
RootRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
DCSObjectRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(&oldLocalToWorld);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the RootRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
RootRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
// We don't need to do this because we're going to use the matrix directly
|
|
// //
|
|
// // If our entity has changed it's localToWorld matrix, update DPL
|
|
// //
|
|
// if(oldLocalToWorld != myEntity->localToWorld)
|
|
// {
|
|
// oldLocalToWorld = myEntity->localToWorld;
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer (tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = oldLocalToWorld;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
// }
|
|
myRenderer->GetMatrixStack()->Push();
|
|
Matrix4x4 tempMatrix;
|
|
tempMatrix = myEntity->localToWorld;
|
|
|
|
myRenderer->GetMatrixStack()->MultMatrix(&tempMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
|
|
DCSObjectRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ChildOffsetRenderable
|
|
//
|
|
ChildOffsetRenderable::ChildOffsetRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix // offset matrix to be applied prior to joint DCS
|
|
):
|
|
DCSObjectRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent)
|
|
{
|
|
//
|
|
// Check incoming data not handled by lower levels
|
|
//
|
|
Check(offset_matrix);
|
|
//
|
|
// Remember my offset matrix
|
|
//
|
|
myOffsetMatrix = *offset_matrix;
|
|
myOffsetDCS = NULL;
|
|
//myParentDCS = parent_DCS;
|
|
//
|
|
// We construct the offset DCS node and link the DCS carrying our our
|
|
// graphical instances to it.
|
|
//
|
|
// myOffsetDCS = dpl_NewDCS ();
|
|
Check_Pointer ( myOffsetDCS );
|
|
// dpl_SetDCSZone ( myDCS, myDPLZone );
|
|
// dpl_AddDCSToDCS ( myOffsetDCS, myDCS );
|
|
//
|
|
// Now we connect that DCS to our parent
|
|
//
|
|
// dpl_AddDCSToDCS ( myParentDCS, myOffsetDCS);
|
|
//
|
|
// Then fill in the offset DCS and std::flush it
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myOffsetDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// *(Matrix4x4*)tempMatrix = myOffsetMatrix;
|
|
// dpl_FlushDCS ( myOffsetDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ChildOffsetRenderable
|
|
//
|
|
ChildOffsetRenderable::~ChildOffsetRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Delete the connection to our parent DCS
|
|
////
|
|
//dpl_RemoveDCSFromDCS(myParentDCS, myOffsetDCS);
|
|
////
|
|
//// Delete the static DCS and it's connections to the dynamic one
|
|
////
|
|
//dpl_RemoveDCSFromDCS(myOffsetDCS, myDCS);
|
|
//dpl_DeleteDCS(myOffsetDCS);
|
|
//myOffsetDCS = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ChildOffsetRenderable
|
|
//
|
|
Logical
|
|
ChildOffsetRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
DCSObjectRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check_Pointer(myParentDCS);
|
|
Check_Pointer(myOffsetDCS);
|
|
Check(&myOffsetMatrix);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ChildOffsetRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
ChildOffsetRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// Call the next lower execute method
|
|
//
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&myOffsetMatrix.ToD3DMatrix());
|
|
DCSObjectRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for HingeRenderable
|
|
//
|
|
#define SINGLE_AXIS_HINGE True
|
|
|
|
HingeRenderable::HingeRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
const Hinge *my_hinge // Hinge attribute we will use to control the joint
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//
|
|
// Check the incomming data
|
|
//
|
|
Check(my_hinge);
|
|
//
|
|
// Initialize our variables
|
|
//
|
|
myHinge = my_hinge;
|
|
oldHinge = *my_hinge;
|
|
//
|
|
// Dump the initial value of the hing into the DCS our instances are attached
|
|
// to, then std::flush it out. We have to copy the hinge to a quaternion because
|
|
// the math library doesn't support direct assignment of hing to matrix yet.
|
|
//
|
|
hingeOffsetMatrix.BuildIdentity();
|
|
/*#if SINGLE_AXIS_HINGE
|
|
SinCosPair
|
|
temp_sin_cos_pair;
|
|
temp_sin_cos_pair = myHinge->rotationAmount;
|
|
switch(myHinge->axisNumber)
|
|
{
|
|
case X_Axis:
|
|
// dpl_SetDCSXAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
hingeOffsetMatrix.
|
|
break;
|
|
case Y_Axis:
|
|
// dpl_SetDCSYAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
break;
|
|
case Z_Axis:
|
|
// dpl_SetDCSZAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
break;
|
|
}
|
|
#else*/
|
|
Quaternion
|
|
temp_quaternion;
|
|
// float32
|
|
// *temp_matrix;
|
|
// temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer( temp_matrix );
|
|
temp_quaternion = oldHinge;
|
|
hingeOffsetMatrix.BuildRotation(temp_quaternion);
|
|
// *(Matrix4x4*)temp_matrix = temp_quaternion;
|
|
//#endif
|
|
// dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for HingeRenderable
|
|
//
|
|
HingeRenderable::~HingeRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the HingeRenderable
|
|
//
|
|
Logical
|
|
HingeRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(myHinge);
|
|
Check(&oldHinge);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the HingeRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
HingeRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// If the hinge we're watching has changed, update our matrix
|
|
//
|
|
if(oldHinge != *myHinge)
|
|
{
|
|
oldHinge = *myHinge;
|
|
hingeOffsetMatrix.BuildIdentity();
|
|
//#if SINGLE_AXIS_HINGE
|
|
// SinCosPair
|
|
// temp_sin_cos_pair;
|
|
// temp_sin_cos_pair = myHinge->rotationAmount;
|
|
// switch(myHinge->axisNumber)
|
|
// {
|
|
// case X_Axis:
|
|
// dpl_SetDCSXAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
// break;
|
|
// case Y_Axis:
|
|
// dpl_SetDCSYAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
// break;
|
|
// case Z_Axis:
|
|
// dpl_SetDCSZAxis(myDCS, temp_sin_cos_pair.sine, temp_sin_cos_pair.cosine);
|
|
// break;
|
|
// }
|
|
//#else
|
|
Quaternion
|
|
temp_quaternion;
|
|
// float32
|
|
// *temp_matrix;
|
|
// temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer( temp_matrix );
|
|
temp_quaternion = oldHinge;
|
|
hingeOffsetMatrix.BuildRotation(temp_quaternion);
|
|
// *(Matrix4x4*)temp_matrix = temp_quaternion;
|
|
//#endif
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
}
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&myOffsetMatrix.ToD3DMatrix());
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&hingeOffsetMatrix.ToD3DMatrix());
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
DCSObjectRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for BallJointRenderable
|
|
//
|
|
BallJointRenderable::BallJointRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
const EulerAngles *my_euler // Euler angles to control rotation of the ball joint
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//float32
|
|
// *temp_matrix;
|
|
//
|
|
// Check the incomming data
|
|
//
|
|
Check(my_euler);
|
|
//
|
|
// Initialize our variables
|
|
//
|
|
myEuler = my_euler;
|
|
oldEuler = *my_euler;
|
|
//
|
|
// Dump the initial value of the euler angles into the DCS our instances are attached
|
|
// to, then std::flush it out.
|
|
//
|
|
eulerMatrix = *myEuler;
|
|
//temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
//Check_Pointer( temp_matrix );
|
|
//*(Matrix4x4*)temp_matrix = oldEuler;
|
|
//dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for BallJointRenderable
|
|
//
|
|
BallJointRenderable::~BallJointRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the BallJointRenderable
|
|
//
|
|
Logical
|
|
BallJointRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(myEuler);
|
|
Check(&oldEuler);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the BallJointRenderable
|
|
//
|
|
void
|
|
BallJointRenderable::Execute()
|
|
{
|
|
//float32
|
|
// *temp_matrix;
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// If the hinge we're watching has changed, update our matrix
|
|
//
|
|
if(oldEuler != *myEuler)
|
|
{
|
|
oldEuler = *myEuler;
|
|
eulerMatrix = oldEuler;
|
|
// temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer( temp_matrix );
|
|
// *(Matrix4x4*)temp_matrix = oldEuler;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
}
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&myOffsetMatrix.ToD3DMatrix());
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&eulerMatrix.ToD3DMatrix());
|
|
DCSObjectRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for BallTranslateJointRenderable
|
|
//
|
|
BallTranslateJointRenderable::BallTranslateJointRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
const EulerAngles *my_euler, // Euler angles to control rotation of the ball joint
|
|
const Point3D *my_translation // offset for the translation part of the joint
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
AffineMatrix
|
|
tempAffine(True);
|
|
|
|
//float32
|
|
// *temp_matrix;
|
|
//
|
|
// Check the incomming data
|
|
//
|
|
Check(my_euler);
|
|
Check(my_translation);
|
|
//
|
|
// Initialize our variables
|
|
//
|
|
myEuler = my_euler;
|
|
oldEuler = *my_euler;
|
|
myTranslation = my_translation;
|
|
oldTranslation = *my_translation;
|
|
//
|
|
// Dump the initial value of the euler angles into the DCS our instances are attached
|
|
// to, then std::flush it out.
|
|
//
|
|
//temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
Check_Pointer( temp_matrix );
|
|
tempAffine = oldTranslation;
|
|
tempAffine = oldEuler;
|
|
jointMatrix = tempAffine;
|
|
//*(Matrix4x4*)temp_matrix = tempAffine;
|
|
//dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for BallTranslateJointRenderable
|
|
//
|
|
BallTranslateJointRenderable::~BallTranslateJointRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the BallTranslateJointRenderable
|
|
//
|
|
Logical
|
|
BallTranslateJointRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(myEuler);
|
|
Check(&oldEuler);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the BallTranslateJointRenderable
|
|
//
|
|
void
|
|
BallTranslateJointRenderable::Execute()
|
|
{
|
|
//float32
|
|
// *temp_matrix;
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// If the hinge we're watching has changed, update our matrix
|
|
//
|
|
if(oldEuler != *myEuler || oldTranslation != *myTranslation)
|
|
{
|
|
oldEuler = *myEuler;
|
|
oldTranslation = *myTranslation;
|
|
// temp_matrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer( temp_matrix );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine = oldTranslation;
|
|
tempAffine = oldEuler;
|
|
jointMatrix = tempAffine;
|
|
// *(Matrix4x4*)temp_matrix = tempAffine;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
}
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&myOffsetMatrix.ToD3DMatrix());
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&jointMatrix.ToD3DMatrix());
|
|
DCSObjectRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for SpinScaleQuatRenderable
|
|
//
|
|
SpinScaleQuatRenderable::SpinScaleQuatRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
Quaternion *rotation_quaternion,// rotates the object
|
|
Vector3D *scale_vector, // Scales the object
|
|
Logical *visible, // turns the object on and off
|
|
Scalar z_spin_rate // spins the object about z (radians/frame)
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check the inbound data
|
|
////
|
|
//Check(rotation_quaternion);
|
|
//Check(scale_vector);
|
|
//Check_Pointer(visible);
|
|
////
|
|
//// Remember the entity that this renderable is attached to and the
|
|
//// orientation matrix that offsets it to the correct position.
|
|
////
|
|
//myRotationQuaternion = rotation_quaternion;
|
|
//myScaleVector = scale_vector;
|
|
//myVisible = visible;
|
|
//myZSpinRate = z_spin_rate;
|
|
//OldVisible = *visible;
|
|
//OldZSpin = 0;
|
|
////
|
|
//// Setup the dcs matrix to it's initial state
|
|
////
|
|
//float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
//Check_Pointer ( tempMatrix );
|
|
//AffineMatrix tempAffine(True);
|
|
//tempAffine *= (*myScaleVector);
|
|
//tempAffine *= (*myRotationQuaternion);
|
|
//*(Matrix4x4*)tempMatrix = tempAffine;
|
|
//dpl_FlushDCS ( myDCS );
|
|
////
|
|
//// Set the instance visibility correctly
|
|
////
|
|
//dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
//dpl_FlushInstance ( myInstance );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for SpinScaleQuatRenderable
|
|
//
|
|
SpinScaleQuatRenderable::~SpinScaleQuatRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the SpinScaleQuatRenderable
|
|
//
|
|
Logical
|
|
SpinScaleQuatRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the SpinScaleQuatRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
SpinScaleQuatRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Load up the DCS matrix with the localToWorld matrix from the entity
|
|
//// then std::flush out the new DCS
|
|
////
|
|
//if(OldVisible != *myVisible)
|
|
//{
|
|
// OldVisible = *myVisible;
|
|
// dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
// dpl_FlushInstance ( myInstance );
|
|
//}
|
|
////
|
|
//// If the beam is visible, we have to update it
|
|
////
|
|
//if(OldVisible)
|
|
//{
|
|
// OldZSpin += myZSpinRate;
|
|
// if(OldZSpin > TWO_PI)
|
|
// OldZSpin -= TWO_PI;
|
|
// Hinge temp_hinge(Z_Axis, OldZSpin);
|
|
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
|
|
// AffineMatrix tempAffine(True);
|
|
// Quaternion temp_quaternion;
|
|
// temp_quaternion = temp_hinge;
|
|
// tempAffine = temp_quaternion;
|
|
// tempAffine *= (*myScaleVector);
|
|
// temp_quaternion = *myRotationQuaternion;
|
|
// tempAffine *= temp_quaternion;
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
//}
|
|
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
ChildOffsetRenderable::Execute();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for POVTranslocateRenderable
|
|
//
|
|
// BT (task #52): world-mask bridge for the reconstructed translocation warp. The
|
|
// authentic POVTranslocateRenderable toggles l4_application->SetIsDead around its
|
|
// collapse/expand (L4VIDRND.cpp:1947/1989) to black out the world during the death
|
|
// throb and reveal it on rebirth. Our reconstruction drives the warp from
|
|
// btl4vid.cpp (no L4Application handle there), so expose the same flag through this
|
|
// bridge. It is a PURE render-pass gate (verified: every IsDead() reader is a draw
|
|
// loop -- terrain/decal/sky/alpha/particles/reticle; no camera/input/targeting), so
|
|
// driving it directly is safe -- unlike pulsing the SimulationState trigger, which
|
|
// also drives the camera/POV + targeting (the f053535 regression).
|
|
void BTSetWorldDead(int dead)
|
|
{
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
if (l4_application != 0)
|
|
l4_application->SetIsDead(dead != 0);
|
|
}
|
|
|
|
POVTranslocateRenderable::POVTranslocateRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
bool isDeathZone, // DPL zone the world is in
|
|
dpl_ZONE *death_zone, // DPL zone the player's VTV and death effect are in
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
StateIndicator *effect_trigger, // State dial we use to control the translocation
|
|
unsigned effect_control_state // State that controls start/end of the effect
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
#define COLLAPSE_TIME 1.3f // Time in seconds for initial collapse
|
|
#define COLLAPSE_START_SCALE 100.0f // Scale factor of the sphere when we start collapse
|
|
#define EXPAND_TIME 1.0f // Time that expansion of the sphere should take
|
|
#define EXPAND_END_SCALE 150.0f // Scale factor of the sphere when expansion ends
|
|
#define ROTATE_RATE (0.5f * (0.01745329222222))
|
|
#define ROTATE_LIMIT (20.0f * (0.01745329222222))
|
|
#define TRANSLATE_RATE 0.2f
|
|
#define TRANSLATE_LIMIT 2.0f
|
|
// // HACK HACK HACK this should be removed once red planet is checked out
|
|
if(execution_type != Watcher)
|
|
std::cout<<"POVTranslocateRenderable wants to be a watcher and isn't!\n";
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
// Check_Pointer(this_zone);
|
|
// Check_Pointer(death_zone);
|
|
// Check_Pointer(parent_DCS);
|
|
Check(effect_trigger);
|
|
//
|
|
// Remember the entity and DCS this renderable is attached to
|
|
//
|
|
// myZone = this_zone;
|
|
// myDeathZone = death_zone;
|
|
// myParentDCS = parent_DCS;
|
|
myEffectTrigger = effect_trigger;
|
|
myEffectControlState = effect_control_state;
|
|
myState = IdleState;
|
|
myRotateY = 0.0f;
|
|
myRotateYSpeed = TRANSLATE_RATE;
|
|
//
|
|
// Load up the object we're going to use for the translocation
|
|
//
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
// dpl_OBJECT* myTranslocateSphere = dpl_LoadObject ( "tsphere.bgf", dpl_load_normal );
|
|
myDevice = l4_application->GetVideoRenderer()->GetDevice();
|
|
myTranslocateSphere = d3d_OBJECT::LoadObject(myDevice, "tsphere.bgf");
|
|
graphicalObject = myTranslocateSphere;
|
|
|
|
if (isDeathDraw)
|
|
{
|
|
//Draw this as sky
|
|
for (int i = 0; i < graphicalObject->GetDrawOpCount(); i++)
|
|
{
|
|
graphicalObject->GetDrawOp(i)->drawAsSky = true;
|
|
}
|
|
}
|
|
// Check_Pointer(myTranslocateSphere);
|
|
//
|
|
// Setup a DCS that we can put the sphere on so it can be rotated and scaled
|
|
// around the VTV. Attach the sphere to this DCS but make it invisible.
|
|
//
|
|
// myInstance = dpl_NewInstance();
|
|
// myDCS = dpl_NewDCS();
|
|
Check_Pointer (myInstance);
|
|
Check_Pointer (myDCS);
|
|
// dpl_AddDCSToDCS (myParentDCS, myDCS);
|
|
// dpl_SetDCSZone (myDCS, myDeathZone);
|
|
// dpl_SetInstanceObject (myInstance, myTranslocateSphere);
|
|
// dpl_SetInstanceIntersect (myInstance, dpl_isect_mode_obj);
|
|
// dpl_SetInstanceSectMask (myInstance, NULL);
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
visible = false;
|
|
// dpl_AddInstanceToDCS (myDCS, myInstance);
|
|
// dpl_FlushInstance (myInstance);
|
|
// dpl_FlushDCS (myDCS);
|
|
//
|
|
// Connect us to the state dial's watcher hook
|
|
//
|
|
//l4_application->GetVideoRenderer()->mDeathRenderables.Add(this);
|
|
myEffectTrigger->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for POVTranslocationRenderable
|
|
//
|
|
POVTranslocateRenderable::~POVTranslocateRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Check(this);
|
|
////
|
|
//// Disconnect the structure we have setup
|
|
////
|
|
//dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
//dpl_RemoveInstanceFromDCS(myDCS,myInstance);
|
|
////
|
|
//// Delete the DPL elements we created
|
|
////
|
|
//dpl_DeleteInstance(myInstance);
|
|
//dpl_DeleteDCS(myDCS);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the POVTranslocateRenderable
|
|
//
|
|
Logical
|
|
POVTranslocateRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
|
|
Check_Pointer(myZone);
|
|
Check_Pointer(myDeathZone);
|
|
Check_Pointer(myParentDCS);
|
|
Check(myEffectTrigger);
|
|
Check_Pointer(myInstance);
|
|
Check_Pointer(myDCS);
|
|
Verify(myState >= IdleState && myState <= ExpandRevealState);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for POVTranslocateRenderable.
|
|
//
|
|
void
|
|
POVTranslocateRenderable::Execute()
|
|
{
|
|
Scalar
|
|
elapsed_time,
|
|
current_time,
|
|
percent_time_left,
|
|
percent_time_used,
|
|
scale_factor;
|
|
unsigned
|
|
current_trigger_state;
|
|
//
|
|
// Get the current state and the current time for later use
|
|
//
|
|
Check(myEffectTrigger);
|
|
current_trigger_state = myEffectTrigger->GetState();
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
//
|
|
// State engine (running off myState) to manage running of the death effect
|
|
//
|
|
// std::cout<<"POVTranslocateRenderable::Execute\n";
|
|
switch(myState)
|
|
{
|
|
//
|
|
// IdleState waits for a transition in the effect control state and starts
|
|
// the effect state machine when it detects one.
|
|
//
|
|
case IdleState:
|
|
{
|
|
if(current_trigger_state == myEffectControlState)
|
|
{
|
|
myState = InitialCollapseState;
|
|
myCollapseEnd = current_time + COLLAPSE_TIME;
|
|
visible = true;
|
|
// dpl_SetInstanceVisibility (myInstance, True);
|
|
// dpl_FlushInstance (myInstance);
|
|
myRenderer->AddDynamicRenderable(this);
|
|
std::cout<<"POVTranslocateRenderable::Going Dynamic\n";
|
|
}
|
|
break;
|
|
}
|
|
//
|
|
// This case handles ending the screen flash when we need to
|
|
//
|
|
case FlashScreenState:
|
|
{
|
|
myState = InitialCollapseState;
|
|
break;
|
|
}
|
|
//
|
|
// InitialCollapseState handles reducing the sphere from its max size down
|
|
// to one over a period of time. We figure the percentage of the time
|
|
// left then multiply it by the size the sphere started at to get the
|
|
// scale factor.
|
|
//
|
|
case InitialCollapseState:
|
|
{
|
|
percent_time_left = (myCollapseEnd - current_time)/COLLAPSE_TIME;
|
|
//
|
|
// See how much time is left in the effect.
|
|
//
|
|
|
|
if(percent_time_left <= 0.0f)
|
|
{
|
|
//
|
|
// Time's up! Go to WaitForReincarnate state, force scale factor to
|
|
// 1.0, and turn off the outside world4
|
|
//
|
|
scale_factor = 1.0f;
|
|
// dpl_SetZoneAllViewsOff (myZone);
|
|
// dpl_FlushZone (myZone);
|
|
|
|
myCollapseEnd = current_time;
|
|
myState = WaitForReincarnateState;
|
|
l4_application->SetIsDead(true);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Recalculate the scale factor based on time left
|
|
//
|
|
//visible = false;
|
|
scale_factor = (percent_time_left * COLLAPSE_START_SCALE) + 1.0f;
|
|
}
|
|
//
|
|
// Build a scaling identity matrix based on our scale factor
|
|
//
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine(0,0) = scale_factor;
|
|
tempAffine(1,1) = scale_factor;
|
|
tempAffine(2,2) = scale_factor;
|
|
//
|
|
// Put the scale matrix into the DCS and std::flush it.
|
|
//
|
|
localToWorld = tempAffine;
|
|
// tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// DPL_FLUSH_DCS (myDCS);
|
|
break;
|
|
}
|
|
//
|
|
// WaitForReincarnateState waits till we the trigger state switches off
|
|
// then does what we want to get us back into the world.
|
|
//
|
|
case WaitForReincarnateState:
|
|
{
|
|
if(current_trigger_state != myEffectControlState)
|
|
{
|
|
//
|
|
// Switch the world back on, then change states
|
|
//
|
|
// dpl_SetZoneAllViewsOn (myZone);
|
|
// dpl_FlushZone (myZone);
|
|
myState = ExpandRevealState;
|
|
myCollapseEnd = current_time + EXPAND_TIME;
|
|
l4_application->SetIsDead(false);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Mess with the DCS to make the tunnel effect more pronounced
|
|
//
|
|
elapsed_time = current_time - myCollapseEnd;
|
|
Point3D temp_point(
|
|
(cos(elapsed_time * 3.33) * TRANSLATE_LIMIT),
|
|
(sin(elapsed_time * 2.5) * TRANSLATE_LIMIT),
|
|
0.0);
|
|
// tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer( tempMatrix );
|
|
localToWorld = temp_point;
|
|
// *(Matrix4x4*)tempMatrix = temp_point;
|
|
// DPL_FLUSH_DCS(myDCS);
|
|
}
|
|
break;
|
|
}
|
|
//
|
|
// ExpandRevealState expands the sphere rapidly in size to reveal the world
|
|
// getting rid of the sphere when it hits a maximum size.
|
|
//
|
|
case ExpandRevealState:
|
|
{
|
|
//
|
|
// In case we get killed again while in this state, I watch for
|
|
// a change back into the trigger state and retrigger the
|
|
// effect if it shows up
|
|
//
|
|
if(current_trigger_state == myEffectControlState)
|
|
{
|
|
myState = InitialCollapseState;
|
|
myCollapseEnd = current_time + COLLAPSE_TIME;
|
|
//// dpl_SetInstanceVisibility (myInstance, True);
|
|
//// dpl_FlushInstance (myInstance);
|
|
//// myRenderer->AddDynamicRenderable(this);
|
|
//// std::cout<<"POVTranslocateRenderable::Going Dynamic\n";
|
|
}
|
|
percent_time_used = 1.0f - ((myCollapseEnd - current_time)/EXPAND_TIME);
|
|
if(percent_time_used >= 1.0f)
|
|
{
|
|
visible = false;
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
// dpl_FlushInstance (myInstance);
|
|
myState = IdleState;
|
|
scale_factor = 1.0f;
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
//// std::cout<<"POVTranslocateRenderable::Going Static\n";
|
|
}
|
|
else
|
|
{
|
|
scale_factor = (percent_time_used * EXPAND_END_SCALE) + 1.0f;
|
|
}
|
|
//
|
|
// Build a scaling identity matrix based on our scale factor
|
|
//
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine(0,0) = scale_factor;
|
|
tempAffine(1,1) = scale_factor;
|
|
tempAffine(2,2) = scale_factor;
|
|
//
|
|
// Put the scale matrix into the DCS and std::flush it.
|
|
//
|
|
localToWorld = tempAffine;
|
|
// tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// DPL_FLUSH_DCS (myDCS);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!visible)
|
|
{
|
|
graphicalObject = NULL;
|
|
} else
|
|
{
|
|
graphicalObject = myTranslocateSphere;
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&localToWorld.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
VideoRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for POVStartEndRenderable This handles the effect we use when
|
|
// the mission begins and ends (different from death)
|
|
//
|
|
POVStartEndRenderable::POVStartEndRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
bool isDeathZone, // DPL zone the world is in
|
|
dpl_ZONE *death_zone, // DPL zone the player's VTV and death effect are in
|
|
dpl_VIEW *this_view, // The view containing our eye
|
|
StateIndicator *effect_trigger, // State dial we use to control the translocation
|
|
float red_fog, // Fog color
|
|
float green_fog,
|
|
float blue_fog,
|
|
float near_fog, // The near fog plane
|
|
float far_fog, // The far fog plane
|
|
unsigned start_mission_state, // State that signals start of mission
|
|
unsigned end_mission_state // State that signals end of mission
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
#define FLASH_TIME (0.1f) // Time the screen will stay stark white
|
|
#define FADE_IN_TIME (1.0f) // Time to fade from white to the world
|
|
#define FADE_OUT_TIME (0.5f) // Time to fade to black at the end of the game
|
|
// HACK HACK HACK this should be removed once red planet is checked out
|
|
if(execution_type != Watcher)
|
|
std::cout<<"POVStartEndRenderable wants to be a watcher and isn't!\n";
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check_Pointer(this_zone);
|
|
Check_Pointer(death_zone);
|
|
Check_Pointer(this_view);
|
|
Check(effect_trigger);
|
|
//
|
|
// Remember the entity and DCS this renderable is attached to
|
|
//
|
|
// myZone = this_zone;
|
|
myDeathZone = death_zone;
|
|
myEffectTrigger = effect_trigger;
|
|
myView = this_view;
|
|
myState = WaitForStartState;
|
|
myFogRed = red_fog;
|
|
myFogGreen = green_fog;
|
|
myFogBlue = blue_fog;
|
|
myFogNear = near_fog;
|
|
myFogFar = far_fog;
|
|
myStartMissionState = start_mission_state;
|
|
myEndMissionState = end_mission_state;
|
|
myRenderer->SetFogStyle(DPLRenderer::noUpdateFogSetting);
|
|
|
|
l4_application->GetVideoRenderer()->AddRenderable(this);
|
|
//
|
|
// Connect us to the state dial's watcher hook
|
|
//
|
|
myEffectTrigger->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for POVStartEndRenderable
|
|
//
|
|
POVStartEndRenderable::~POVStartEndRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the POVStartEndRenderable
|
|
//
|
|
Logical
|
|
POVStartEndRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
|
|
Check_Pointer(myZone);
|
|
Check_Pointer(myDeathZone);
|
|
Check(myEffectTrigger);
|
|
Verify(myState >= WaitForStartState && myState <= FadeOutState);
|
|
Verify(myFogRed >= 0.0f && myFogRed <= 1.0f);
|
|
Verify(myFogGreen >= 0.0f && myFogGreen <= 1.0f);
|
|
Verify(myFogBlue >= 0.0f && myFogBlue <= 1.0f);
|
|
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for POVStartEndRenderable.
|
|
//
|
|
void
|
|
POVStartEndRenderable::Execute()
|
|
{
|
|
Scalar
|
|
current_time,
|
|
percent_time_left,
|
|
percent_time_used;
|
|
unsigned
|
|
current_trigger_state;
|
|
//
|
|
// Get the current state and the current time for later use
|
|
//
|
|
Check(myEffectTrigger);
|
|
current_trigger_state = myEffectTrigger->GetState();
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
//
|
|
// State engine (running off myState) to manage running of the death effect
|
|
//
|
|
//std::cout<<"POVStartEndRenderable::Executing\n";
|
|
switch(myState)
|
|
{
|
|
//
|
|
// WaitForStartState waits for the state that signals the start of the mission
|
|
// then sends the screen to full white by manipulating the fog color and limits.
|
|
//
|
|
case WaitForStartState:
|
|
{
|
|
myRenderer->SetFogStyle(DPLRenderer::noUpdateFogSetting);
|
|
if(current_trigger_state == myStartMissionState)
|
|
{
|
|
myState = FlashScreenState;
|
|
myStateTimer = current_time + FLASH_TIME;
|
|
float fogNear = 0.01f;
|
|
float fogFar = 0.05f;
|
|
float fogRed = 1.0f;
|
|
float fogGreen = 1.0f;
|
|
float fogBlue = 1.0f;
|
|
myRenderer->SetCurrentFogLimits(fogNear, fogFar);
|
|
myRenderer->GetDevice()->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_XRGB((int)(255 * fogRed), (int)(255 * fogGreen), (int)(255 * fogBlue)));
|
|
// dpl_SetViewFog(
|
|
// myView,
|
|
// dpl_fog_type_pixel_lin,
|
|
// 1.0,
|
|
// 1.0,
|
|
// 1.0,
|
|
// 0.01,
|
|
// 0.05 );
|
|
// dpl_FlushView(myView);
|
|
myRenderer->AddDynamicRenderable(this);
|
|
// std::cout<<"POVStartEndRenderable::Going Dynamic\n";
|
|
}
|
|
break;
|
|
}
|
|
//
|
|
// FlashScreenState is a state we park in for a short time so the screen will
|
|
// stay white for more than one frame.
|
|
//
|
|
case FlashScreenState:
|
|
{
|
|
if(myStateTimer <= current_time)
|
|
{
|
|
myStateTimer = current_time + FADE_IN_TIME;
|
|
myState = FadeInState;
|
|
}
|
|
break;
|
|
}
|
|
//
|
|
// FadeInState fades the fog color down from white to what it's supposed to
|
|
// be, while sweeping the fog ranges out to their proper ranges.
|
|
//
|
|
case FadeInState:
|
|
{
|
|
percent_time_left = (myStateTimer - current_time)/FADE_IN_TIME;
|
|
if(percent_time_left <= 0.0f)
|
|
{
|
|
percent_time_left = 0.0f;
|
|
myState = MissionRunningState;
|
|
myRenderer->SetFogStyle(DPLRenderer::updateFogSetting);
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
// std::cout<<"POVStartEndRenderable::Going Static\n";
|
|
}
|
|
percent_time_used = 1.0f - percent_time_left;
|
|
myRenderer->GetCurrentFogSettings(
|
|
&myFogRed,
|
|
&myFogGreen,
|
|
&myFogBlue,
|
|
&myFogNear,
|
|
&myFogFar);
|
|
|
|
myFogRed += (1.0f - myFogRed) * percent_time_left;
|
|
myFogGreen += (1.0f - myFogGreen) * percent_time_left;
|
|
myFogBlue += (1.0f - myFogBlue) * percent_time_left;
|
|
myFogNear *= percent_time_used;
|
|
myFogFar *= percent_time_used;
|
|
|
|
myFogNear += 0.01f;
|
|
myFogFar += 0.05f;
|
|
|
|
myRenderer->SetCurrentFogLimits(myFogNear, myFogFar);
|
|
myRenderer->GetDevice()->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_XRGB((int)(255 * myFogRed), (int)(255 * myFogGreen), (int)(255 * myFogBlue)));
|
|
// dpl_SetViewFog(
|
|
// myView,
|
|
// dpl_fog_type_pixel_lin,
|
|
// myFogRed + ((1.0f - myFogRed) * percent_time_left),
|
|
// myFogGreen + ((1.0f - myFogGreen) * percent_time_left),
|
|
// myFogBlue + ((1.0f - myFogBlue) * percent_time_left),
|
|
// (myFogNear * percent_time_used) + 0.01f,
|
|
// (myFogFar * percent_time_used) + 0.05f);
|
|
// dpl_FlushView(myView);
|
|
break;
|
|
}
|
|
//
|
|
// MissionRunningState is where we park while the mission is going on, waiting
|
|
// for the state that signals the end of the game
|
|
//
|
|
case MissionRunningState:
|
|
{
|
|
if(current_trigger_state == myEndMissionState)
|
|
{
|
|
myState = FadeOutState;
|
|
myStateTimer = current_time + FADE_OUT_TIME;
|
|
myRenderer->SetFogStyle(DPLRenderer::noUpdateFogSetting);
|
|
myRenderer->AddDynamicRenderable(this);
|
|
// std::cout<<"POVStartEndRenderable::Going Dynamic\n";
|
|
} else
|
|
{
|
|
myRenderer->GetCurrentFogSettings(
|
|
&myFogRed,
|
|
&myFogGreen,
|
|
&myFogBlue,
|
|
&myFogNear,
|
|
&myFogFar);
|
|
myRenderer->SetCurrentFogLimits(myFogNear, myFogFar);
|
|
}
|
|
break;
|
|
}
|
|
//
|
|
// FadeOutState handles doing a fade-to-black at the end of the game
|
|
//
|
|
case FadeOutState:
|
|
{
|
|
percent_time_left = (myStateTimer - current_time)/FADE_OUT_TIME;
|
|
if(percent_time_left <= 0.0f)
|
|
{
|
|
myState = WaitForStartState;
|
|
percent_time_left = 0.0f;
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
// std::cout<<"POVStartEndRenderable::Going Static\n";
|
|
}
|
|
myRenderer->GetCurrentFogSettings(
|
|
&myFogRed,
|
|
&myFogGreen,
|
|
&myFogBlue,
|
|
&myFogNear,
|
|
&myFogFar);
|
|
|
|
myFogRed *= percent_time_left;
|
|
myFogGreen *= percent_time_left;
|
|
myFogBlue *= percent_time_left;
|
|
myFogNear *= percent_time_left;
|
|
myFogFar *= percent_time_left;
|
|
|
|
myFogNear += 0.01f;
|
|
myFogFar += 0.05f;
|
|
|
|
myRenderer->SetCurrentFogLimits(myFogNear, myFogFar);
|
|
myRenderer->GetDevice()->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_XRGB((int)(255 * myFogRed), (int)(255 * myFogGreen), (int)(255 * myFogBlue)));
|
|
|
|
// dpl_SetViewFog(
|
|
// myView,
|
|
// dpl_fog_type_pixel_lin,
|
|
// myFogRed * percent_time_left,
|
|
// myFogGreen * percent_time_left,
|
|
// myFogBlue * percent_time_left,
|
|
// (myFogNear * percent_time_left) + 0.01f,
|
|
// (myFogFar * percent_time_left) + 0.05f);
|
|
// dpl_FlushView(myView);
|
|
break;
|
|
}
|
|
}
|
|
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the ReticleRenderable
|
|
// This produces a movable crosshair reticle that can be either static or
|
|
// dynamic. If static, it will position the graphic at wherever the reticle
|
|
// points when we construct this.
|
|
//
|
|
ReticleRenderable::ReticleRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Reticle **my_reticle, // points to renderable reticle pointer that points to entity's reticle
|
|
dpl_VIEW *this_view // the view associated with our eye
|
|
):
|
|
VideoRenderable(entity, execution_type),
|
|
mVB(NULL)
|
|
{
|
|
//
|
|
// Remember the entity that this renderable is attached to
|
|
//
|
|
rendererReticle = my_reticle;
|
|
myReticle = *my_reticle;
|
|
myOldReticlePosition = myReticle->reticlePosition;
|
|
|
|
LPDIRECT3DDEVICE9 device = myRenderer->GetDevice();
|
|
|
|
device->CreateVertexBuffer(sizeof(L4VERTEX_2D) * 8, D3DUSAGE_WRITEONLY, L4VERTEX_2D_FVF, D3DPOOL_MANAGED, &mVB, NULL);
|
|
|
|
L4VERTEX_2D *verts;
|
|
mVB->Lock(0, 0, (void**)&verts, 0);
|
|
|
|
DWORD color = D3DCOLOR_XRGB(0, 128, 0);
|
|
float segmentLen = 5.0f / 192.0f;
|
|
float spread = 5.0f / 256.0f;
|
|
float width = myRenderer->GetWidth();
|
|
float height = myRenderer->GetHeight();
|
|
float centerX = width / 2.0f;
|
|
float centerY = height / 2.0f;
|
|
|
|
// top segment
|
|
verts[0].x = centerX;
|
|
verts[0].y = centerY - (spread + segmentLen) * height;
|
|
verts[0].z = 0.0f;
|
|
verts[0].rhw = 1.0f;
|
|
verts[0].color = color;
|
|
|
|
verts[1].x = centerX;
|
|
verts[1].y = centerY - spread * height;
|
|
verts[1].z = 0.0f;
|
|
verts[1].rhw = 1.0f;
|
|
verts[1].color = color;
|
|
|
|
// right segment
|
|
verts[2].x = centerX + (spread + segmentLen) * height;
|
|
verts[2].y = centerY;
|
|
verts[2].z = 0.0f;
|
|
verts[2].rhw = 1.0f;
|
|
verts[2].color = color;
|
|
|
|
verts[3].x = centerX + spread * height;
|
|
verts[3].y = centerY;
|
|
verts[3].z = 0.0f;
|
|
verts[3].rhw = 1.0f;
|
|
verts[3].color = color;
|
|
|
|
// bottom segment
|
|
verts[4].x = centerX;
|
|
verts[4].y = centerY + (spread + segmentLen) * height;
|
|
verts[4].z = 0.0f;
|
|
verts[4].rhw = 1.0f;
|
|
verts[4].color = color;
|
|
|
|
verts[5].x = centerX;
|
|
verts[5].y = centerY + spread * height;
|
|
verts[5].z = 0.0f;
|
|
verts[5].rhw = 1.0f;
|
|
verts[5].color = color;
|
|
|
|
// left segment
|
|
verts[6].x = centerX - (spread + segmentLen) * height;
|
|
verts[6].y = centerY;
|
|
verts[6].z = 0.0f;
|
|
verts[6].rhw = 1.0f;
|
|
verts[6].color = color;
|
|
|
|
verts[7].x = centerX - spread * height;
|
|
verts[7].y = centerY;
|
|
verts[7].z = 0.0f;
|
|
verts[7].rhw = 1.0f;
|
|
verts[7].color = color;
|
|
|
|
mVB->Unlock();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the ReticleRenderable
|
|
//
|
|
ReticleRenderable::~ReticleRenderable()
|
|
{
|
|
if (mVB)
|
|
{
|
|
mVB->Release();
|
|
mVB = NULL;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLDrawReticleRenderable
|
|
// Not much to check here, the entity and DCS pointers must be valid while
|
|
// the instance is allowed to be NULL
|
|
//
|
|
Logical ReticleRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myReticle);
|
|
Check_Pointer(rendererReticle);
|
|
Check_Pointer(myView);
|
|
return True;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ReticleRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void ReticleRenderable::Execute()
|
|
{
|
|
//
|
|
// See if the reticle has moved
|
|
//
|
|
if(myOldReticlePosition != myReticle->reticlePosition)
|
|
{
|
|
myOldReticlePosition = myReticle->reticlePosition;
|
|
//
|
|
// Re-create the display list that positions the reticle
|
|
//
|
|
// dpl2d_OpenDisplayList(
|
|
// myPositionDisplayList,
|
|
// dpl2d_open_mode_clear);
|
|
// dpl2d_IdMatrix(my_2d_matrix);
|
|
// dpl2d_TranslateMatrix(
|
|
// my_2d_matrix,
|
|
// myOldReticlePosition.x,
|
|
// myOldReticlePosition.y );
|
|
// dpl2d_AddSetMatrix(
|
|
// myPositionDisplayList,
|
|
// my_2d_matrix );
|
|
// dpl2d_CloseDisplayList(myPositionDisplayList);
|
|
// dpl2d_FlushDisplayList(myPositionDisplayList);
|
|
}
|
|
|
|
// we've done everything that needs to be done, no need to call parent
|
|
}
|
|
|
|
void ReticleRenderable::Render(int pass, const D3DXMATRIX *viewTransform)
|
|
{
|
|
if (myReticle->reticleState == Reticle::ReticleState::ReticleOn)
|
|
{
|
|
LPDIRECT3DDEVICE9 device = myRenderer->GetDevice();
|
|
|
|
device->SetTexture(0, NULL);
|
|
device->SetStreamSource(0, mVB, 0, sizeof(L4VERTEX_2D));
|
|
device->DrawPrimitive(D3DPT_LINELIST, 0, 4);
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the CameraShipHUDRenderable
|
|
//
|
|
CameraShipHUDRenderable::CameraShipHUDRenderable(Entity *entity, ExecutionType execution_type, int *player_index, Logical *display_ranking_window)
|
|
: VideoRenderable(entity, execution_type)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
|
|
//
|
|
// Remember the entity that this renderable is attached to
|
|
//
|
|
LPDIRECT3DDEVICE9 device = myRenderer->GetDevice();
|
|
|
|
device->CreateVertexBuffer(sizeof(L4VERTEX_2D_TEX) * 4, D3DUSAGE_WRITEONLY, L4VERTEX_2D_TEX_FVF, D3DPOOL_MANAGED, &mVB, NULL);
|
|
|
|
L4VERTEX_2D_TEX *verts;
|
|
mVB->Lock(0, 0, (void**)&verts, 0);
|
|
memset(verts, 0, sizeof(L4VERTEX_2D_TEX) * 4);
|
|
|
|
DWORD color = D3DCOLOR_XRGB(0, 128, 0);
|
|
float width = myRenderer->GetWidth();
|
|
float height = myRenderer->GetHeight();
|
|
float centerX = width / 2.0f;
|
|
float centerY = height / 2.0f;
|
|
float nameWidth = (width * 0.32f) / 2.0f;
|
|
float nameHeight = height * 0.10f;
|
|
|
|
// top right
|
|
verts[0].x = centerX + nameWidth;
|
|
verts[0].y = height - (nameHeight * 2.0f);
|
|
verts[0].u = 1.0f;
|
|
verts[0].v = 0.0f;
|
|
verts[0].rhw = 1.0f;
|
|
verts[0].color = color;
|
|
|
|
// top left
|
|
verts[1].x = centerX - nameWidth;
|
|
verts[1].y = height - (nameHeight * 2.0f);
|
|
verts[1].u = 0.0f;
|
|
verts[1].v = 0.0f;
|
|
verts[1].rhw = 1.0f;
|
|
verts[1].color = color;
|
|
|
|
// bottom right
|
|
verts[2].x = centerX + nameWidth;
|
|
verts[2].y = height - nameHeight;
|
|
verts[2].u = 1.0f;
|
|
verts[2].v = 1.0f;
|
|
verts[2].rhw = 1.0f;
|
|
verts[2].color = color;
|
|
|
|
// bottom left
|
|
verts[3].x = centerX - nameWidth;
|
|
verts[3].y = height - nameHeight;
|
|
verts[3].u = 0.0f;
|
|
verts[3].v = 1.0f;
|
|
verts[3].rhw = 1.0f;
|
|
verts[3].color = color;
|
|
|
|
mVB->Unlock();
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Read in PlayerName Geometry
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//playerNameObject[0] = dpl_LoadObject("PNAME1.bgf", dpl_load_normal);
|
|
//playerNameObject[1] = dpl_LoadObject("PNAME2.bgf", dpl_load_normal);
|
|
//playerNameObject[2] = dpl_LoadObject("PNAME3.bgf", dpl_load_normal);
|
|
//playerNameObject[3] = dpl_LoadObject("PNAME4.bgf", dpl_load_normal);
|
|
//playerNameObject[4] = dpl_LoadObject("PNAME5.bgf", dpl_load_normal);
|
|
//playerNameObject[5] = dpl_LoadObject("PNAME6.bgf", dpl_load_normal);
|
|
//playerNameObject[6] = dpl_LoadObject("PNAME7.bgf", dpl_load_normal);
|
|
//playerNameObject[7] = dpl_LoadObject("PNAME8.bgf", dpl_load_normal);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Read in Ordinal Rankings Geometry
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//ordinalObject[0] = dpl_LoadObject("PLACE1.bgf", dpl_load_normal);
|
|
//ordinalObject[1] = dpl_LoadObject("PLACE2.bgf", dpl_load_normal);
|
|
//ordinalObject[2] = dpl_LoadObject("PLACE3.bgf", dpl_load_normal);
|
|
//ordinalObject[3] = dpl_LoadObject("PLACE4.bgf", dpl_load_normal);
|
|
//ordinalObject[4] = dpl_LoadObject("PLACE5.bgf", dpl_load_normal);
|
|
//ordinalObject[5] = dpl_LoadObject("PLACE6.bgf", dpl_load_normal);
|
|
//ordinalObject[6] = dpl_LoadObject("PLACE7.bgf", dpl_load_normal);
|
|
//ordinalObject[7] = dpl_LoadObject("PLACE8.bgf", dpl_load_normal);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Initialize CameraFollowing
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
followedPlayerIndex = player_index;
|
|
oldFollowedPlayerIndex = -1;
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create One DCS for a Camera Following Name Bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//followedNameDCS = dpl_NewDCS();
|
|
//followedNameInstance = dpl_NewInstance();
|
|
//dpl_ScaleDCS ( followedNameDCS, 0.20f, 0.20f, 1.0f );
|
|
//dpl_TranslateDCS ( followedNameDCS, 0.0f, -0.15f, -0.5f );
|
|
//dpl_SetDCSIgnoreGeo ( followedNameDCS, 1 );
|
|
//dpl_SetDCSTraversal ( followedNameDCS, 0x7 );
|
|
//dpl_AddDCSToScene ( followedNameDCS );
|
|
//dpl_SetInstanceObject ( followedNameInstance, playerNameObject[0] );
|
|
//dpl_AddInstanceToDCS ( followedNameDCS, followedNameInstance );
|
|
//dpl_SetInstanceVisibility ( followedNameInstance, 1 );
|
|
//dpl_FlushInstance ( followedNameInstance );
|
|
//dpl_FlushDCS ( followedNameDCS );
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create One DCS for Camera Following Ordinal Ranking Bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//followedOrdinalDCS = dpl_NewDCS();
|
|
//followedOrdinalInstance = dpl_NewInstance();
|
|
//dpl_AddDCSToDCS ( followedNameDCS, followedOrdinalDCS );
|
|
//dpl_SetInstanceObject ( followedOrdinalInstance, ordinalObject[0] );
|
|
//dpl_AddInstanceToDCS ( followedOrdinalDCS, followedOrdinalInstance );
|
|
//dpl_SetDCSIgnoreGeo ( followedOrdinalDCS, 1 );
|
|
//dpl_SetDCSTraversal ( followedOrdinalDCS, 0x7 );
|
|
//dpl_TranslateDCS ( followedOrdinalDCS, -0.75f, 0.0f, 0.0f );
|
|
//dpl_SetInstanceVisibility ( followedOrdinalInstance, 0 );
|
|
//dpl_FlushInstance ( followedOrdinalInstance );
|
|
//dpl_FlushDCS ( followedOrdinalDCS );
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create the Ranking Window
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
displayRankingWindow = display_ranking_window;
|
|
oldDisplayRankingWindow = False;
|
|
|
|
Scalar rank_window_y;
|
|
rank_window_y = 0.16f;
|
|
|
|
//rankingWindowDCS = dpl_NewDCS();
|
|
//dpl_ScaleDCS ( rankingWindowDCS, 0.12f, 0.12f, 1.0f );
|
|
//dpl_TranslateDCS ( rankingWindowDCS, 0.22f, rank_window_y, -0.5f );
|
|
//dpl_SetDCSIgnoreGeo ( rankingWindowDCS, 1 );
|
|
//dpl_SetDCSTraversal ( rankingWindowDCS, 0x7 );
|
|
//dpl_AddDCSToScene ( rankingWindowDCS );
|
|
//dpl_FlushDCS ( rankingWindowDCS );
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Initialize the pointer's to the player Ranks
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
playerRank = NULL;
|
|
oldPlayerRank = NULL;
|
|
nameDCS = NULL;
|
|
rankDCS = NULL;
|
|
nameInstance = NULL;
|
|
rankInstance = NULL;
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// See How Many Regular Players and CameraShip Players!
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
playerCount = 0;
|
|
Check(application);
|
|
EntityManager *entity_mgr = application->GetEntityManager();
|
|
Check(entity_mgr);
|
|
EntityGroup *player_group = entity_mgr->FindGroup("Players");
|
|
if (player_group)
|
|
{
|
|
Check(player_group);
|
|
ChainIteratorOf<Node*> player_iterator(player_group->groupMembers);
|
|
playerCount = player_iterator.GetSize();
|
|
}
|
|
|
|
EntityGroup *camera_player_group = entity_mgr->FindGroup("CameraPlayers");
|
|
int camera_player_count=0;
|
|
if (camera_player_group)
|
|
{
|
|
Check(player_group);
|
|
ChainIteratorOf<Node*> camera_iterator(camera_player_group->groupMembers);
|
|
camera_player_count = camera_iterator.GetSize();
|
|
}
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make the Arrays for Ranking the size of regular and cameras players
|
|
// summed up. This is necessary since GameMachineHost type of Camera
|
|
// Ships also have a bitmapIndex!
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
if (playerCount)
|
|
{
|
|
camera_player_count += playerCount;
|
|
Verify(camera_player_count <= MAX_PLAYER_NAMES);
|
|
playerRank = new (int (*[camera_player_count]));
|
|
Register_Pointer(playerRank);
|
|
Player *active_player;
|
|
if(player_group)
|
|
{
|
|
Check(player_group);
|
|
ChainIteratorOf<Node*> player_iterator(player_group->groupMembers);
|
|
while ((active_player = (Player*) player_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// PlayerRank Array indexed by bitmapIndex
|
|
// holds that player's ranking
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(active_player);
|
|
Verify(
|
|
active_player->playerBitmapIndex > 0
|
|
&& active_player->playerBitmapIndex <= MAX_PLAYER_NAMES
|
|
);
|
|
playerRank[active_player->playerBitmapIndex - 1] =
|
|
&active_player->playerRanking ;
|
|
}
|
|
}
|
|
if (camera_player_group)
|
|
{
|
|
ChainIteratorOf<Node*> camera_iterator(camera_player_group->groupMembers);
|
|
while ((active_player = (Player*) camera_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// PlayerRank Array indexed by bitmapIndex
|
|
// holds that player's ranking
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(active_player);
|
|
Verify(
|
|
active_player->playerBitmapIndex > 0
|
|
&& active_player->playerBitmapIndex <= MAX_PLAYER_NAMES
|
|
);
|
|
playerRank[active_player->playerBitmapIndex - 1] =
|
|
&active_player->playerRanking ;
|
|
}
|
|
}
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Initialize OldPlayerRank
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
oldPlayerRank = new int[camera_player_count];
|
|
Register_Pointer(oldPlayerRank);
|
|
|
|
int ii;
|
|
for(ii=0; ii<camera_player_count; ++ii)
|
|
{
|
|
oldPlayerRank[ii] = -1;
|
|
}
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Only Create Name and Rank DCS's for Regular players
|
|
// CameraShip Players do not have a score and thus are not
|
|
// displayed
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Allocate memory for all the DCS's
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//nameDCS = new (dpl_DCS (*[playerCount]));
|
|
//Register_Pointer(nameDCS);
|
|
//rankDCS = new (dpl_DCS (*[playerCount]));
|
|
//Register_Pointer(rankDCS);
|
|
//nameInstance = new (dpl_INSTANCE (*[playerCount]));
|
|
//Register_Pointer(nameInstance);
|
|
//rankInstance = new (dpl_INSTANCE (*[playerCount]));
|
|
//Register_Pointer(rankInstance);
|
|
|
|
Scalar delta_y;
|
|
|
|
for( ii = 0; ii < playerCount ; ++ii)
|
|
{
|
|
delta_y = -(ii * 0.24);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create one DCS for a Name Bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//nameDCS[ii] = dpl_NewDCS();
|
|
//nameInstance[ii] = dpl_NewInstance();
|
|
//dpl_AddDCSToDCS ( rankingWindowDCS, nameDCS[ii] );
|
|
//dpl_SetInstanceObject ( nameInstance[ii], playerNameObject[ii] );
|
|
//dpl_SetDCSIgnoreGeo ( nameDCS[ii], 1 );
|
|
//dpl_SetDCSTraversal ( nameDCS[ii], 0x7 );
|
|
//dpl_TranslateDCS ( nameDCS[ii], 0.0f, delta_y, 0.0f );
|
|
//dpl_AddInstanceToDCS ( nameDCS[ii], nameInstance[ii] );
|
|
//dpl_SetInstanceVisibility ( nameInstance[ii], 0 );
|
|
//dpl_FlushInstance ( nameInstance[ii] );
|
|
//dpl_FlushDCS ( nameDCS[ii] );
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create One DCS for Ordinal Ranking Bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//rankDCS[ii] = dpl_NewDCS();
|
|
//rankInstance[ii] = dpl_NewInstance();
|
|
//dpl_AddDCSToDCS ( nameDCS[ii], rankDCS[ii] );
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Ordinal Object will remain Static on the Ranking Window
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//dpl_SetInstanceObject ( rankInstance[ii], ordinalObject[ii] );
|
|
//dpl_AddInstanceToDCS ( rankDCS[ii], rankInstance[ii] );
|
|
//dpl_SetDCSIgnoreGeo ( rankDCS[ii], 1 );
|
|
//dpl_SetDCSTraversal ( rankDCS[ii], 0x7 );
|
|
//dpl_TranslateDCS ( rankDCS[ii], -0.75f, 0.0f, 0.0f );
|
|
//dpl_SetInstanceVisibility ( rankInstance[ii], 0 );
|
|
//dpl_FlushInstance ( rankInstance[ii] );
|
|
//dpl_FlushDCS ( rankDCS[ii] );
|
|
}
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the CameraShipHUDRenderable
|
|
//
|
|
CameraShipHUDRenderable::~CameraShipHUDRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Check(this);
|
|
|
|
//dpl_RemoveInstanceFromDCS(followedNameDCS, followedNameInstance);
|
|
//dpl_RemoveDCSFromScene(followedNameDCS);
|
|
//dpl_DeleteInstance(followedNameInstance);
|
|
//dpl_DeleteDCS(followedNameDCS);
|
|
|
|
//dpl_RemoveInstanceFromDCS(followedOrdinalDCS, followedOrdinalInstance);
|
|
//dpl_RemoveDCSFromScene(followedOrdinalDCS);
|
|
//dpl_DeleteInstance(followedOrdinalInstance);
|
|
//dpl_DeleteDCS(followedOrdinalDCS);
|
|
////
|
|
////~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//// Delete the Ranking Window
|
|
////~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
////
|
|
//Check(application);
|
|
//for(int ii=0;ii<playerCount;++ii)
|
|
//{
|
|
// dpl_RemoveInstanceFromDCS(rankDCS[ii], rankInstance[ii]);
|
|
// dpl_RemoveDCSFromDCS(nameDCS[ii], rankDCS[ii]);
|
|
// dpl_DeleteInstance(rankInstance[ii]);
|
|
// dpl_DeleteDCS(rankDCS[ii]);
|
|
|
|
// dpl_RemoveInstanceFromDCS(nameDCS[ii], nameInstance[ii]);
|
|
// dpl_RemoveDCSFromDCS(rankingWindowDCS,nameDCS[ii]);
|
|
// dpl_DeleteInstance(nameInstance[ii]);
|
|
// dpl_DeleteDCS(nameDCS[ii]);
|
|
//}
|
|
//if (rankDCS)
|
|
//{
|
|
// Unregister_Pointer(rankDCS);
|
|
// delete[] rankDCS;
|
|
//}
|
|
//if (nameDCS)
|
|
//{
|
|
// Unregister_Pointer(nameDCS);
|
|
// delete[] nameDCS;
|
|
//}
|
|
//if(rankInstance)
|
|
//{
|
|
// Unregister_Pointer(rankInstance);
|
|
// delete[] rankInstance;
|
|
//}
|
|
//if (nameInstance)
|
|
//{
|
|
// Unregister_Pointer(nameInstance);
|
|
// delete[] nameInstance;
|
|
//}
|
|
//if (rankingWindowDCS)
|
|
//{
|
|
// dpl_RemoveDCSFromScene(rankingWindowDCS);
|
|
// dpl_DeleteDCS(rankingWindowDCS);
|
|
//}
|
|
//if (oldPlayerRank)
|
|
//{
|
|
// Unregister_Pointer(oldPlayerRank);
|
|
// delete[] oldPlayerRank;
|
|
//}
|
|
//if (playerRank)
|
|
//{
|
|
// Unregister_Pointer(playerRank);
|
|
// delete[] playerRank;
|
|
//}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the CameraShipHUDRenderable
|
|
//
|
|
void CameraShipHUDRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
|
|
if (!playerCount || *followedPlayerIndex <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Update the Followed Player NameBitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
if (oldFollowedPlayerIndex != *followedPlayerIndex - 1)
|
|
{
|
|
oldFollowedPlayerIndex = *followedPlayerIndex - 1;
|
|
|
|
if (oldFollowedPlayerIndex < 8)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Change the bitmap shown
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//dpl_SetInstanceObject (
|
|
// followedNameInstance,
|
|
// playerNameObject[oldFollowedPlayerIndex]
|
|
//);
|
|
//dpl_FlushInstance ( followedNameInstance );
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Change the bitmap shown
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//dpl_SetInstanceObject (
|
|
// followedOrdinalInstance,
|
|
// ordinalObject[*playerRank[oldFollowedPlayerIndex]]
|
|
//);
|
|
//dpl_FlushInstance ( followedOrdinalInstance );
|
|
}
|
|
}
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Update the Rankings for All Players
|
|
// whenever they change!
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
for(int ii=0; ii<playerCount; ++ii)
|
|
{
|
|
if (oldPlayerRank[ii] != (*playerRank[ii]))
|
|
{
|
|
oldPlayerRank[ii] = *playerRank[ii];
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Name instance corresponds to rank
|
|
// playerNameobject corresponds to playerBitmapIndex
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//dpl_SetInstanceObject(
|
|
// nameInstance[oldPlayerRank[ii]],
|
|
// playerNameObject[ii]
|
|
//);
|
|
//dpl_FlushInstance ( nameInstance[oldPlayerRank[ii]] );
|
|
}
|
|
}
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Toggle Ranking Window Visibility
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
if (oldDisplayRankingWindow != *displayRankingWindow)
|
|
{
|
|
oldDisplayRankingWindow = *displayRankingWindow;
|
|
for(int ii=0; ii<playerCount; ++ii)
|
|
{
|
|
if (oldDisplayRankingWindow)
|
|
{
|
|
//dpl_SetInstanceVisibility ( nameInstance[ii], 1 );
|
|
//dpl_SetInstanceVisibility ( rankInstance[ii], 1 );
|
|
}
|
|
else
|
|
{
|
|
//dpl_SetInstanceVisibility ( nameInstance[ii], 0 );
|
|
//dpl_SetInstanceVisibility ( rankInstance[ii], 0 );
|
|
}
|
|
//dpl_FlushInstance ( nameInstance[ii] );
|
|
//dpl_FlushInstance ( rankInstance[ii] );
|
|
}
|
|
}
|
|
|
|
if (application->GetApplicationState() == Application::StoppingMission ||
|
|
application->GetApplicationState() == Application::EndingMission)
|
|
{
|
|
//dpl_SetInstanceVisibility ( followedOrdinalInstance, 0 );
|
|
//dpl_SetInstanceVisibility ( followedNameInstance, 0 );
|
|
//dpl_FlushInstance ( followedOrdinalInstance );
|
|
//dpl_FlushInstance ( followedNameInstance );
|
|
}
|
|
|
|
VideoRenderable::Execute();
|
|
}
|
|
|
|
void CameraShipHUDRenderable::Render(int pass, const D3DXMATRIX *viewTransform)
|
|
{
|
|
if (application->GetApplicationState() == Application::RunningMission && oldFollowedPlayerIndex >= 0 && oldFollowedPlayerIndex < MAX_PLAYER_NAMES)
|
|
{
|
|
LPDIRECT3DDEVICE9 device = myRenderer->GetDevice();
|
|
|
|
device->SetFVF(L4VERTEX_2D_TEX_FVF);
|
|
device->SetStreamSource(0, mVB, 0, sizeof(L4VERTEX_2D_TEX));
|
|
device->SetTexture(0, myRenderer->GetNameTexture(oldFollowedPlayerIndex));
|
|
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Logical
|
|
CameraShipHUDRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DCSMorphObjectRenderable
|
|
//
|
|
DCSMorphObjectRenderable::DCSMorphObjectRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_OBJECT *destination_object, // destination
|
|
dpl_OBJECT *start_object, // start object
|
|
dpl_OBJECT *end_object, // end object
|
|
Scalar *morph_control, // pointer to control variable
|
|
int32 morph_mode, // Defines type of morph to do
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask // intersection mask for the object
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check incoming data
|
|
////
|
|
//Check_Pointer(destination_object);
|
|
//Check_Pointer(start_object);
|
|
//Check_Pointer(end_object);
|
|
//Check_Pointer(morph_control);
|
|
//Check_Pointer(this_zone);
|
|
////
|
|
//// Remember my dpl object, intersect and offset data
|
|
////
|
|
//myDPLObject = destination_object;
|
|
//myStartObject = start_object;
|
|
//myEndObject = end_object;
|
|
//myMorphControl = morph_control;
|
|
//oldMorphControl = *myMorphControl;
|
|
//myMorphMode = morph_mode;
|
|
//myDPLZone = this_zone;
|
|
//myIntersectMode = intersect_mode;
|
|
//myIntersectMask = intersect_mask;
|
|
//myDCS = NULL;
|
|
//myInstance = NULL;
|
|
////
|
|
//// We need to construct a DCS node here and remember it. The next class up is
|
|
//// expected to handle the std::flushing and connecting of structure so we just setup
|
|
//// the DCS and zone information here, leaving std::flushing to someone else.
|
|
////
|
|
//myDCS = dpl_NewDCS ();
|
|
//Check_Pointer ( myDCS );
|
|
//dpl_SetDCSZone ( myDCS, myDPLZone );
|
|
////
|
|
//// Construct the instance(s) and hang them on the DCS. Since we may be building
|
|
//// more than one instance, we have to take care of std::flushing them here.
|
|
////
|
|
//myInstance = dpl_NewInstance();
|
|
//Check_Pointer ( myInstance);
|
|
//dpl_SetInstanceObject ( myInstance, myDPLObject);
|
|
//dpl_SetInstanceIntersect ( myInstance, myIntersectMode );
|
|
//dpl_SetInstanceSectMask ( myInstance, myIntersectMask );
|
|
//dpl_SetInstanceVisibility ( myInstance, 1 );
|
|
//dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
//dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Setup the morph and do the initial morph to get the destination object
|
|
////--------------------------------------------------------------------------
|
|
//// NOTE: dpl_MorphObject seems to have Start and End objects reversed
|
|
//// so they are reversed here as well...(two negatives make positive)
|
|
////--------------------------------------------------------------------------
|
|
//dpl_MorphObject(myDPLObject,myStartObject,myEndObject,oldMorphControl,myMorphMode);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DCSMorphObjectRenderable
|
|
//
|
|
DCSMorphObjectRenderable::~DCSMorphObjectRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Delete the instance(s) hanging on the DCS (if any)
|
|
//// NOTE: we may want to iterate through all the instances here using DPL routines
|
|
////
|
|
//dpl_RemoveInstanceFromDCS(myDCS, myInstance);
|
|
//dpl_DeleteInstance(myInstance);
|
|
////
|
|
//// Delete the DCS
|
|
////
|
|
//dpl_DeleteDCS(myDCS);
|
|
//myDCS = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DCSMorphObjectRenderable
|
|
//
|
|
Logical
|
|
DCSMorphObjectRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
VideoRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check_Pointer(myDPLObject);
|
|
Check_Pointer(myStartObject);
|
|
Check_Pointer(myEndObject);
|
|
Check_Pointer(myMorphControl);
|
|
Check_Pointer(myDPLZone);
|
|
Check_Pointer(myDCS);
|
|
Check_Pointer(myInstance);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DCSMorphObjectRenderable
|
|
// If the morph control variable has changed, we re-do the morph
|
|
//
|
|
void
|
|
DCSMorphObjectRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// See if the morph control varaible has changed
|
|
////
|
|
//if(oldMorphControl != *myMorphControl)
|
|
//{
|
|
// oldMorphControl = *myMorphControl;
|
|
// //--------------------------------------------------------------------------
|
|
// // NOTE: dpl_MorphObject seems to have Start and End objects reversed
|
|
// // so they are reversed here as well...(two negatives make positive)
|
|
// //--------------------------------------------------------------------------
|
|
|
|
// dpl_MorphObject(myDPLObject,myStartObject,myEndObject,oldMorphControl,myMorphMode);
|
|
//}
|
|
////
|
|
//// Call the next lower execute method
|
|
////
|
|
//#if DEBUG_LEVEL > 0
|
|
//VideoRenderable::Execute();
|
|
// #endif
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for RootMorphRenderable
|
|
//
|
|
RootMorphRenderable::RootMorphRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_OBJECT *destination_object, // destination
|
|
dpl_OBJECT *start_object, // start object
|
|
dpl_OBJECT *end_object, // end object
|
|
Scalar *morph_control, // pointer to control variable
|
|
int32 morph_mode, // Defines type of morph to do
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask // intersection mask for the object
|
|
):
|
|
DCSMorphObjectRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
destination_object, // destination
|
|
start_object, // start object
|
|
end_object, // end object
|
|
morph_control, // pointer to control variable
|
|
morph_mode, // Defines type of morph to do
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask) // intersection mask for the object
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// All the incoming data will have been checked by DCSObjectRenderable
|
|
//// already, so we don't have to check anything locally.
|
|
////
|
|
////
|
|
//// Initialize our variables
|
|
////
|
|
//oldLocalToWorld = myEntity->localToWorld;
|
|
////
|
|
//// Now we finish the work of hooking up and initializing the root renderable
|
|
//// Add the DCS to the scene and initialize it's matrix with the localToWorld
|
|
//// transformation from our entity
|
|
////
|
|
//dpl_AddDCSToScene ( myDCS );
|
|
//float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
//Check_Pointer ( tempMatrix );
|
|
//*(Matrix4x4*)tempMatrix = myEntity->localToWorld;
|
|
//dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for RootMorphRenderable
|
|
//
|
|
RootMorphRenderable::~RootMorphRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our structure before we do anything
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// Remove the DCS from the scene, deletion of the DCS and it's instances is
|
|
//// handled by our parent class.
|
|
////
|
|
//dpl_RemoveDCSFromScene(myDCS);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the RootMorphRenderable
|
|
//
|
|
Logical
|
|
RootMorphRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
DCSMorphObjectRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(&oldLocalToWorld);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the RootMorphRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
RootMorphRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// If our entity has changed it's localToWorld matrix, update DPL
|
|
////
|
|
//if(oldLocalToWorld != myEntity->localToWorld)
|
|
//{
|
|
// oldLocalToWorld = myEntity->localToWorld;
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer (tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = oldLocalToWorld;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
//}
|
|
////
|
|
//// Call the execute method in our parent
|
|
////
|
|
DCSMorphObjectRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ChildMorphRenderable
|
|
//
|
|
ChildMorphRenderable::ChildMorphRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_OBJECT *destination_object, // destination
|
|
dpl_OBJECT *start_object, // start object
|
|
dpl_OBJECT *end_object, // end object
|
|
Scalar *morph_control, // pointer to control variable
|
|
int32 morph_mode, // Defines type of morph to do
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
dpl_DCS *parent_DCS // the parent DCS we will be offsetting from
|
|
):
|
|
DCSMorphObjectRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
destination_object, // destination
|
|
start_object, // start object
|
|
end_object, // end object
|
|
morph_control, // pointer to control variable
|
|
morph_mode, // Defines type of morph to do
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask) // intersection mask for the object
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// All the incoming data will have been checked by DCSObjectRenderable
|
|
//// already, so we don't have to check anything locally.
|
|
////
|
|
//Check_Pointer(parent_DCS);
|
|
////
|
|
//// Now we finish the work of hooking up and initializing the root renderable
|
|
//// Add the DCS to the scene and initialize it's matrix with the localToWorld
|
|
//// transformation from our entity
|
|
////
|
|
//dpl_AddDCSToDCS ( parent_DCS, myDCS );
|
|
//dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ChildMorphRenderable
|
|
//
|
|
ChildMorphRenderable::~ChildMorphRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ChildMorphRenderable
|
|
//
|
|
Logical
|
|
ChildMorphRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
DCSMorphObjectRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ChildMorphRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
ChildMorphRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
DCSMorphObjectRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ScalingExplosionRenderable
|
|
//
|
|
ScalingExplosionRenderable::ScalingExplosionRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // This will be the scaling explosion object
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
Vector3D *control_vector, // Effect control velocity vector
|
|
Vector3D *accel_vector, // rate of change of control vector
|
|
Scalar gravity,
|
|
int *trigger // doesn't run till the trigger comes up
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//
|
|
// Check the incoming data
|
|
//
|
|
Check(control_vector);
|
|
#if DEBUG_LEVEL > 0
|
|
if(trigger)
|
|
Check_Pointer(trigger);
|
|
#endif
|
|
//
|
|
// Initialize our variables
|
|
//
|
|
myScalingVector.x = 0.01;
|
|
myScalingVector.y = 0.01;
|
|
myScalingVector.z = 0.01;
|
|
myVelocityVector = *control_vector;
|
|
myVelocityChange = *accel_vector;
|
|
myGravity = gravity;
|
|
myVelocity = 0.0f;
|
|
myTranslation.x = 0.0;
|
|
myTranslation.y = 0.0;
|
|
myTranslation.z = 0.0;
|
|
myTrigger = trigger;
|
|
//
|
|
// Initialize the matrix in this dcs
|
|
//
|
|
//float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
//Check_Pointer ( tempMatrix );
|
|
//AffineMatrix tempAffine(True);
|
|
//tempAffine *= myScalingVector;
|
|
//tempAffine *= myTranslation;
|
|
//*(Matrix4x4*)tempMatrix = tempAffine;
|
|
//dpl_FlushDCS ( myDCS );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ScalingExplosionRenderable
|
|
//
|
|
ScalingExplosionRenderable::~ScalingExplosionRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ScalingExplosionRenderable
|
|
//
|
|
Logical
|
|
ScalingExplosionRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
DCSObjectRenderable::TestInstance();
|
|
//
|
|
// Test our own variables
|
|
//
|
|
Check(&myScalingVector);
|
|
Check(&myVelocityVector);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ScalingExplosionRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
ScalingExplosionRenderable::Execute()
|
|
{
|
|
//
|
|
// Check our variables
|
|
//
|
|
Check(this);
|
|
if(!myTrigger || *myTrigger != 0)
|
|
{
|
|
//
|
|
// Apply the scaling factor to the object
|
|
//
|
|
myVelocityVector += myVelocityChange;
|
|
myScalingVector += myVelocityVector;
|
|
myVelocity += myGravity;
|
|
myTranslation.y += myVelocity;
|
|
//
|
|
// Initialize the matrix in this dcs
|
|
//
|
|
//float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
//Check_Pointer ( tempMatrix );
|
|
//AffineMatrix tempAffine(True);
|
|
//tempAffine *= myScalingVector;
|
|
//tempAffine *= myTranslation;
|
|
//*(Matrix4x4*)tempMatrix = tempAffine;
|
|
//DPL_FLUSH_DCS ( myDCS );
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
ChildOffsetRenderable::Execute();
|
|
}
|
|
}
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Micro Renderables
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
// From here to the row of === is pretty kludgy stuff to allow dave to prototype
|
|
// some explosion stuff.
|
|
// I expect to replace most of it within a week with the all-new micro
|
|
// renderable system.
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DependantRenderable
|
|
// This is a class of renderable that has other dependant renderables which it
|
|
// will execute on command. This is a base for this type of renderable and is
|
|
// not ment to be used by itself.
|
|
//
|
|
DependantRenderable::DependantRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type // How/when to execute the renderable
|
|
):
|
|
VideoRenderable(entity, execution_type),
|
|
dependantRenderableSocket(NULL)
|
|
{
|
|
// Check incoming data
|
|
// Initialize variables
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DependantRenderable
|
|
DependantRenderable::~DependantRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DependantRenderable
|
|
Logical
|
|
DependantRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
// Now do our checking
|
|
Check(&dependantRenderableSocket);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// AddDependantRenderable for the DependantRenderable
|
|
// This adds an existing renderable as a dependant on this renderable so it
|
|
// will be run when this renderable is executed.
|
|
void
|
|
DependantRenderable::AddDependantRenderable(Component *dependant)
|
|
{
|
|
Check(dependant);
|
|
dependantRenderableSocket.Add(dependant);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DependantRenderable
|
|
void
|
|
DependantRenderable::Execute()
|
|
{
|
|
Component
|
|
*dependant;
|
|
//
|
|
// Make an iterator for our components then execute them all
|
|
//
|
|
// std::cout<<"DependantRenderable::Execute()\n";
|
|
SChainIteratorOf<Component*> dependant_iterator(&dependantRenderableSocket);
|
|
while ((dependant = dependant_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
dependant->Execute();
|
|
// std::cout<<"dependant->Execute();\n";
|
|
}
|
|
|
|
// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ScalarTriggerRenderable
|
|
// Whenever "watched_value" changes by "watched_precision" the dependants of this
|
|
// renderable will be called.
|
|
//
|
|
ScalarTriggerRenderable::ScalarTriggerRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar *watched_value, // we run dependants when this changes
|
|
Scalar watched_precision // watched_value must change by this much
|
|
):
|
|
DependantRenderable(entity, execution_type)
|
|
{
|
|
//
|
|
// Check incoming data
|
|
//
|
|
Check_Pointer(watched_value);
|
|
//
|
|
// Initialize variables
|
|
//
|
|
myWatchedValue = watched_value;
|
|
myOldWatchedValue = *myWatchedValue;
|
|
myPrecision = watched_precision;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ScalarTriggerRenderable
|
|
ScalarTriggerRenderable::~ScalarTriggerRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ScalarTriggerRenderable
|
|
Logical
|
|
ScalarTriggerRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
DependantRenderable::TestInstance();
|
|
// Now do our checking
|
|
Check_Pointer(myWatchedValue);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ScalarTriggerRenderable
|
|
void
|
|
ScalarTriggerRenderable::Execute()
|
|
{
|
|
Check(this);
|
|
//
|
|
// If there hasn't been a significant enough change, return right now
|
|
//
|
|
if(Abs((*myWatchedValue - myOldWatchedValue)) < myPrecision)
|
|
return;
|
|
//
|
|
// Update my watcher data, then call my parent to execute the dependants
|
|
//
|
|
myOldWatchedValue = *myWatchedValue;
|
|
DependantRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for TimeCullRenderable
|
|
// This renderable will run all it's dependants at a set frequency based on
|
|
// a clock value supplied by the culling system.
|
|
//
|
|
TimeCullRenderable::TimeCullRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar delay_between_runs // Time delay between executions of dependants
|
|
):
|
|
DependantRenderable(entity, execution_type)
|
|
{
|
|
//
|
|
// Check incoming data
|
|
//
|
|
//
|
|
// Initialize the renderable, set clock so this will execute the first time
|
|
// it's called.
|
|
//
|
|
delayBetweenRuns = delay_between_runs;
|
|
nextRunTime = myRenderer->GetCurrentFrameTime();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for TimeCullRenderable
|
|
TimeCullRenderable::~TimeCullRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the TimeCullRenderable
|
|
Logical
|
|
TimeCullRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
DependantRenderable::TestInstance();
|
|
// Now do our checking
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the TimeCullRenderable
|
|
void
|
|
TimeCullRenderable::Execute()
|
|
{
|
|
Check(this);
|
|
//
|
|
// If it's time, call my parent to execute the dependants
|
|
//
|
|
if(nextRunTime <= myRenderer->GetCurrentFrameTime())
|
|
{
|
|
nextRunTime = myRenderer->GetCurrentFrameTime() + delayBetweenRuns;
|
|
DependantRenderable::Execute();
|
|
// std::cout<<"Time Cull ran dependants\n";
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MechCullRenderable::MechCullRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Logical always_run_all, // If true, disable culling and run everything
|
|
bool isDeathZone // Switch off this zone when the mech goes off screen
|
|
):
|
|
DependantRenderable(entity, execution_type),
|
|
legRenderableSocket(NULL)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
Check_Pointer(my_zone);
|
|
myAlwaysRunAll = always_run_all;
|
|
//myZone = my_zone;
|
|
myMechWasVisible = True;
|
|
myNextRootUpdate = myRenderer->GetCurrentFrameTime();
|
|
myNextLegUpdate = myRenderer->GetCurrentFrameTime();
|
|
myRootUpdateRate = 0.0;
|
|
myLegUpdateRate = 0.0;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for MechCullRenderable
|
|
MechCullRenderable::~MechCullRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// AddDependantLegRenderable for the MechCullRenderable
|
|
// This adds an existing renderable as a dependant of the leg chain.
|
|
void
|
|
MechCullRenderable::AddDependantLegRenderable(Component *dependant)
|
|
{
|
|
Check(dependant);
|
|
legRenderableSocket.Add(dependant);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the MechCullRenderable
|
|
Logical
|
|
MechCullRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
DependantRenderable::TestInstance();
|
|
// Now do our checking
|
|
Check_Pointer(myZone);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the MechCullRenderable
|
|
void
|
|
MechCullRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//#define CULL_VOLUME_SIZE 11.0 // Assume mech (or other object) fills 10 meter bubble
|
|
Scalar
|
|
current_time;
|
|
//Point3D
|
|
// target_point;
|
|
//Component
|
|
// *dependant;
|
|
|
|
//Check(this);
|
|
////
|
|
//// If we've been told to always run everything, do so. I don't flip the
|
|
//// profile bit here because I only want to time the actual cull algorithim.
|
|
////
|
|
//if(myAlwaysRunAll)
|
|
//{
|
|
// DependantRenderable::Execute();
|
|
// SChainIteratorOf<Component*> dependant_iterator(&legRenderableSocket);
|
|
// while ((dependant = dependant_iterator.ReadAndNext()) != NULL)
|
|
// {
|
|
// dependant->Execute();
|
|
// }
|
|
// myMechWasVisible = True;
|
|
// return;
|
|
//}
|
|
//SET_VIDEO_MECH_CULL_RENDERABLE();
|
|
////
|
|
//// Continue on to do the full culling process
|
|
////
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
////
|
|
//// Transform this entities position into eye space
|
|
////
|
|
//target_point = myEntity->localOrigin.linearPosition;
|
|
//target_point *= (*myRenderer->GetWorldToEyeMatrix());
|
|
//Check(this);
|
|
////
|
|
//// See if this is inside the viewing volume
|
|
//// HACK, viewing volume is hard coded here for now
|
|
//// negative z goes into the screen
|
|
////
|
|
//// See if it's behind me
|
|
////
|
|
//if((target_point.z - CULL_VOLUME_SIZE) >= 0.0f)
|
|
//{
|
|
// if(myMechWasVisible)
|
|
// {
|
|
// myMechWasVisible = False;
|
|
// dpl_SetZoneAllViewsOff (myZone);
|
|
// dpl_FlushZone (myZone);
|
|
// //
|
|
// // Set the root rate to slow and the leg rate to stopped
|
|
// //
|
|
// myRootUpdateRate = 1.0f;
|
|
// myLegUpdateRate = 60.0f;
|
|
// myNextRootUpdate = current_time + myRootUpdateRate;
|
|
// myNextLegUpdate = current_time + myLegUpdateRate;
|
|
// }
|
|
//}
|
|
//else
|
|
//{
|
|
// //
|
|
// // Fix up the Z so objects very close behind us (close enough they might
|
|
// // stick into our view) will be properly culled.
|
|
// //
|
|
// if(target_point.z >= 0)
|
|
// target_point.z = 0.1;
|
|
// else
|
|
// target_point.z = Abs(target_point.z);
|
|
// Check(this);
|
|
// //
|
|
// // See if the object's volume is to the left or right of the culling
|
|
// // volume.
|
|
// //
|
|
// if(((Abs(target_point.x)-CULL_VOLUME_SIZE)/target_point.z) > myRenderer->GetViewRatio())
|
|
// {
|
|
// //
|
|
// // If we were visible before, we're not any more
|
|
// //
|
|
// Check(this);
|
|
// if(myMechWasVisible)
|
|
// {
|
|
// myMechWasVisible = False;
|
|
// dpl_SetZoneAllViewsOff (myZone);
|
|
// dpl_FlushZone (myZone);
|
|
// //
|
|
// // Set the root rate to slow and the leg rate to stopped
|
|
// //
|
|
// myRootUpdateRate = 1.0f;
|
|
// myLegUpdateRate = 60.0f;
|
|
// myNextRootUpdate = current_time + myRootUpdateRate;
|
|
// myNextLegUpdate = current_time + myLegUpdateRate;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// // If we were invisible before, we're visible now
|
|
// //
|
|
// Check(this);
|
|
// if(!myMechWasVisible)
|
|
// {
|
|
// myMechWasVisible = True;
|
|
// dpl_SetZoneAllViewsOn (myZone);
|
|
// dpl_FlushZone (myZone);
|
|
// //
|
|
// // Set the various update rates appropriately and force an update
|
|
// //
|
|
// myRootUpdateRate = 0.0;
|
|
// myNextRootUpdate = current_time;
|
|
// myNextLegUpdate = current_time;
|
|
// }
|
|
// //
|
|
// // Set the leg update rate based on range (really should be a formulia)
|
|
// //
|
|
// if(target_point.z < 500.0f)
|
|
// myLegUpdateRate = 0.0;
|
|
// else
|
|
// myLegUpdateRate = 0.25;
|
|
// }
|
|
//}
|
|
////
|
|
//// Flip the trace bit here because I don't want to include the cost of the
|
|
//// dependant renderables.
|
|
////
|
|
//CLEAR_VIDEO_MECH_CULL_RENDERABLE();
|
|
////
|
|
//// Use the data already calculated to determine which of the dependant
|
|
//// renderable groups we should execute.
|
|
////
|
|
//if(myNextLegUpdate <= current_time)
|
|
//{
|
|
// myNextLegUpdate = current_time + myLegUpdateRate;
|
|
// //
|
|
// // Execute all the leg renderables
|
|
// //
|
|
// SChainIteratorOf<Component*> dependant_iterator(&legRenderableSocket);
|
|
// while ((dependant = dependant_iterator.ReadAndNext()) != NULL)
|
|
// {
|
|
// dependant->Execute();
|
|
// }
|
|
//}
|
|
if(myNextRootUpdate <= current_time)
|
|
{
|
|
myNextRootUpdate = current_time + myRootUpdateRate;
|
|
DependantRenderable::Execute();
|
|
}
|
|
return;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for InstanceSwitchRenderable
|
|
InstanceSwitchRenderable::InstanceSwitchRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_INSTANCE *this_instance, // the instance to control
|
|
Logical sense, // instance on when trigger is....
|
|
int *trigger // true if the instance is on, false if off
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// Check incoming data
|
|
//Check_Pointer(this_instance);
|
|
//Check_Pointer(trigger);
|
|
//// Initialize variables
|
|
//mySense = sense;
|
|
//myInstance = this_instance;
|
|
//myTriggerAttribute = trigger;
|
|
//oldTriggerAttribute = *myTriggerAttribute;
|
|
//if(mySense == oldTriggerAttribute)
|
|
//{
|
|
// dpl_SetInstanceVisibility ( myInstance, 1 );
|
|
//}
|
|
//else
|
|
//{
|
|
// dpl_SetInstanceVisibility ( myInstance, 0 );
|
|
//}
|
|
// dpl_FlushInstance ( myInstance );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for InstanceSwitchRenderable
|
|
InstanceSwitchRenderable::~InstanceSwitchRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the InstanceSwitchRenderable
|
|
Logical
|
|
InstanceSwitchRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myInstance);
|
|
Check_Pointer(myTriggerAttribute);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the InstanceSwitchRenderable
|
|
void
|
|
InstanceSwitchRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// Check our variables
|
|
//Check(this);
|
|
//if(*myTriggerAttribute != oldTriggerAttribute)
|
|
//{
|
|
// oldTriggerAttribute = *myTriggerAttribute;
|
|
// if(mySense == oldTriggerAttribute)
|
|
// {
|
|
// dpl_SetInstanceVisibility ( myInstance, 1 );
|
|
// }
|
|
// else
|
|
// {
|
|
// dpl_SetInstanceVisibility ( myInstance, 0 );
|
|
// }
|
|
// dpl_FlushInstance ( myInstance );
|
|
//}
|
|
//// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// StateInstanceSwitchRenderable is designed to be a watcher that connects to
|
|
// a state dial. Whenever the state dial changes we are called and check to
|
|
// see if the trigger state has been entered. If we are in the trigger state
|
|
// we will change the instance visibility based on the sense variable passed
|
|
// into the constructor. This lets you have an instance on while in a
|
|
// certain state or off while in that state and on in others.
|
|
// Messages Sent: None
|
|
// Messages Received: None
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for StateInstanceSwitchRenderable
|
|
//
|
|
StateInstanceSwitchRenderable::StateInstanceSwitchRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_INSTANCE *this_instance, // the instance to control
|
|
Logical sense, // true to turn on in this state, false for off
|
|
StateIndicator *state_dial, // State dial we use to control the on/off
|
|
unsigned trigger_state // State that we look for
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check incoming data for correctness
|
|
////
|
|
//Check_Pointer(this_instance);
|
|
//Check(state_dial);
|
|
////
|
|
//// Initialize variables
|
|
////
|
|
//myInstance = this_instance;
|
|
//mySense = sense;
|
|
//myStateDial = state_dial;
|
|
//myTriggerState = trigger_state;
|
|
////
|
|
//// Put the instance in the proper state and std::flush it
|
|
////
|
|
//if(myStateDial->GetState() == myTriggerState)
|
|
//{
|
|
// if(mySense == True)
|
|
// myLastInstanceState = True;
|
|
// else
|
|
// myLastInstanceState = False;
|
|
//}
|
|
//else
|
|
//{
|
|
// if(mySense == True)
|
|
// myLastInstanceState = False;
|
|
// else
|
|
// myLastInstanceState = True;
|
|
//}
|
|
//dpl_SetInstanceVisibility ( myInstance, myLastInstanceState );
|
|
//dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Connect us to the state dial's watcher hook
|
|
////
|
|
//state_dial->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for StateInstanceSwitchRenderable
|
|
StateInstanceSwitchRenderable::~StateInstanceSwitchRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the StateInstanceSwitchRenderable
|
|
Logical
|
|
StateInstanceSwitchRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myInstance);
|
|
Check(myStateDial);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the StateInstanceSwitchRenderable --- called by the state dial
|
|
// watcher hook when the state changes. The state dial won't call us if unless
|
|
// the state actually changes so there is no need to filter transitions between
|
|
// two identical states.
|
|
//
|
|
void
|
|
StateInstanceSwitchRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//unsigned
|
|
// new_state;
|
|
////
|
|
//// Check our variables
|
|
////
|
|
//Check(this);
|
|
////
|
|
//// See what state we should go into
|
|
////
|
|
//if(myStateDial->GetState() == myTriggerState)
|
|
//{
|
|
// if(mySense == True)
|
|
// new_state = True;
|
|
// else
|
|
// new_state = False;
|
|
//}
|
|
//else
|
|
//{
|
|
// if(mySense == True)
|
|
// new_state = False;
|
|
// else
|
|
// new_state = True;
|
|
//}
|
|
//if(new_state != myLastInstanceState)
|
|
//{
|
|
// myLastInstanceState = new_state;
|
|
// dpl_SetInstanceVisibility ( myInstance, myLastInstanceState );
|
|
// dpl_FlushInstance ( myInstance );
|
|
//}
|
|
//// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for MakeDCSFall
|
|
MakeDCSFall::MakeDCSFall(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_DCS *this_DCS, // the DCS to control
|
|
Scalar gravity, // Gravity in meters/sec squared
|
|
int *trigger // true if the instance is on, false if off
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
// Check incoming data
|
|
Check_Pointer(this_DCS);
|
|
Check_Pointer(trigger);
|
|
//
|
|
// Was an input trigger provided?
|
|
//
|
|
if(trigger)
|
|
{
|
|
// Yes, remember a pointer to it and it's state
|
|
myTrigger = trigger;
|
|
oldMyTrigger = *myTrigger;
|
|
}
|
|
else
|
|
{
|
|
// No, point it at a fake trigger that is turned on
|
|
fakeTrigger = 1;
|
|
myTrigger = &fakeTrigger;
|
|
oldMyTrigger = 0;
|
|
}
|
|
//
|
|
// Initialize other variables
|
|
//
|
|
myDCS = this_DCS;
|
|
myDisplacement = Point3D::Identity;
|
|
myHalfAcceleration = gravity/2.0f;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for MakeDCSFall
|
|
MakeDCSFall::~MakeDCSFall()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the MakeDCSFall
|
|
Logical
|
|
MakeDCSFall::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the MakeDCSFall
|
|
void
|
|
MakeDCSFall::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// Check our variables
|
|
//Check(this);
|
|
////
|
|
//// Look for an edge in the trigger input
|
|
////
|
|
//if(*myTrigger != oldMyTrigger)
|
|
//{
|
|
// //
|
|
// // A transition from zero to nonzero resets the DCS position and
|
|
// // starts us falling again.
|
|
// //
|
|
// if(oldMyTrigger == 0)
|
|
// {
|
|
// myFallStart = myRenderer->GetCurrentFrameTime();
|
|
// myDisplacement = Point3D::Identity;
|
|
// }
|
|
// oldMyTrigger = *myTrigger;
|
|
//}
|
|
////
|
|
//// If the trigger is nonzero and the sweep isn't at 1 yet, update
|
|
//// the sweep values.
|
|
////
|
|
//if(oldMyTrigger != 0)
|
|
//{
|
|
// Scalar
|
|
// elapsed_time,
|
|
// current_time;
|
|
// // Figure displacement do to gravity... 0.5 * a * t^2
|
|
// // note that we've already taken a * 0.5 in the constructor
|
|
// current_time = myRenderer->GetCurrentFrameTime();
|
|
// elapsed_time = current_time - myFallStart;
|
|
// myDisplacement.y = myHalfAcceleration * (elapsed_time * elapsed_time);
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer (tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = myDisplacement;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
//}
|
|
//// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//=============================================================================
|
|
#if 0
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for SquareWaveRenderable
|
|
SquareWaveRenderable::SquareWaveRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar time_false, // time to spend in zero state
|
|
Scalar time_true, // time to spend in one state
|
|
int *trigger // starts square wave when it goes to 1
|
|
int start_state // state we start in
|
|
int cycles // number of transitions before we stop
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
if(trigger)
|
|
{
|
|
// Yes, remember a pointer to it and it's state
|
|
myTriggerInput = trigger;
|
|
oldTriggerInput = *myTrigger;
|
|
}
|
|
else
|
|
{
|
|
// No, point it at a fake trigger that is turned on
|
|
fakeTrigger = 1;
|
|
myTriggerInput = &fakeTrigger;
|
|
oldTriggerInput = 0;
|
|
}
|
|
// Initialize variables
|
|
myTriggerInput = trigger;
|
|
oldTriggerInput = 0;
|
|
myNextStateChange = 0;
|
|
myTimeFalse = time_false;
|
|
myTimeTrue = time_true;
|
|
myTriggerAttribute = start_state;
|
|
myCyclesLeft = cycles;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for SquareWaveRenderable
|
|
SquareWaveRenderable::~SquareWaveRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the SquareWaveRenderable
|
|
Logical
|
|
SquareWaveRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Verify(myTriggerTime > 0.0f);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the SquareWaveRenderable
|
|
void
|
|
SquareWaveRenderable::Execute()
|
|
{
|
|
Scalar
|
|
current_time;
|
|
// Check our variables
|
|
Check(this);
|
|
|
|
if(*myTriggerInput != oldTriggerInput && oldTriggerInput == 0)
|
|
{
|
|
if(myStartState)
|
|
{
|
|
myNextStateChange = myRenderer->GetCurrentFrameTime();
|
|
myNextStateChange += myTimeTrue;
|
|
myTriggerAttribute = True;
|
|
}
|
|
else
|
|
{
|
|
myNextStateChange = myRenderer->GetCurrentFrameTime();
|
|
myNextStateChange += myTimeFalse;
|
|
myTriggerAttribute = False;
|
|
}
|
|
myCyclesLeft = myCycles;
|
|
}
|
|
|
|
if(*myTriggerInput == 1 && myCyclesLeft > 0)
|
|
{
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
if(current_time >= myNextStateChange)
|
|
{
|
|
myCyclesLeft--;
|
|
myTriggerAttribute = (!myTriggerAttribute);
|
|
if(myTriggerAttribute)
|
|
{
|
|
myNextStateChange = myRenderer->GetCurrentFrameTime();
|
|
myNextStateChange += myTimeTrue;
|
|
}
|
|
else
|
|
{
|
|
myNextStateChange = myRenderer->GetCurrentFrameTime();
|
|
myNextStateChange += myTimeFalse;
|
|
}
|
|
}
|
|
}
|
|
// Call the next lower execute method
|
|
#if DEBUG_LEVEL > 0
|
|
VideoRenderable::Execute();
|
|
#endif
|
|
}
|
|
#endif
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for OneShotDelayRenderable
|
|
// This renderable delays for a fixed amount after it's creation, then turns on
|
|
// a trigger attribute. It is used for the triggering of other renderables a
|
|
// fixed time after an object is created.
|
|
OneShotDelayRenderable::OneShotDelayRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar delay_time, // How long to wait before raising the trigger
|
|
Scalar duration_time // How long trigger is up (0.0 == stay up)
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
// Check incoming data
|
|
Verify(delay_time >= 0.0f);
|
|
Verify(duration_time >= 0.0f);
|
|
// Initialize variables
|
|
myState = WaitingForTriggerTime;
|
|
myEndTimeFlag = !Small_Enough(duration_time);
|
|
myTriggerTime = myRenderer->GetCurrentFrameTime();
|
|
myTriggerTime += delay_time;
|
|
myTriggerEndTime = myTriggerTime + duration_time;
|
|
myTriggerAttribute = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for OneShotDelayRenderable
|
|
OneShotDelayRenderable::~OneShotDelayRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the OneShotDelayRenderable
|
|
Logical
|
|
OneShotDelayRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Verify(myTriggerTime > 0.0f);
|
|
Verify(myTriggerEndTime >= myTriggerTime);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the OneShotDelayRenderable
|
|
void
|
|
OneShotDelayRenderable::Execute()
|
|
{
|
|
Scalar
|
|
current_time;
|
|
// Check our variables
|
|
Check(this);
|
|
if (myState != WaitingForEternity)
|
|
{
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
// putting this here insures that the one-time will always spend
|
|
// at least one frame at True before resetting.
|
|
if (myState == WaitingForTriggerTime)
|
|
{
|
|
if (current_time > myTriggerTime)
|
|
{
|
|
myTriggerAttribute = 1;
|
|
if (myEndTimeFlag)
|
|
{
|
|
myState = WaitingForTriggerEndTime;
|
|
}
|
|
else
|
|
{
|
|
myState = WaitingForEternity;
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
}
|
|
}
|
|
}
|
|
else if (myState == WaitingForTriggerEndTime)
|
|
{
|
|
if (current_time > myTriggerEndTime)
|
|
{
|
|
myTriggerAttribute = NULL;
|
|
myState = WaitingForEternity;
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Dump(myState);
|
|
Fail("invalid myState");
|
|
}
|
|
}
|
|
// Call the next lower execute method
|
|
#if DEBUG_LEVEL > 0
|
|
VideoRenderable::Execute();
|
|
#endif
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for SweepRenderable
|
|
// When triggered this renderable sweeps it's output attribute from 0.0 to 1.0
|
|
// over a preset time interval. Used for controling morphs.
|
|
SweepRenderable::SweepRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar delay_time, // How long to take to sweep from 0 to 1
|
|
int cycles, // number of times to cycle before stopping
|
|
int *trigger, // When it goes from 0 to 1 it resets the sweep generator
|
|
Scalar start_value, // Initial value of sweep (default = 0.0f)
|
|
Scalar end_value, // Final value of sweep (default = 1.0f)
|
|
SweepFunction sweep_function // Function applied to sweep
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//
|
|
// Verify incoming data
|
|
//
|
|
Verify(delay_time >= 0.0f);
|
|
Verify(start_value <= end_value);
|
|
if (sweep_function == Y_SQR_X)
|
|
{ Verify(start_value >= 0.0f); }
|
|
//
|
|
// Was an input trigger provided?
|
|
//
|
|
if(trigger)
|
|
{
|
|
// Yes, remember a pointer to it and it's state
|
|
myTrigger = trigger;
|
|
oldMyTrigger = *myTrigger;
|
|
}
|
|
else
|
|
{
|
|
// No, point it at a fake trigger that is turned on
|
|
fakeTrigger = 1;
|
|
myTrigger = &fakeTrigger;
|
|
oldMyTrigger = 0;
|
|
}
|
|
//
|
|
// Initialize other variables
|
|
//
|
|
mySweepFunction = sweep_function;
|
|
myStartValue = start_value;
|
|
myEndValue = end_value;
|
|
myCycleCount = cycles;
|
|
mySweepTime = delay_time;
|
|
mySweepAttribute = myStartValue;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for SweepRenderable
|
|
SweepRenderable::~SweepRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the SweepRenderable
|
|
Logical
|
|
SweepRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Verify(mySweepTime >= 0.0f)
|
|
Verify((mySweepAttribute >= myStartValue) && (mySweepAttribute <= myEndValue));
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the SweepRenderable
|
|
void
|
|
SweepRenderable::Execute()
|
|
{
|
|
// Check our variables
|
|
Check(this);
|
|
//
|
|
// Look for an edge in the trigger input
|
|
//
|
|
if(*myTrigger != oldMyTrigger)
|
|
{
|
|
//
|
|
// A transition from zero to nonzero resets all the sweep parameters
|
|
// and starts the process over again.
|
|
//
|
|
if(oldMyTrigger == 0)
|
|
{
|
|
// A transition from zero to nonzero causes a reset of sweep timers
|
|
// and starts the sweep running.
|
|
mySweepStart = myRenderer->GetCurrentFrameTime();
|
|
mySweepAttribute = myStartValue;
|
|
myCyclesLeft = myCycleCount;
|
|
}
|
|
oldMyTrigger = *myTrigger;
|
|
}
|
|
//
|
|
// If the trigger is nonzero and the sweep isn't at 1 yet, update
|
|
// the sweep values.
|
|
//
|
|
if(oldMyTrigger != 0 && myCyclesLeft > 0)
|
|
{
|
|
Scalar
|
|
current_time;
|
|
// putting this here insures that the sweep will always spend one frame at
|
|
// {EndValue} before resetting.
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
if(mySweepAttribute >= myEndValue)
|
|
{
|
|
myCyclesLeft--;
|
|
if(myCyclesLeft > 0)
|
|
{ mySweepStart = current_time; }
|
|
}
|
|
mySweepAttribute = myStartValue + (myEndValue - myStartValue) *
|
|
(current_time - mySweepStart) / mySweepTime;
|
|
if (mySweepFunction == Y_SQR_X)
|
|
{
|
|
mySweepAttribute = Sqrt(mySweepAttribute);
|
|
}
|
|
// else if (mySweepFunction == Y_ )
|
|
// {
|
|
// }
|
|
if(mySweepAttribute > myEndValue)
|
|
{ mySweepAttribute = myEndValue; }
|
|
}
|
|
// Call the next lower execute method
|
|
#if DEBUG_LEVEL > 0
|
|
VideoRenderable::Execute();
|
|
#endif
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for PullFogRenderable
|
|
// This routine handles swapping the fog settings in and out when you
|
|
// turn headlight systems on and off.
|
|
//
|
|
PullFogRenderable::PullFogRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Logical *light_1,
|
|
Logical *light_2 // address containing the trigger
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check_Pointer(light_1);
|
|
myLight1 = light_1;
|
|
myOldLight1 = !(*myLight1);
|
|
if(light_2 == NULL)
|
|
{
|
|
myLight2 = myLight1;
|
|
}
|
|
else
|
|
{
|
|
Check_Pointer(light_2);
|
|
myLight2 = light_2;
|
|
}
|
|
myOldLight2 = !(*myLight2);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for PullFogRenderable
|
|
//
|
|
PullFogRenderable::~PullFogRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the PullFogRenderable
|
|
//
|
|
Logical
|
|
PullFogRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myLight1);
|
|
Check_Pointer(myLight2);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for PullFogRenderable.
|
|
//
|
|
void
|
|
PullFogRenderable::Execute()
|
|
{
|
|
Check(this);
|
|
if(*myLight1 != myOldLight1 || *myLight2 != myOldLight2)
|
|
{
|
|
myOldLight1 = *myLight1;
|
|
myOldLight2 = *myLight2;
|
|
if(myOldLight1 || myOldLight2)
|
|
{
|
|
myRenderer->SetFogStyle(DPLRenderer::searchLightOnFogStyle);
|
|
}
|
|
else
|
|
{
|
|
myRenderer->SetFogStyle(DPLRenderer::searchLightOffFogStyle);
|
|
}
|
|
}
|
|
// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLEffectRenderable
|
|
// This routine handles the creation of a DPL special effect whenever the
|
|
// trigger attribute changes. This is an edge triggered renderable and will
|
|
// generate an effect on ANY form of state change. The only way to effect the
|
|
// size and speed of the effect is by way of the DPL effect tables.
|
|
//
|
|
DPLEffectRenderable::DPLEffectRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
int *trigger, // address containing the trigger
|
|
int effect_type, // DPL effect number to trigger
|
|
HierarchicalDrawComponent *parent, // DCS the effect is relative to (may be NULL)
|
|
Point3D *offset_point // Offset (or world coordinants if DCS is NULL)
|
|
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check_Pointer(trigger);
|
|
Verify(effect_type >= 0);
|
|
#if DEBUG_LEVEL > 0
|
|
if(effect_DCS != NULL)
|
|
Check_Pointer(effect_DCS);
|
|
#endif
|
|
Check(offset_point);
|
|
//
|
|
// Initialze the local variables
|
|
//
|
|
myTrigger = trigger;
|
|
oldMyTrigger = *myTrigger;
|
|
myEffectType = effect_type;
|
|
// myEffectDCS = effect_DCS;
|
|
myEffectOffset = *offset_point;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLEffectRenderable
|
|
//
|
|
DPLEffectRenderable::~DPLEffectRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLEffectRenderable
|
|
//
|
|
Logical
|
|
DPLEffectRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myTrigger);
|
|
Verify(myEffectType >= 0);
|
|
#if DEBUG_LEVEL > 0
|
|
if(myEffectDCS != NULL)
|
|
Check_Pointer(myEffectDCS);
|
|
#endif
|
|
Check(&myEffectOffset);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLEffectRenderable.
|
|
//
|
|
void
|
|
DPLEffectRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Check_Pointer(myTrigger);
|
|
//if(*myTrigger != oldMyTrigger)
|
|
//{
|
|
// dpl_EXPLOSION_EFFECT_INFO my_explosion;
|
|
// oldMyTrigger = *myTrigger;
|
|
// my_explosion.type = myEffectType;
|
|
// my_explosion.x = myEffectOffset.x;
|
|
// my_explosion.y = myEffectOffset.y;
|
|
// my_explosion.z = myEffectOffset.z;
|
|
// dpl_Effect ( dpl_effect_type_explosion, myEffectDCS, &my_explosion );
|
|
//}
|
|
//// Call the next lower execute method
|
|
//#if DEBUG_LEVEL > 0
|
|
VideoRenderable::Execute();
|
|
// #endif
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLPSFXRenderable
|
|
// This routine triggers a pfx whenever the trigger attribute goes true.
|
|
// since pfx effects have built-in durations we don't attempt to do any repeats
|
|
// or other controls here, we just start one and kill it if the entity dies.
|
|
//
|
|
DPLPSFXRenderable::DPLPSFXRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
int *trigger, // address containing the trigger
|
|
dpl_PARTICLESTART_EFFECT_INFO *psfx_definition, // name of file with the PFX description in it
|
|
HierarchicalDrawComponent *parent, // DCS the effect is relative to (may be NULL)
|
|
Point3D *offset_point // Offset (or world coordinants if DCS is NULL)
|
|
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check_Pointer(trigger);
|
|
#if DEBUG_LEVEL > 0
|
|
if(effect_DCS != NULL)
|
|
Check_Pointer(effect_DCS);
|
|
#endif
|
|
Check(offset_point);
|
|
if(!psfx_definition)
|
|
{
|
|
Fail("A pfx was not defined in the .ini file\n");
|
|
}
|
|
//
|
|
// Initialze the local variables
|
|
//
|
|
myTrigger = trigger;
|
|
myOldTrigger = *myTrigger;
|
|
// myEffectDCS = effect_DCS;
|
|
myEffectOffset = *offset_point;
|
|
myPSFXInfo = *psfx_definition;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLPSFXRenderable
|
|
//
|
|
DPLPSFXRenderable::~DPLPSFXRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// !!!!HACK Note that because the effect id changes every time we start one,
|
|
//// the destructor will only stop the last PFX played. We should probably
|
|
//// be keeping track of all the ID's we've sent down to make sure everything
|
|
//// attached to the DCS gets properly killed.
|
|
//Check(this);
|
|
//dpl_Effect ( dpl_effect_type_particlestop, NULL, &myPSFXInfo );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLPSFXRenderable
|
|
//
|
|
Logical
|
|
DPLPSFXRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myTrigger);
|
|
#if DEBUG_LEVEL > 0
|
|
if(myEffectDCS != NULL)
|
|
Check_Pointer(myEffectDCS);
|
|
#endif
|
|
Check(&myEffectOffset);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLPSFXRenderable.
|
|
//
|
|
void
|
|
DPLPSFXRenderable::Execute()
|
|
{
|
|
Check_Pointer(myTrigger);
|
|
if(*myTrigger != myOldTrigger)
|
|
{
|
|
myOldTrigger = *myTrigger;
|
|
if(myOldTrigger == True)
|
|
{
|
|
// we put our id into the lower 16 bits because (at least) the upper 8 bits are flags
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
//myPSFXInfo.identifier =
|
|
// (myPSFXInfo.identifier & 0xffff0000) |
|
|
// l4_application->GetVideoRenderer()->GetUniqueID();
|
|
//dpl_Effect ( dpl_effect_type_particlestart, myEffectDCS, &myPSFXInfo );
|
|
}
|
|
}
|
|
// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLPSFXStateRenderable
|
|
// This routine triggers a pfx whenever a state dial transitions to a designated
|
|
// state.
|
|
// NOTE this currently does NOT trigger if the state dial is in the trigger state
|
|
// when this renderable is created.
|
|
//
|
|
DPLPSFXStateRenderable::DPLPSFXStateRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
StateIndicator *effect_trigger, // Trigger effect when this state changes
|
|
unsigned my_trigger, // The state to edge trigger on
|
|
dpl_PARTICLESTART_EFFECT_INFO *psfx_definition, // name of file with the PFX description in it
|
|
HierarchicalDrawComponent *parent, // DCS the effect is relative to (may be NULL)
|
|
Point3D *offset_point // Offset (or world coordinants if DCS is NULL)
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check(effect_trigger);
|
|
Check_Pointer(psfx_definition);
|
|
#if DEBUG_LEVEL > 0
|
|
if(effect_DCS != NULL)
|
|
Check_Pointer(effect_DCS);
|
|
#endif
|
|
Check(offset_point);
|
|
if(!psfx_definition)
|
|
{
|
|
Fail("A pfx was not defined in the .ini file\n");
|
|
}
|
|
//
|
|
// Initialze the local variables
|
|
//
|
|
myTriggerState = my_trigger;
|
|
myStateDial = effect_trigger;
|
|
// myEffectDCS = effect_DCS;
|
|
myEffectOffset = *offset_point;
|
|
myPSFXInfo = *psfx_definition;
|
|
//
|
|
// Add us to the state's watcher socket
|
|
//
|
|
effect_trigger->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLPSFXStateRenderable
|
|
//
|
|
DPLPSFXStateRenderable::~DPLPSFXStateRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// !!!!HACK Note that because the effect id changes every time we start one,
|
|
//// the destructor will only stop the last PFX played. We should probably
|
|
//// be keeping track of all the ID's we've sent down to make sure everything
|
|
//// attached to the DCS gets properly killed.
|
|
//Check(this);
|
|
//dpl_Effect ( dpl_effect_type_particlestop, NULL, &myPSFXInfo );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLPSFXStateRenderable
|
|
//
|
|
Logical
|
|
DPLPSFXStateRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
#if DEBUG_LEVEL > 0
|
|
if(myEffectDCS != NULL)
|
|
Check_Pointer(myEffectDCS);
|
|
#endif
|
|
Check(&myEffectOffset);
|
|
Check(myStateDial);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLPSFXStateRenderable.
|
|
// Note that this will get called by the state dial, not by the renderer
|
|
//
|
|
void DPLPSFXStateRenderable::Execute()
|
|
{
|
|
Check(myStateDial);
|
|
//
|
|
// If the state dial is in the right state, trigger
|
|
//
|
|
if(myStateDial->GetState() == myTriggerState)
|
|
{
|
|
// we put our id into the lower 16 bits because (at least) the upper 8 bits are flags
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
//myPSFXInfo.identifier =
|
|
// (myPSFXInfo.identifier & 0xffff0000) |
|
|
// l4_application->GetVideoRenderer()->GetUniqueID();
|
|
//dpl_Effect ( dpl_effect_type_particlestart, myEffectDCS, &myPSFXInfo );
|
|
}
|
|
//
|
|
// Call the next lower execute method
|
|
//
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLMaterialRenderable
|
|
// This renderable creates a DPL Material structure and encapsulates it so
|
|
// it will be properly deleted when the object it's part of gets deleted.
|
|
DPLMaterialRenderable::DPLMaterialRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar ambient_red, // Material's ambient component
|
|
Scalar ambient_green,
|
|
Scalar ambient_blue,
|
|
Scalar emissive_red, // Material's emissive component
|
|
Scalar emissive_green,
|
|
Scalar emissive_blue,
|
|
Scalar diffuse_red, // Material's diffuse component
|
|
Scalar diffuse_green,
|
|
Scalar diffuse_blue,
|
|
Scalar specular_red, // Material's specular component
|
|
Scalar specular_green,
|
|
Scalar specular_blue,
|
|
Scalar specular_shininess,
|
|
Scalar opacity_red, // Material's opacity
|
|
Scalar opacity_green,
|
|
Scalar opacity_blue,
|
|
dpl_TEXTURE *texture, // Material's texture pointer
|
|
Scalar z_dither, // Material's Z dither value
|
|
int fog_immune // Material's Fog Imunity value
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// Check input pointers
|
|
//#if DEBUG_LEVEL > 0
|
|
//if(texture)
|
|
// Check_Pointer(texture);
|
|
//#endif
|
|
//// Create and initialize the DPL material
|
|
//myMaterial = dpl_NewMaterial();
|
|
//Check_Pointer(myMaterial);
|
|
////
|
|
//// Materials should be static most of the time, if they are dynamic it means someone
|
|
//// inheriting from us is going to try and modify the material. So if we are dynamic
|
|
//// we leave the rest of this stuff for that routine to do
|
|
////
|
|
//if(execution_type == DPLMaterialRenderable::Static)
|
|
//{
|
|
// dpl_SetMaterialAmbient (myMaterial, ambient_red, ambient_green, ambient_blue);
|
|
// dpl_SetMaterialEmissive (myMaterial, emissive_red, emissive_green, emissive_blue);
|
|
// dpl_SetMaterialDiffuse (myMaterial, diffuse_red, diffuse_green, diffuse_blue);
|
|
// dpl_SetMaterialSpecular (myMaterial, specular_red, specular_green, specular_blue, specular_shininess);
|
|
// dpl_SetMaterialOpacity (myMaterial, opacity_red, opacity_green, opacity_blue);
|
|
// if(texture)
|
|
// dpl_SetMaterialTexture(myMaterial, texture);
|
|
// if(z_dither)
|
|
// dpl_SetMaterialDitherZ(myMaterial, z_dither);
|
|
// if(fog_immune)
|
|
// dpl_SetMaterialFogImmunity(myMaterial,fog_immune);
|
|
// dpl_FlushMaterial(myMaterial);
|
|
//}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLMaterialRenderable
|
|
DPLMaterialRenderable::~DPLMaterialRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//// Check our structure before we do anything
|
|
//Check(this);
|
|
//dpl_DeleteMaterial(myMaterial);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLMaterialRenderable
|
|
Logical
|
|
DPLMaterialRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myMaterial);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLMaterialRenderable
|
|
void
|
|
DPLMaterialRenderable::Execute()
|
|
{
|
|
Check(this);
|
|
// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for MorphMaterialRenderable
|
|
// This renderable takes two material specifications and loads up a third
|
|
// material with a morph between the first two.
|
|
MorphMaterialRenderable::MorphMaterialRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
Scalar ambient_red_1, // Material's ambient component
|
|
Scalar ambient_green_1,
|
|
Scalar ambient_blue_1,
|
|
Scalar emissive_red_1, // Material's emissive component
|
|
Scalar emissive_green_1,
|
|
Scalar emissive_blue_1,
|
|
Scalar diffuse_red_1, // Material's diffuse component
|
|
Scalar diffuse_green_1,
|
|
Scalar diffuse_blue_1,
|
|
Scalar specular_red_1, // Material's specular component
|
|
Scalar specular_green_1,
|
|
Scalar specular_blue_1,
|
|
Scalar specular_shininess_1,
|
|
Scalar opacity_red_1, // Material's opacity
|
|
Scalar opacity_green_1,
|
|
Scalar opacity_blue_1,
|
|
dpl_TEXTURE *texture_1, // Material's texture pointer
|
|
Scalar z_dither_1, // Material's Z dither value
|
|
int fog_immune_1, // Material's Fog Imunity value
|
|
Scalar ambient_red_2, // Material's ambient component
|
|
Scalar ambient_green_2,
|
|
Scalar ambient_blue_2,
|
|
Scalar emissive_red_2, // Material's emissive component
|
|
Scalar emissive_green_2,
|
|
Scalar emissive_blue_2,
|
|
Scalar diffuse_red_2, // Material's diffuse component
|
|
Scalar diffuse_green_2,
|
|
Scalar diffuse_blue_2,
|
|
Scalar specular_red_2, // Material's specular component
|
|
Scalar specular_green_2,
|
|
Scalar specular_blue_2,
|
|
Scalar specular_shininess_2,
|
|
Scalar opacity_red_2, // Material's opacity
|
|
Scalar opacity_green_2,
|
|
Scalar opacity_blue_2,
|
|
Scalar z_dither_2, // Material's Z dither value
|
|
Scalar *morph_control
|
|
):
|
|
DPLMaterialRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type,
|
|
ambient_red_1, ambient_green_1, ambient_blue_1, // Material's ambient component
|
|
emissive_red_1, emissive_green_1, emissive_blue_1, // Material's emissive component
|
|
diffuse_red_1, diffuse_green_1, diffuse_blue_1, // Material's diffuse component
|
|
specular_red_1, specular_green_1, specular_blue_1, specular_shininess_1, // Material's specular component
|
|
opacity_red_1, opacity_green_1, opacity_blue_1, // Material's opacity
|
|
texture_1, // Material's texture pointer
|
|
z_dither_1, // Material's Z dither value
|
|
fog_immune_1) // Material's Fog Imunity value
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Scalar
|
|
// Weight1,
|
|
// Weight2;
|
|
////
|
|
//// Remember the parameters of the two materials we are morphing between
|
|
////
|
|
//myAmbientRed1 = ambient_red_1; // Material's ambient component
|
|
//myAmbientGreen1 = ambient_green_1;
|
|
//myAmbientBlue1 = ambient_blue_1;
|
|
//myEmissiveRed1 = emissive_red_1; // Material's emissive component
|
|
//myEmissiveGreen1 = emissive_green_1;
|
|
//myEmissiveBlue1 = emissive_blue_1;
|
|
//myDiffuseRed1 = diffuse_red_1; // Material's diffuse component
|
|
//myDiffuseGreen1 = diffuse_green_1;
|
|
//myDiffuseBlue1 = diffuse_blue_1;
|
|
//mySpecularRed1 = specular_red_1; // Material's specular component
|
|
//mySpecularGreen1 = specular_green_1;
|
|
//mySpecularBlue1 = specular_blue_1;
|
|
//mySpecularShininess1 = specular_shininess_1;
|
|
//myOpacityRed1 = opacity_red_1; // Material's opacity
|
|
//myOpacityGreen1 = opacity_green_1;
|
|
//myOpacityBlue1 = opacity_blue_1;
|
|
//myTexture1 = texture_1; // Material's texture pointer
|
|
//myZDither1 = z_dither_1; // Material's Z dither value
|
|
//myFogImmune1 = fog_immune_1; // Material's Fog Imunity value
|
|
//myAmbientRed2 = ambient_red_2; // Material's ambient component
|
|
//myAmbientGreen2 = ambient_green_2;
|
|
//myAmbientBlue2 = ambient_blue_2;
|
|
//myEmissiveRed2 = emissive_red_2; // Material's emissive component
|
|
//myEmissiveGreen2 = emissive_green_2;
|
|
//myEmissiveBlue2 = emissive_blue_2;
|
|
//myDiffuseRed2 = diffuse_red_2; // Material's diffuse component
|
|
//myDiffuseGreen2 = diffuse_green_2;
|
|
//myDiffuseBlue2 = diffuse_blue_2;
|
|
//mySpecularRed2 = specular_red_2; // Material's specular component
|
|
//mySpecularGreen2 = specular_green_2;
|
|
//mySpecularBlue2 = specular_blue_2;
|
|
//mySpecularShininess2 = specular_shininess_2;
|
|
//myOpacityRed2 = opacity_red_2; // Material's opacity
|
|
//myOpacityGreen2 = opacity_green_2;
|
|
//myOpacityBlue2 = opacity_blue_2;
|
|
//myZDither2 = z_dither_2; // Material's Z dither value
|
|
//myMorphControl = morph_control;
|
|
//oldMorphControl = *morph_control;
|
|
////
|
|
//// Calculate the target material
|
|
////
|
|
//Weight1 = 1.0 - oldMorphControl;
|
|
//Weight2 = oldMorphControl;
|
|
//myAmbientRed = (myAmbientRed1*Weight1) + (myAmbientRed2*Weight2);
|
|
//myAmbientGreen = (myAmbientGreen1*Weight1) + (myAmbientGreen2*Weight2);
|
|
//myAmbientBlue = (myAmbientBlue1*Weight1) + (myAmbientBlue2*Weight2);
|
|
//myEmissiveRed = (myEmissiveRed1*Weight1) + (myEmissiveRed2*Weight2);
|
|
//myEmissiveGreen = (myEmissiveGreen1*Weight1) + (myEmissiveGreen2*Weight2);
|
|
//myEmissiveBlue = (myEmissiveBlue1*Weight1) + (myEmissiveBlue2*Weight2);
|
|
//myDiffuseRed = (myDiffuseRed1*Weight1) + (myDiffuseRed2*Weight2);
|
|
//myDiffuseGreen = (myDiffuseGreen1*Weight1) + (myDiffuseGreen2*Weight2);
|
|
//myDiffuseBlue = (myDiffuseBlue1*Weight1) + (myDiffuseBlue2*Weight2);
|
|
//mySpecularRed = (mySpecularRed1*Weight1) + (mySpecularRed2*Weight2);
|
|
//mySpecularGreen = (mySpecularGreen1*Weight1) + (mySpecularGreen2*Weight2);
|
|
//mySpecularBlue = (mySpecularBlue1*Weight1) + (mySpecularBlue2*Weight2);
|
|
//mySpecularShininess = (mySpecularShininess1*Weight1) + (mySpecularShininess2*Weight2);
|
|
//myOpacityRed = (myOpacityRed1*Weight1) + (myOpacityRed2*Weight2);
|
|
//myOpacityGreen = (myOpacityGreen1*Weight1) + (myOpacityGreen2*Weight2);
|
|
//myOpacityBlue = (myOpacityBlue1*Weight1) + (myOpacityBlue2*Weight2);
|
|
//myZDither = (myZDither1*Weight1) + (myZDither2*Weight2);
|
|
////
|
|
//// Initialize the target material
|
|
////
|
|
//dpl_SetMaterialAmbient (myMaterial, myAmbientRed, myAmbientGreen, myAmbientBlue);
|
|
//dpl_SetMaterialEmissive (myMaterial, myEmissiveRed, myEmissiveGreen, myEmissiveBlue);
|
|
//dpl_SetMaterialDiffuse (myMaterial, myDiffuseRed, myDiffuseGreen, myDiffuseBlue);
|
|
//dpl_SetMaterialSpecular (myMaterial, mySpecularRed, mySpecularGreen, mySpecularBlue, mySpecularShininess);
|
|
//dpl_SetMaterialOpacity (myMaterial, myOpacityRed, myOpacityGreen, myOpacityBlue);
|
|
//if(myTexture1)
|
|
// dpl_SetMaterialTexture(myMaterial, myTexture1);
|
|
//if(myZDither)
|
|
// dpl_SetMaterialDitherZ(myMaterial,myZDither);
|
|
//if(myFogImmune1)
|
|
// dpl_SetMaterialFogImmunity(myMaterial,myFogImmune1);
|
|
//dpl_FlushMaterial(myMaterial);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for MorphMaterialRenderable
|
|
MorphMaterialRenderable::~MorphMaterialRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the MorphMaterialRenderable
|
|
Logical
|
|
MorphMaterialRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the MorphMaterialRenderable
|
|
void
|
|
MorphMaterialRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
//Scalar
|
|
// Weight1,
|
|
// Weight2;
|
|
|
|
//Check(this);
|
|
//// See if the morph control variable has changed
|
|
//if(oldMorphControl != *myMorphControl)
|
|
//{
|
|
// //
|
|
// // Re-calculate the target material
|
|
// //
|
|
// oldMorphControl = *myMorphControl;
|
|
// Weight1 = 1.0 - oldMorphControl;
|
|
// Weight2 = oldMorphControl;
|
|
// myAmbientRed = (myAmbientRed1*Weight1) + (myAmbientRed2*Weight2);
|
|
// myAmbientGreen = (myAmbientGreen1*Weight1) + (myAmbientGreen2*Weight2);
|
|
// myAmbientBlue = (myAmbientBlue1*Weight1) + (myAmbientBlue2*Weight2);
|
|
// myEmissiveRed = (myEmissiveRed1*Weight1) + (myEmissiveRed2*Weight2);
|
|
// myEmissiveGreen = (myEmissiveGreen1*Weight1) + (myEmissiveGreen2*Weight2);
|
|
// myEmissiveBlue = (myEmissiveBlue1*Weight1) + (myEmissiveBlue2*Weight2);
|
|
// myDiffuseRed = (myDiffuseRed1*Weight1) + (myDiffuseRed2*Weight2);
|
|
// myDiffuseGreen = (myDiffuseGreen1*Weight1) + (myDiffuseGreen2*Weight2);
|
|
// myDiffuseBlue = (myDiffuseBlue1*Weight1) + (myDiffuseBlue2*Weight2);
|
|
// mySpecularRed = (mySpecularRed1*Weight1) + (mySpecularRed2*Weight2);
|
|
// mySpecularGreen = (mySpecularGreen1*Weight1) + (mySpecularGreen2*Weight2);
|
|
// mySpecularBlue = (mySpecularBlue1*Weight1) + (mySpecularBlue2*Weight2);
|
|
// mySpecularShininess = (mySpecularShininess1*Weight1) + (mySpecularShininess2*Weight2);
|
|
// myOpacityRed = (myOpacityRed1*Weight1) + (myOpacityRed2*Weight2);
|
|
// myOpacityGreen = (myOpacityGreen1*Weight1) + (myOpacityGreen2*Weight2);
|
|
// myOpacityBlue = (myOpacityBlue1*Weight1) + (myOpacityBlue2*Weight2);
|
|
// myZDither = (myZDither1*Weight1) + (myZDither2*Weight2);
|
|
// //
|
|
// // Reset the target material and std::flush it
|
|
// // Note we don't try to morph texture or fog immune
|
|
// //
|
|
// dpl_SetMaterialAmbient (myMaterial, myAmbientRed, myAmbientGreen, myAmbientBlue);
|
|
// dpl_SetMaterialEmissive (myMaterial, myEmissiveRed, myEmissiveGreen, myEmissiveBlue);
|
|
// dpl_SetMaterialDiffuse (myMaterial, myDiffuseRed, myDiffuseGreen, myDiffuseBlue);
|
|
// dpl_SetMaterialSpecular (myMaterial, mySpecularRed, mySpecularGreen, mySpecularBlue, mySpecularShininess);
|
|
// dpl_SetMaterialOpacity (myMaterial, myOpacityRed, myOpacityGreen, myOpacityBlue);
|
|
// if(myZDither)
|
|
// dpl_SetMaterialDitherZ(myMaterial,myZDither);
|
|
// dpl_FlushMaterial(myMaterial);
|
|
//}
|
|
//// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLDamageMaterialRenderable
|
|
// This renderable handles modifying a material in response to damage. We
|
|
// get the pointer to an existing DPL material on startup and we get out
|
|
// color and texture settings from that
|
|
DPLDamageMaterialRenderable::DPLDamageMaterialRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_MATERIAL *damage_material, // The material we want to control
|
|
Scalar *damage_attribute, // The attribute containing the current damage level
|
|
Scalar damage_percent // Degradation factor to make damaged material
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Scalar
|
|
// Weight1,
|
|
// Weight2;
|
|
//
|
|
// Check_Pointer(damage_material);
|
|
// Check_Pointer(damage_attribute);
|
|
// Verify(damage_percent >= 0.0f && damage_percent <= 1.0f);
|
|
// //
|
|
// // Grab the material's components, remember them and figure the target colors
|
|
// //
|
|
// myMaterial = damage_material;
|
|
// myDamageAttribute = damage_attribute;
|
|
// oldDamageAttribute = *myDamageAttribute;
|
|
// dpl_GetMaterialAmbient (myMaterial, &myAmbientRed1, &myAmbientGreen1, &myAmbientBlue1);
|
|
// dpl_GetMaterialEmissive (myMaterial, &myEmissiveRed1, &myEmissiveGreen1, &myEmissiveBlue1);
|
|
// dpl_GetMaterialDiffuse (myMaterial, &myDiffuseRed1, &myDiffuseGreen1, &myDiffuseBlue1);
|
|
// dpl_GetMaterialSpecular (myMaterial, &mySpecularRed1, &mySpecularGreen1, &mySpecularBlue1, &mySpecularShininess1);
|
|
// dpl_GetMaterialOpacity (myMaterial, &myOpacityRed1, &myOpacityGreen1, &myOpacityBlue1);
|
|
// myAmbientRed2 = damage_percent * myAmbientRed1; // Material's ambient component
|
|
// myAmbientGreen2 = damage_percent * myAmbientGreen1;
|
|
// myAmbientBlue2 = damage_percent * myAmbientBlue1;
|
|
// myEmissiveRed2 = damage_percent * myEmissiveRed1; // Material's emissive component
|
|
// myEmissiveGreen2 = damage_percent * myEmissiveGreen1;
|
|
// myEmissiveBlue2 = damage_percent * myEmissiveBlue1;
|
|
// myDiffuseRed2 = damage_percent * myDiffuseRed1; // Material's diffuse component
|
|
// myDiffuseGreen2 = damage_percent * myDiffuseGreen1;
|
|
// myDiffuseBlue2 = damage_percent * myDiffuseBlue1;
|
|
// mySpecularRed2 = damage_percent * mySpecularRed1; // Material's specular component
|
|
// mySpecularGreen2 = damage_percent * mySpecularGreen1;
|
|
// mySpecularBlue2 = damage_percent * mySpecularBlue1;
|
|
// mySpecularShininess2 = damage_percent * mySpecularShininess1;
|
|
// myOpacityRed2 = damage_percent * myOpacityRed1; // Material's opacity
|
|
// myOpacityGreen2 = damage_percent * myOpacityGreen1;
|
|
// myOpacityBlue2 = damage_percent * myOpacityBlue1;
|
|
// //
|
|
// // Calculate the target material using the current level of damage
|
|
// //
|
|
// Weight1 = 1.0f - oldDamageAttribute;
|
|
// Weight2 = oldDamageAttribute;
|
|
// myAmbientRed = (myAmbientRed1*Weight1) + (myAmbientRed2*Weight2);
|
|
// myAmbientGreen = (myAmbientGreen1*Weight1) + (myAmbientGreen2*Weight2);
|
|
// myAmbientBlue = (myAmbientBlue1*Weight1) + (myAmbientBlue2*Weight2);
|
|
// myEmissiveRed = (myEmissiveRed1*Weight1) + (myEmissiveRed2*Weight2);
|
|
// myEmissiveGreen = (myEmissiveGreen1*Weight1) + (myEmissiveGreen2*Weight2);
|
|
// myEmissiveBlue = (myEmissiveBlue1*Weight1) + (myEmissiveBlue2*Weight2);
|
|
// myDiffuseRed = (myDiffuseRed1*Weight1) + (myDiffuseRed2*Weight2);
|
|
// myDiffuseGreen = (myDiffuseGreen1*Weight1) + (myDiffuseGreen2*Weight2);
|
|
// myDiffuseBlue = (myDiffuseBlue1*Weight1) + (myDiffuseBlue2*Weight2);
|
|
// mySpecularRed = (mySpecularRed1*Weight1) + (mySpecularRed2*Weight2);
|
|
// mySpecularGreen = (mySpecularGreen1*Weight1) + (mySpecularGreen2*Weight2);
|
|
// mySpecularBlue = (mySpecularBlue1*Weight1) + (mySpecularBlue2*Weight2);
|
|
// mySpecularShininess = (mySpecularShininess1*Weight1)+ (mySpecularShininess2*Weight2);
|
|
// myOpacityRed = (myOpacityRed1*Weight1) + (myOpacityRed2*Weight2);
|
|
// myOpacityGreen = (myOpacityGreen1*Weight1) + (myOpacityGreen2*Weight2);
|
|
// myOpacityBlue = (myOpacityBlue1*Weight1) + (myOpacityBlue2*Weight2);
|
|
// //
|
|
// // Set the target material
|
|
// //
|
|
// dpl_SetMaterialAmbient (myMaterial, myAmbientRed, myAmbientGreen, myAmbientBlue);
|
|
// dpl_SetMaterialEmissive (myMaterial, myEmissiveRed, myEmissiveGreen, myEmissiveBlue);
|
|
// dpl_SetMaterialDiffuse (myMaterial, myDiffuseRed, myDiffuseGreen, myDiffuseBlue);
|
|
// dpl_SetMaterialSpecular (myMaterial, mySpecularRed, mySpecularGreen, mySpecularBlue, mySpecularShininess);
|
|
//// dpl_SetMaterialOpacity (myMaterial, myOpacityRed, myOpacityGreen, myOpacityBlue);
|
|
// dpl_FlushMaterial(myMaterial);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLDamageMaterialRenderable
|
|
DPLDamageMaterialRenderable::~DPLDamageMaterialRenderable()
|
|
{
|
|
// Check our structure before we do anything
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLDamageMaterialRenderable
|
|
Logical
|
|
DPLDamageMaterialRenderable::TestInstance() const
|
|
{
|
|
// Call our parent's TestInstance first
|
|
VideoRenderable::TestInstance();
|
|
Check_Pointer(myMaterial);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLDamageMaterialRenderable
|
|
void
|
|
DPLDamageMaterialRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Scalar
|
|
// Weight1,
|
|
// Weight2;
|
|
//
|
|
// Check(this);
|
|
// if(oldDamageAttribute != *myDamageAttribute)
|
|
// {
|
|
// //
|
|
// // Re-calculate the target material
|
|
// //
|
|
// oldDamageAttribute = *myDamageAttribute;
|
|
// Weight1 = 1.0 - oldDamageAttribute;
|
|
// Weight2 = oldDamageAttribute;
|
|
// myAmbientRed = (myAmbientRed1*Weight1) + (myAmbientRed2*Weight2);
|
|
// myAmbientGreen = (myAmbientGreen1*Weight1) + (myAmbientGreen2*Weight2);
|
|
// myAmbientBlue = (myAmbientBlue1*Weight1) + (myAmbientBlue2*Weight2);
|
|
// myEmissiveRed = (myEmissiveRed1*Weight1) + (myEmissiveRed2*Weight2);
|
|
// myEmissiveGreen = (myEmissiveGreen1*Weight1) + (myEmissiveGreen2*Weight2);
|
|
// myEmissiveBlue = (myEmissiveBlue1*Weight1) + (myEmissiveBlue2*Weight2);
|
|
// myDiffuseRed = (myDiffuseRed1*Weight1) + (myDiffuseRed2*Weight2);
|
|
// myDiffuseGreen = (myDiffuseGreen1*Weight1) + (myDiffuseGreen2*Weight2);
|
|
// myDiffuseBlue = (myDiffuseBlue1*Weight1) + (myDiffuseBlue2*Weight2);
|
|
// mySpecularRed = (mySpecularRed1*Weight1) + (mySpecularRed2*Weight2);
|
|
// mySpecularGreen = (mySpecularGreen1*Weight1) + (mySpecularGreen2*Weight2);
|
|
// mySpecularBlue = (mySpecularBlue1*Weight1) + (mySpecularBlue2*Weight2);
|
|
// mySpecularShininess = (mySpecularShininess1*Weight1)+ (mySpecularShininess2*Weight2);
|
|
// myOpacityRed = (myOpacityRed1*Weight1) + (myOpacityRed2*Weight2);
|
|
// myOpacityGreen = (myOpacityGreen1*Weight1) + (myOpacityGreen2*Weight2);
|
|
// myOpacityBlue = (myOpacityBlue1*Weight1) + (myOpacityBlue2*Weight2);
|
|
// //
|
|
// // Reset the target material and std::flush it
|
|
// //
|
|
// dpl_SetMaterialAmbient (myMaterial, myAmbientRed, myAmbientGreen, myAmbientBlue);
|
|
// dpl_SetMaterialEmissive (myMaterial, myEmissiveRed, myEmissiveGreen, myEmissiveBlue);
|
|
// dpl_SetMaterialDiffuse (myMaterial, myDiffuseRed, myDiffuseGreen, myDiffuseBlue);
|
|
// dpl_SetMaterialSpecular (myMaterial, mySpecularRed, mySpecularGreen, mySpecularBlue, mySpecularShininess);
|
|
//// dpl_SetMaterialOpacity (myMaterial, myOpacityRed, myOpacityGreen, myOpacityBlue);
|
|
// dpl_FlushMaterial(myMaterial);
|
|
// }
|
|
// // Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~End of the new renderable class hiearchy~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~Dynamic Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~these renderables allow things to change after construction~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//#############################################################################
|
|
// This is the DPLEyeRenderable class. This is a DYNAMIC renderable that
|
|
// places the renderer's eyepoint relative to some other DCS/renderable.
|
|
// At the moment the eyepoint won't actually move in response to an argument
|
|
// but this will be changed after we have something to hook the eye to.
|
|
//#############################################################################
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the DPLEyeRenderable
|
|
// All the arguments are required.
|
|
//
|
|
DPLEyeRenderable::DPLEyeRenderable(
|
|
Entity* This_Entity,
|
|
const LinearMatrix& Offset_Matrix,
|
|
HierarchicalDrawComponent* parent,
|
|
EulerAngles* eyepoint_rotation // Pointer to attribute that contains eye rotations
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, parent)
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check the inbound data
|
|
// //
|
|
Check(This_Entity);
|
|
Check(&Offset_Matrix);
|
|
Check_Pointer(Parent_DCS);
|
|
#if DEBUG_LEVEL > 0
|
|
if(eyepoint_rotation)
|
|
Check(eyepoint_rotation);
|
|
#endif
|
|
//
|
|
// Remember the entity that this renderable is attached to and the
|
|
// orientation matrix that sets the eye location
|
|
//
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
myOrientationMatrix = Offset_Matrix;
|
|
myEyepointRotation = eyepoint_rotation;
|
|
if(myEyepointRotation)
|
|
{
|
|
oldEyepointRotation = *myEyepointRotation;
|
|
}
|
|
else
|
|
{
|
|
oldEyepointRotation = NULL;
|
|
}
|
|
//
|
|
// Create the dpl DCS for this renderable, connect it to it's parent
|
|
// and set it into the current zone.
|
|
//
|
|
// myDCS = dpl_NewDCS ();
|
|
// Check_Pointer(myDCS);
|
|
// dpl_AddDCSToDCS ( myParentDCS, myDCS );
|
|
// dpl_SetDCSZone ( myDCS, This_Zone );
|
|
//
|
|
// Load up the DCS matrix with the supplied matrix
|
|
//
|
|
// float32* dplMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer(dplMatrix);
|
|
// *((Matrix4x4*)dplMatrix) = rotation_matrix;
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer(tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = OrientationMatrix;
|
|
//
|
|
// Flush out the instance and DCS
|
|
//
|
|
// dpl_SetViewDCS ( This_View, myDCS);
|
|
// dpl_FlushView ( This_View);
|
|
// dpl_FlushDCS ( myDCS );
|
|
|
|
// myEntity->AddDynamicVideoComponent(this);
|
|
//
|
|
// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
//
|
|
// myEntity->AddStaticVideoComponent(this);
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
//l4_application->GetVideoRenderer()->mDeathRenderables.Add(this);
|
|
myDevice = l4_application->GetVideoRenderer()->GetDevice();
|
|
|
|
camMatrix = myOrientationMatrix;
|
|
if (myEyepointRotation)
|
|
{
|
|
Matrix4x4 rotation;
|
|
rotation = *myEyepointRotation;
|
|
//camMatrix.entries[14] /= 1.1f;
|
|
camMatrix *= rotation;
|
|
}
|
|
|
|
Matrix4x4 mat4;
|
|
mat4 = camMatrix;
|
|
Matrix4x4 prev;
|
|
prev = *myRenderer->GetMatrixStack()->GetTop();
|
|
mat4 *= prev;
|
|
LinearMatrix mat(True);
|
|
mat = mat4;
|
|
|
|
D3DXVECTOR3 pos(mat(3,0), mat(3, 1), mat(3,2));
|
|
mat(3,0) = 0;
|
|
mat(3,1) = 0;
|
|
mat(3,2) = 0;
|
|
|
|
Matrix4x4 temp;
|
|
temp = mat;
|
|
D3DXMATRIX drot = temp.ToD3DMatrix();
|
|
D3DXVECTOR3 at(0,0,1);
|
|
D3DXVECTOR3 up(0,1,0);
|
|
|
|
at.x = drot._31 + drot._41;
|
|
at.y = drot._32 + drot._42;
|
|
at.z = drot._33 + drot._43;
|
|
at += pos;
|
|
|
|
up.x = drot._21 + drot._41;
|
|
up.y = drot._22 + drot._42;
|
|
up.z = drot._23 + drot._43;
|
|
|
|
//D3DXVECTOR3 dir;
|
|
//D3DXVec3Subtract(&dir,&at, &pos);
|
|
//D3DXVec3Normalize(&dir, &dir);
|
|
//D3DXVec3Scale(&dir, &dir, 50);
|
|
//D3DXVec3Subtract(&pos, &pos, &dir);
|
|
|
|
// AUTHENTIC VIEW = inverse(eyeWorld) (decomp FUN_004c22c4 @part_013.c:11788,
|
|
// FUN_0040b244 = affine inverse) -- NOT a LookAt with a hand-picked forward axis.
|
|
// The look/up axes fall out of the eye's OWN basis via the inverse, so every mech
|
|
// aims out the windshield regardless of its siteeyepoint axis convention (the old
|
|
// +Z-forward/+Y-up LookAt guess is why the view aimed into the canopy for some
|
|
// mechs). mat4 = eyeLocal * parentWorld = the eye WORLD matrix; pos/at/up are
|
|
// retained only for the aim-boresight feed below.
|
|
D3DXMATRIX eyeW = mat4.ToD3DMatrix();
|
|
D3DXMATRIX view;
|
|
D3DXMatrixInverse(&view, NULL, &eyeW);
|
|
|
|
//myDevice->SetTransform(D3DTS_VIEW, &view);
|
|
|
|
oldLocalToWorld = myEntity->localToWorld;
|
|
mForceUpdate = true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLEyeRenderable
|
|
// After calling this the eyepoint must be relocated to another DCS before
|
|
// the execute method of the renderer is called.
|
|
//
|
|
DPLEyeRenderable::~DPLEyeRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
//// Below is probably unnecessary as the parent should be destroyed too
|
|
//// but Phil is making a patch to allow us to check that.
|
|
//// dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
// dpl_DeleteDCS(myDCS);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLEyeRenderable
|
|
//
|
|
Logical
|
|
DPLEyeRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer(myDCS);
|
|
Check_Pointer(myParentDCS);
|
|
Check(&myOrientationMatrix);
|
|
Check(myEntity);
|
|
if(myEyepointRotation)
|
|
{
|
|
Check(myEyepointRotation);
|
|
}
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLEyeRenderable.
|
|
//
|
|
void
|
|
DPLEyeRenderable::Execute()
|
|
{
|
|
static int dbgEyeExec = 0;
|
|
if (dbgEyeExec < 8)
|
|
{
|
|
DEBUG_STREAM << "[EYE] Execute called #" << dbgEyeExec
|
|
<< " entityL2W.t=(" << myEntity->localToWorld(3,0) << ","
|
|
<< myEntity->localToWorld(3,1) << "," << myEntity->localToWorld(3,2) << ")\n" << std::flush;
|
|
}
|
|
//STUBBED: DPL RB 1/14/07
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// If we have an eyepoint rotation specified, generate a new matrix each
|
|
// time based upon the setting of the eyepoint rotation
|
|
//----------------------------------------------------------------------
|
|
//
|
|
static float s_oldEyeBob = 0.0f;
|
|
static float s_oldEyeSway = 0.0f;
|
|
// BT fix (task #15 pivot/stutter): the change-detection gate fired only ~8
|
|
// times in 16s of constant motion (the LinearMatrix comparison is
|
|
// insensitive), so the camera updated in occasional discrete jumps -- view
|
|
// stutter while moving, and during a stationary turn the camera HELD its
|
|
// stale pose while the mech yawed ("the mech dances a circle around the
|
|
// camera"). The view compose is one matrix multiply + LookAt: recompute
|
|
// EVERY frame.
|
|
if (true)
|
|
{
|
|
mForceUpdate = false;
|
|
s_oldEyeBob = gBTEyeBobY;
|
|
s_oldEyeSway = gBTEyeSwayX;
|
|
oldLocalToWorld = myEntity->localToWorld;
|
|
|
|
// AUTHENTIC combine order (decomp FUN_004579a8 @part_007.c:9305-9316):
|
|
// eyeLocal = baseOffset(myOrientationMatrix) * R(EyepointRotation), R applied
|
|
// FIRST in the eye's own local space. (Was R * Orient -- inverted.)
|
|
camMatrix = myOrientationMatrix;
|
|
if (myEyepointRotation)
|
|
{
|
|
oldEyepointRotation = *myEyepointRotation;
|
|
Matrix4x4 rotation; rotation = *myEyepointRotation;
|
|
camMatrix *= rotation;
|
|
}
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
Matrix4x4 mat4;
|
|
mat4 = camMatrix;
|
|
Matrix4x4 prev;
|
|
prev = *myRenderer->GetMatrixStack()->GetTop();
|
|
mat4 *= prev;
|
|
LinearMatrix mat(True);
|
|
mat = mat4;
|
|
|
|
D3DXVECTOR3 pos(mat(3,0), mat(3, 1), mat(3,2));
|
|
mat(3,0) = 0;
|
|
mat(3,1) = 0;
|
|
mat(3,2) = 0;
|
|
|
|
Matrix4x4 temp;
|
|
temp = mat;
|
|
D3DXMATRIX drot = temp.ToD3DMatrix();
|
|
D3DXVECTOR3 at(0,0,1);
|
|
D3DXVECTOR3 up(0,1,0);
|
|
|
|
at.x = drot._31 + drot._41;
|
|
at.y = drot._32 + drot._42;
|
|
at.z = drot._33 + drot._43;
|
|
at += pos;
|
|
|
|
up.x = drot._21 + drot._41;
|
|
up.y = drot._22 + drot._42;
|
|
up.z = drot._23 + drot._43;
|
|
|
|
//D3DXVECTOR3 dir;
|
|
//D3DXVec3Subtract(&dir,&at, &pos);
|
|
//D3DXVec3Normalize(&dir, &dir);
|
|
//D3DXVec3Scale(&dir, &dir, 10.0f);
|
|
//D3DXVec3Add(&pos, &pos, &dir);
|
|
//D3DXVec3Add(&pos, &pos, &(D3DXVECTOR3(0, 0.15f, 0)));
|
|
//D3DXVec3Add(&at, &pos,&( D3DXVECTOR3(0, 0, 1)));
|
|
|
|
//
|
|
// BT bring-up (task #15/#20): cockpit BOB. The leg gait channel writes
|
|
// the clip's vertical root motion into the root joint every frame, but
|
|
// this camera's DCS chain does not consume animated joints (the
|
|
// authentic path is the gyro-driven eye-joint chain -- deferred), so
|
|
// the view rode at a constant height and the walk read as a glide.
|
|
// mech4.cpp publishes the player's live root-bob offset here.
|
|
//
|
|
pos.y += gBTEyeBobY;
|
|
at.y += gBTEyeBobY;
|
|
// Lateral sway along the camera's RIGHT vector (rotation row 0) --
|
|
// the stride's side-to-side weight shift.
|
|
pos.x += drot._11 * gBTEyeSwayX; pos.z += drot._13 * gBTEyeSwayX;
|
|
at.x += drot._11 * gBTEyeSwayX; at.z += drot._13 * gBTEyeSwayX;
|
|
|
|
// AUTHENTIC VIEW = inverse(eyeWorld) (decomp FUN_004c22c4 @part_013.c:11788, affine
|
|
// inverse FUN_0040b244) -- the live per-frame path. Replaces the hand-rolled LookAt
|
|
// that assumed +Z=forward/+Y=up (which mis-framed the cockpit); the look/up axes now
|
|
// fall out of the eye's own basis. pos/at/up above are kept only for the aim-boresight.
|
|
D3DXMATRIX eyeW = mat4.ToD3DMatrix();
|
|
D3DXMATRIX view;
|
|
D3DXMatrixInverse(&view, NULL, &eyeW);
|
|
|
|
// EYE POSITION CHECK + 'too far back' diagnostic (task #55).
|
|
D3DXVECTOR3 eyeFwdW(-view._13, -view._23, -view._33); // D3D view -Z = world look dir
|
|
{
|
|
const char *ef = getenv("BT_EYE_FWD"); // push eye forward k units along its look dir
|
|
if (ef && *ef && myRenderer->mCamera == this)
|
|
{
|
|
float k = (float)atof(ef);
|
|
eyeW._41 += k*eyeFwdW.x; eyeW._42 += k*eyeFwdW.y; eyeW._43 += k*eyeFwdW.z;
|
|
D3DXMatrixInverse(&view, NULL, &eyeW);
|
|
}
|
|
}
|
|
if (dbgEyeExec < 8)
|
|
{
|
|
DEBUG_STREAM << "[EYECHK] eyeW=(" << eyeW._41 << "," << eyeW._42 << "," << eyeW._43
|
|
<< ") fwd=(" << eyeFwdW.x << "," << eyeFwdW.y << "," << eyeFwdW.z
|
|
<< ") ent=(" << myEntity->localToWorld(3,0) << "," << myEntity->localToWorld(3,1)
|
|
<< "," << myEntity->localToWorld(3,2) << ")\n" << std::flush;
|
|
++dbgEyeExec;
|
|
}
|
|
|
|
// Only the ACTIVE camera writes the view: the BT view toggle builds
|
|
// BOTH the cockpit and chase eyes; an unconditional write here let
|
|
// whichever eye executed LAST stomp the toggled camera every frame.
|
|
if (myRenderer->mCamera == this)
|
|
{
|
|
myDevice->SetTransform(D3DTS_VIEW, &view);
|
|
|
|
if (dbgEyeExec < 8)
|
|
DEBUG_STREAM << "[EYE] ACTIVE eye " << (void *)this
|
|
<< " (mCamera match) pos.y=" << pos.y << "\n" << std::flush;
|
|
|
|
// aim-ray feed (task #36): publish this eye's world pose --
|
|
// the LookAtRH basis (zaxis = back, view direction = -zaxis)
|
|
// -- for the reticle pick ray / designator projection.
|
|
{
|
|
extern void BTSetAimCamera(const float pos[3], const float xax[3],
|
|
const float yax[3], const float zax[3]);
|
|
// AIM BORESIGHT (task #48): the guns fire along the mech's
|
|
// GYRO-STABILIZED horizontal heading, NOT the terrain-pitched
|
|
// body/eye. Publishing the raw eye basis made a mech standing
|
|
// on a slope (body pitched ~8 deg to conform to the ground) aim
|
|
// its pick ray INTO the ground, short of a distant target
|
|
// (mechPicks=0). Level the boresight: drop the view direction's
|
|
// pitch and rebuild an upright basis (world +Y up). The reticle
|
|
// X still carries the torso twist (BTTwistToReticleX); the reticle
|
|
// Y carries any aim elevation. Falls back to the raw basis only
|
|
// if the view is (degenerately) near-vertical.
|
|
// Derive the boresight from the AUTHORITATIVE view matrix
|
|
// (eyeFwdW = the world look direction from the inverse view),
|
|
// not the old LookAt at/pos rows -- those assumed row2=look,
|
|
// which the authentic inverse-view convention inverted (task
|
|
// #56 follow-through; the stale rows aimed the pick ray at
|
|
// the sky = no target, no discharge).
|
|
D3DXVECTOR3 zax = -eyeFwdW; // back = -look
|
|
D3DXVec3Normalize(&zax, &zax);
|
|
D3DXVECTOR3 xax;
|
|
D3DXVECTOR3 yax;
|
|
D3DXVECTOR3 fwdLevel(eyeFwdW.x, 0.0f, eyeFwdW.z);
|
|
if (D3DXVec3LengthSq(&fwdLevel) > 1e-6f)
|
|
{
|
|
D3DXVec3Normalize(&fwdLevel, &fwdLevel);
|
|
zax = D3DXVECTOR3(-fwdLevel.x, 0.0f, -fwdLevel.z); // back = -level fwd
|
|
D3DXVECTOR3 wup(0.0f, 1.0f, 0.0f);
|
|
D3DXVec3Cross(&xax, &wup, &zax);
|
|
D3DXVec3Normalize(&xax, &xax);
|
|
D3DXVec3Cross(&yax, &zax, &xax); // == world +Y
|
|
}
|
|
else
|
|
{
|
|
D3DXVec3Cross(&xax, &up, &zax);
|
|
D3DXVec3Normalize(&xax, &xax);
|
|
D3DXVec3Cross(&yax, &zax, &xax);
|
|
}
|
|
// ORIGIN: the guns fire from the MECH's torso, not the render
|
|
// eye. In CHASE view the eye sits behind+above the mech, so a
|
|
// ray from `pos` would start over the shoulder (and, being level,
|
|
// fly above a ground target). Anchor the boresight at the mech's
|
|
// XZ + a torso/gun height so the pick works in BOTH views (chase
|
|
// is the default; cockpit toggles with V). In cockpit view this
|
|
// is ~the eyepoint anyway.
|
|
float p[3] = { pos.x, pos.y, pos.z };
|
|
if (myEntity != 0)
|
|
{
|
|
p[0] = myEntity->localToWorld(3,0);
|
|
p[1] = myEntity->localToWorld(3,1) + 5.0f; // feet -> torso/gun height
|
|
p[2] = myEntity->localToWorld(3,2);
|
|
}
|
|
const float x3[3] = { xax.x, xax.y, xax.z };
|
|
const float y3[3] = { yax.x, yax.y, yax.z };
|
|
const float z3[3] = { zax.x, zax.y, zax.z };
|
|
BTSetAimCamera(p, x3, y3, z3);
|
|
}
|
|
}
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
else if (dbgEyeExec < 8)
|
|
{
|
|
DEBUG_STREAM << "[EYE] (no view update this call)\n" << std::flush;
|
|
++dbgEyeExec;
|
|
}
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&camMatrix.ToD3DMatrix());
|
|
HierarchicalDrawComponent::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// This is the DPLChildPointRenderable class. This is a dynamic renderable that
|
|
// lets you build a translating joint between two objects. If you supply a
|
|
// NULL Graphic_Object pointer when constructing the renderable it will be
|
|
// built without hooking up an instance of a graphical object.
|
|
//#############################################################################
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the DPLChildPointRenderable
|
|
//
|
|
DPLChildPointRenderable::DPLChildPointRenderable(
|
|
Entity* This_Entity,
|
|
bool isDeathZone,
|
|
d3d_OBJECT* Graphic_Object,
|
|
dpl_ISECT_MODE Intersect_Mode,
|
|
uint32 Intersect_Mask,
|
|
const LinearMatrix &Offset_Matrix,
|
|
HierarchicalDrawComponent *Parent,
|
|
Point3D *my_point
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
//
|
|
// Check the inbound data
|
|
//
|
|
Check(This_Entity);
|
|
Check_Pointer(This_Zone);
|
|
#if DEBUG_LEVEL > 0
|
|
if(Graphic_Object != NULL)
|
|
Check_Pointer(Graphic_Object);
|
|
#endif
|
|
Check(&Offset_Matrix);
|
|
//Check_Pointer(Parent_DCS);
|
|
Check(my_point);
|
|
//
|
|
// Remember the entity that this renderable is attached to and the
|
|
// orientation matrix that sets the eye location
|
|
//
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
myPoint = my_point;
|
|
OrientationMatrix = Offset_Matrix;
|
|
OldPoint = *my_point;
|
|
//
|
|
// Create the dpl DCS, add it to the parent DCS, set it into the current zone,
|
|
// and stuff the orientation matrix into it
|
|
//
|
|
// myOffsetDCS = dpl_NewDCS();
|
|
//Check_Pointer ( myOffsetDCS );
|
|
// dpl_AddDCSToDCS ( myParentDCS, myOffsetDCS );
|
|
// dpl_SetDCSZone ( myOffsetDCS, This_Zone );
|
|
|
|
// myDCS = dpl_NewDCS();
|
|
Check_Pointer ( myDCS );
|
|
// dpl_AddDCSToDCS ( myOffsetDCS, myDCS );
|
|
// dpl_SetDCSZone ( myDCS, This_Zone );
|
|
//
|
|
// Setup the offset matrix in the offset DCS
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myOffsetDCS );
|
|
Check_Pointer ( tempMatrix );
|
|
// *(Matrix4x4*)tempMatrix = OrientationMatrix;
|
|
//
|
|
// Setup the initial state of the hinge joint
|
|
//
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
// *(Matrix4x4*)tempMatrix2 = *myPoint;
|
|
//
|
|
// If there was a graphic, create an instance with that graphic in it and link
|
|
// it to the DCS.
|
|
//
|
|
graphicalObject = Graphic_Object;
|
|
Matrix4x4 temp,temp2;
|
|
temp = OrientationMatrix;
|
|
temp2 = *myPoint;
|
|
temp *= temp2;
|
|
HierarchicalDrawComponent::SetLocalToWorld(&temp.ToD3DMatrix());
|
|
//if(Graphic_Object == NULL)
|
|
//{
|
|
// graphicalObject = myObject;
|
|
//}
|
|
//else
|
|
//{
|
|
// myInstance = dpl_NewInstance();
|
|
//Check_Pointer ( myInstance );
|
|
// dpl_SetInstanceObject ( myInstance, Graphic_Object );
|
|
// dpl_SetInstanceIntersect ( myInstance, Intersect_Mode );
|
|
// dpl_SetInstanceSectMask ( myInstance, Intersect_Mask );
|
|
// dpl_SetInstanceVisibility ( myInstance, 1 );
|
|
// dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
// dpl_FlushInstance ( myInstance );
|
|
//}
|
|
//
|
|
// Flush out the DCS and add this to the static component list
|
|
//
|
|
// dpl_FlushDCS ( myOffsetDCS );
|
|
// dpl_FlushDCS ( myDCS );
|
|
// myEntity->AddDynamicVideoComponent(this);
|
|
//
|
|
// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
myEntity->AddStaticVideoComponent(this);
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
//l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the DPLChildPointRenderable
|
|
//
|
|
|
|
DPLChildPointRenderable::~DPLChildPointRenderable()
|
|
{
|
|
// Check(this);
|
|
//// Below is probably unnecessary as the parent should be destroyed too
|
|
//// but Phil is making a patch to allow us to check that.
|
|
//// dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
//
|
|
// dpl_DeleteDCS(myDCS);
|
|
// dpl_DeleteDCS(myOffsetDCS);
|
|
// if(myInstance != NULL)
|
|
// {
|
|
// dpl_DeleteInstance(myInstance);
|
|
// }
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLChildPointRenderable
|
|
// This method should really use a watcher to make sure the position of the
|
|
// object has changed before updating the DCS matrix.
|
|
//
|
|
void
|
|
DPLChildPointRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
////
|
|
//// Load up the DCS matrix with the localToWorld matrix from the entity
|
|
//// then std::flush out the new DCS
|
|
////
|
|
// if(OldPoint != *myPoint)
|
|
// {
|
|
// OldPoint = *myPoint;
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
// *(Matrix4x4*)tempMatrix2 = OldPoint;
|
|
// HACK_DPL_FLUSH_DCS ( myDCS );
|
|
// }
|
|
|
|
myRenderer->GetMatrixStack()->Push();
|
|
Matrix4x4 temp,temp2;
|
|
temp = OrientationMatrix;
|
|
temp2 = *myPoint;
|
|
temp *= temp2;
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&temp.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
HierarchicalDrawComponent::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLChildPointRenderable
|
|
//
|
|
Logical
|
|
DPLChildPointRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer ( myDCS );
|
|
Check_Pointer ( myParentDCS );
|
|
Check_Pointer ( myOffsetDCS );
|
|
Check(myPoint);
|
|
if(myInstance != NULL)
|
|
{
|
|
Check_Pointer(myInstance);
|
|
}
|
|
Check(&OrientationMatrix);
|
|
Check(myEntity);
|
|
|
|
return True;
|
|
}
|
|
//
|
|
//#############################################################################
|
|
// This is the DPLScaleRenderable class. This is a dynamic renderable that
|
|
// lets you scale everything downstream of it in the hiearchy. It is also
|
|
// setup to switch it's own instances on and off based on the value in visible.
|
|
//#############################################################################
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the DPLScaleRenderable
|
|
//
|
|
DPLScaleRenderable::DPLScaleRenderable(
|
|
Entity* This_Entity,
|
|
bool isDeathZone,
|
|
d3d_OBJECT* Graphic_Object,
|
|
dpl_ISECT_MODE Intersect_Mode,
|
|
uint32 Intersect_Mask,
|
|
const LinearMatrix &Offset_Matrix,
|
|
HierarchicalDrawComponent *Parent,
|
|
Vector3D *scale_vector,
|
|
Logical *visible
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check the inbound data
|
|
////
|
|
// Check(This_Entity);
|
|
// Check_Pointer(This_Zone);
|
|
// Check_Pointer(Graphic_Object);
|
|
// Check(&Offset_Matrix);
|
|
// Check_Pointer(Parent_DCS);
|
|
// Check(scale_vector);
|
|
// Check_Pointer(visible);
|
|
////
|
|
//// Remember the entity that this renderable is attached to and the
|
|
//// orientation matrix that offsets it to the correct position.
|
|
////
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
myScaleVector = scale_vector;
|
|
myVisible = visible;
|
|
OffsetMatrix = Offset_Matrix;
|
|
OldScaleVector = *scale_vector;
|
|
OldVisible = *visible;
|
|
myObject = Graphic_Object;
|
|
////
|
|
//// Create the dpl DCS, add it to the parent DCS, set it into the current zone,
|
|
//// and stuff the orientation matrix into it
|
|
////
|
|
// myDCS = dpl_NewDCS();
|
|
// Check_Pointer ( myDCS );
|
|
// dpl_AddDCSToDCS ( myParentDCS, myDCS );
|
|
// dpl_SetDCSZone ( myDCS, This_Zone );
|
|
//
|
|
// Setup the dcs matrix to it's initial state
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine *= OldScaleVector;
|
|
tempAffine *= OffsetMatrix;
|
|
transMatrix = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
////
|
|
//// If there was a graphic, create an instance with that graphic in it and link
|
|
//// it to the DCS.
|
|
////
|
|
// myInstance = dpl_NewInstance();
|
|
// Check_Pointer ( myInstance );
|
|
// dpl_SetInstanceObject ( myInstance, Graphic_Object );
|
|
// dpl_SetInstanceIntersect ( myInstance, Intersect_Mode );
|
|
// dpl_SetInstanceSectMask ( myInstance, Intersect_Mask );
|
|
// dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
// dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
// dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Flush out the DCS and add this to the static component list
|
|
////
|
|
// dpl_FlushDCS ( myDCS );
|
|
//// myEntity->AddDynamicVideoComponent(this);
|
|
////
|
|
//// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
// myEntity->AddStaticVideoComponent(this);
|
|
// L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the DPLScaleRenderable
|
|
//
|
|
|
|
DPLScaleRenderable::~DPLScaleRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
//// Below is probably unnecessary as the parent should be destroyed too
|
|
//// but Phil is making a patch to allow us to check that.
|
|
//// dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
//
|
|
// dpl_DeleteDCS(myDCS);
|
|
// dpl_DeleteInstance(myInstance);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLScaleRenderable
|
|
// This method should really use a watcher to make sure the position of the
|
|
// object has changed before updating the DCS matrix.
|
|
//
|
|
void
|
|
DPLScaleRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
//
|
|
// Load up the DCS matrix with the localToWorld matrix from the entity
|
|
// then std::flush out the new DCS
|
|
//
|
|
if(OldVisible != *myVisible)
|
|
{
|
|
OldVisible = *myVisible;
|
|
// dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
// dpl_FlushInstance ( myInstance );
|
|
}
|
|
|
|
if(OldScaleVector != *myScaleVector)
|
|
{
|
|
OldScaleVector = *myScaleVector;
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine *= OldScaleVector;
|
|
tempAffine *= OffsetMatrix;
|
|
transMatrix = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// HACK_DPL_FLUSH_DCS ( myDCS );
|
|
}
|
|
|
|
if (!(*myVisible))
|
|
{
|
|
graphicalObject = NULL;
|
|
} else
|
|
{
|
|
graphicalObject = myObject;
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&transMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
HierarchicalDrawComponent::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLChildRenderable
|
|
//
|
|
Logical
|
|
DPLScaleRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer ( myDCS );
|
|
Check_Pointer ( myParentDCS );
|
|
Check_Pointer(myInstance);
|
|
Check(&OffsetMatrix);
|
|
Check(myEntity);
|
|
Check(myScaleVector);
|
|
|
|
return True;
|
|
}
|
|
//
|
|
//#############################################################################
|
|
// This is the DPLScaleQuatRenderable class. This is a dynamic renderable that
|
|
// lets you control joint position with a Quaternion, Scale with a vector and
|
|
// switch the instance on and off with a logical.
|
|
//#############################################################################
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the DPLScaleQuatRenderable
|
|
//
|
|
DPLScaleQuatRenderable::DPLScaleQuatRenderable(
|
|
Entity* This_Entity,
|
|
bool isDeathZone,
|
|
d3d_OBJECT* Graphic_Object,
|
|
dpl_ISECT_MODE Intersect_Mode,
|
|
uint32 Intersect_Mask,
|
|
const LinearMatrix &Offset_Matrix,
|
|
HierarchicalDrawComponent *Parent,
|
|
Quaternion *rotation_quaternion,
|
|
Vector3D *scale_vector,
|
|
Logical *visible
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
Quaternion my_quat;
|
|
////
|
|
//// Check the inbound data
|
|
////
|
|
// Check(This_Entity);
|
|
// Check_Pointer(This_Zone);
|
|
// Check_Pointer(Graphic_Object);
|
|
// Check(&Offset_Matrix);
|
|
// Check_Pointer(Parent_DCS);
|
|
// Check(rotation_quaternion);
|
|
// Check(scale_vector);
|
|
// Check_Pointer(visible);
|
|
//
|
|
// Remember the entity that this renderable is attached to and the
|
|
// orientation matrix that offsets it to the correct position.
|
|
//
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
myRotationQuaternion = rotation_quaternion;
|
|
myScaleVector = scale_vector;
|
|
myVisible = visible;
|
|
OffsetMatrix = Offset_Matrix;
|
|
OldRotationQuaternion = *rotation_quaternion;
|
|
OldScaleVector = *scale_vector;
|
|
OldVisible = *visible;
|
|
myObject = Graphic_Object;
|
|
////
|
|
//// Create the dpl DCS, add it to the parent DCS, set it into the current zone,
|
|
//// and stuff the orientation matrix into it
|
|
////
|
|
// myDCS = dpl_NewDCS();
|
|
// Check_Pointer ( myDCS );
|
|
// dpl_AddDCSToDCS ( myParentDCS, myDCS );
|
|
// dpl_SetDCSZone ( myDCS, This_Zone );
|
|
//
|
|
// Setup the dcs matrix to it's initial state
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
AffineMatrix tempAffine(True);
|
|
// tempAffine.Multiply(OldRotationQuaternion,OffsetMatrix);
|
|
tempAffine *= OldScaleVector;
|
|
tempAffine *= OldRotationQuaternion;
|
|
tempAffine *= OffsetMatrix;
|
|
tempMatrix = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
////
|
|
//// If there was a graphic, create an instance with that graphic in it and link
|
|
//// it to the DCS.
|
|
////
|
|
// myInstance = dpl_NewInstance();
|
|
// Check_Pointer ( myInstance );
|
|
// dpl_SetInstanceObject ( myInstance, Graphic_Object );
|
|
// dpl_SetInstanceIntersect ( myInstance, Intersect_Mode );
|
|
// dpl_SetInstanceSectMask ( myInstance, Intersect_Mask );
|
|
// dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
// dpl_AddInstanceToDCS ( myDCS, myInstance );
|
|
// dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Flush out the DCS and add this to the static component list
|
|
////
|
|
// dpl_FlushDCS ( myDCS );
|
|
//// myEntity->AddDynamicVideoComponent(this);
|
|
////
|
|
//// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
// myEntity->AddStaticVideoComponent(this);
|
|
// L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the DPLScaleQuatRenderable
|
|
//
|
|
|
|
DPLScaleQuatRenderable::~DPLScaleQuatRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
//// Below is probably unnecessary as the parent should be destroyed too
|
|
//// but Phil is making a patch to allow us to check that.
|
|
//// dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
//
|
|
// dpl_DeleteDCS(myDCS);
|
|
// dpl_DeleteInstance(myInstance);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the DPLScaleQuatRenderable
|
|
// This method should really use a watcher to make sure the position of the
|
|
// object has changed before updating the DCS matrix.
|
|
//
|
|
void
|
|
DPLScaleQuatRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
Check(this);
|
|
//
|
|
// Load up the DCS matrix with the localToWorld matrix from the entity
|
|
// then std::flush out the new DCS
|
|
//
|
|
if(OldVisible != *myVisible)
|
|
{
|
|
OldVisible = *myVisible;
|
|
// dpl_SetInstanceVisibility ( myInstance, OldVisible );
|
|
// dpl_FlushInstance ( myInstance );
|
|
}
|
|
|
|
//
|
|
// The memcmp below is sort of a HACK but all I really care about is if the
|
|
// value in the quaternion has been changed since last time I saw it, this
|
|
// seems to be the easiest way to find out as JM hasn't written an == operator
|
|
//
|
|
if((OldScaleVector != *myScaleVector) ||
|
|
(memcmp(&OldRotationQuaternion,myRotationQuaternion, sizeof(Quaternion)) != 0))
|
|
{
|
|
OldScaleVector = *myScaleVector;
|
|
OldRotationQuaternion = *myRotationQuaternion;
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
AffineMatrix tempAffine(True);
|
|
// tempAffine.Multiply(OldRotationQuaternion,OffsetMatrix);
|
|
tempAffine *= OldScaleVector;
|
|
tempAffine *= OldRotationQuaternion;
|
|
tempAffine *= OffsetMatrix;
|
|
tempMatrix = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// HACK_DPL_FLUSH_DCS ( myDCS );
|
|
}
|
|
|
|
if (!(*myVisible))
|
|
{
|
|
graphicalObject = NULL;
|
|
} else
|
|
{
|
|
graphicalObject = myObject;
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&tempMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
HierarchicalDrawComponent::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLScaleQuatRenderable
|
|
//
|
|
Logical
|
|
DPLScaleQuatRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer ( myDCS );
|
|
Check_Pointer ( myParentDCS );
|
|
Check_Pointer(myInstance);
|
|
Check(&OffsetMatrix);
|
|
Check(myEntity);
|
|
Check(myRotationQuaternion);
|
|
Check(myScaleVector);
|
|
Check_Pointer(myVisible);
|
|
|
|
return True;
|
|
}
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~Static Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~these renderables remain constant after construction~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
//
|
|
//#############################################################################
|
|
// This is the DPLStaticChildRenderable class. This is a STATIC renderable that
|
|
// lets you build a DCS that is a child of a pre-existing DCS. If you supply a
|
|
// NULL Graphic_Object pointer when constructing the renderable it will be
|
|
// built without hooking up an instance of a graphical object.
|
|
//#############################################################################
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for the DPLStaticChildRenderable
|
|
//
|
|
DPLStaticChildRenderable::DPLStaticChildRenderable(
|
|
Entity* This_Entity,
|
|
bool isDeathZone,
|
|
d3d_OBJECT* Graphic_Object,
|
|
dpl_ISECT_MODE Intersect_Mode,
|
|
uint32 Intersect_Mask,
|
|
const LinearMatrix& Offset_Matrix,
|
|
HierarchicalDrawComponent* Parent
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
//
|
|
// Check the inbound data
|
|
//
|
|
Check(This_Entity);
|
|
Check_Pointer(This_Zone);
|
|
Check(&Offset_Matrix);
|
|
//Check_Pointer(Parent_DCS);
|
|
// #if DEBUG_LEVEL > 0
|
|
if(Graphic_Object != NULL)
|
|
Check_Pointer(Graphic_Object);
|
|
// #endif
|
|
//
|
|
// Remember the entity that this renderable is attached to and the
|
|
// orientation matrix that sets the eye location
|
|
//
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
OrientationMatrix = Offset_Matrix;
|
|
graphicalObject = Graphic_Object;
|
|
//
|
|
// Create the dpl DCS, add it to the parent DCS, set it into the current zone,
|
|
// and stuff the orientation matrix into it
|
|
//
|
|
// myDCS = dpl_NewDCS();
|
|
// Check_Pointer(myDCS);
|
|
// dpl_AddDCSToDCS( myParentDCS, myDCS);
|
|
// dpl_SetDCSZone(myDCS, This_Zone);
|
|
// float32* tempMatrix = dpl_GetDCSMatrix(myDCS);
|
|
// Check_Pointer(tempMatrix);
|
|
// *(Matrix4x4*)tempMatrix = OrientationMatrix;
|
|
//
|
|
// If there was a graphic, create an instance with that graphic in it and link
|
|
// it to the DCS.
|
|
//
|
|
if(Graphic_Object == NULL)
|
|
{
|
|
//myInstance = NULL;
|
|
}
|
|
else
|
|
{
|
|
// myInstance = dpl_NewInstance();
|
|
// Check_Pointer(myInstance );
|
|
// dpl_SetInstanceObject(myInstance, Graphic_Object);
|
|
// dpl_SetInstanceIntersect(myInstance, Intersect_Mode);
|
|
// dpl_SetInstanceSectMask(myInstance, Intersect_Mask);
|
|
// dpl_SetInstanceVisibility(myInstance, 1);
|
|
// dpl_AddInstanceToDCS(myDCS, myInstance);
|
|
// dpl_FlushInstance(myInstance);
|
|
}
|
|
//
|
|
// Flush out the DCS and add this to the static component list
|
|
//
|
|
// dpl_FlushDCS(myDCS);
|
|
//myEntity->AddStaticVideoComponent(this);
|
|
|
|
//L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
//Check(l4_application);
|
|
//l4_application->GetVideoRenderer()->mRenderables.Add(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for the DPLStaticChildRenderable
|
|
//
|
|
|
|
DPLStaticChildRenderable::~DPLStaticChildRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Check(this);
|
|
//// Below is probably unnecessary as the parent should be destroyed too
|
|
//// but Phil is making a patch to allow us to check that.
|
|
//// dpl_RemoveDCSFromDCS(myParentDCS, myDCS);
|
|
//
|
|
// dpl_DeleteDCS(myDCS);
|
|
// if(myInstance != NULL)
|
|
// {
|
|
// dpl_DeleteInstance(myInstance);
|
|
// }
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLStaticChildRenderable
|
|
//
|
|
Logical
|
|
DPLStaticChildRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check_Pointer(myDCS);
|
|
Check_Pointer(myParentDCS);
|
|
if(myInstance != NULL)
|
|
{
|
|
Check_Pointer(myInstance);
|
|
}
|
|
Check(&OrientationMatrix);
|
|
Check(myEntity);
|
|
|
|
return True;
|
|
}
|
|
|
|
void DPLStaticChildRenderable::Execute()
|
|
{
|
|
myRenderer->GetMatrixStack()->Push();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&OrientationMatrix.ToD3DMatrix());
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
HierarchicalDrawComponent::Execute();
|
|
|
|
//std::vector<HierarchicalDrawComponent *>::iterator iter = m_children.begin();
|
|
|
|
//while(iter != m_children.end())
|
|
//{
|
|
// (*iter)->Execute();
|
|
// iter++;
|
|
//}
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~Special Effects Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//#############################################################################
|
|
// This is the DPLSFXRenderable class. This renderable is used to trigger a
|
|
// special effect in the world. The effect can be relative to a DCS or can be
|
|
// positioned in world coordinants by passing NULL as Parent_DCS. The trigger
|
|
// is a specific attribute entering a specific state. The effect will be
|
|
// generated repeatedly till the trigger changes state.
|
|
//
|
|
// This renderable is useful for triggering one-shot effects like puffs of smoke
|
|
// from guns or for triggering effects that the renderer will automatically
|
|
// repeat on it's own.
|
|
//#############################################################################
|
|
#define DPLSFXRenderable_MAX_RATE 28.0 // Repeat rate when speed = 1.0
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLSFXRenderable
|
|
//
|
|
DPLSFXRenderable::DPLSFXRenderable(
|
|
Entity *This_Entity, // Entity to attach the effect to
|
|
bool isDeathZone , //*This_Zone, // DPL zone everything will be in
|
|
const Point3D &Offset_Point, // Point offset from the parent DCS
|
|
HierarchicalDrawComponent *Parent, // Parent DCS (can be NULL for world)
|
|
StateIndicator *Effect_Trigger, // Trigger effect when this state changes
|
|
int Trigger_State, // Trigger effect when in this state
|
|
int Effect_Type, // Type of effect to trigger
|
|
Scalar Repeat_Speed // Effect repeat speed.
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
Check(This_Entity);
|
|
// Check_Pointer(This_Zone);
|
|
Check(&Offset_Point);
|
|
#if DEBUG_LEVEL > 0
|
|
if(Parent_DCS != NULL)
|
|
Check_Pointer(Parent_DCS);
|
|
#endif
|
|
Check(Effect_Trigger);
|
|
//
|
|
// Remember the entity and DCS this renderable is attached to
|
|
//
|
|
myEntity = This_Entity;
|
|
//myParentDCS = Parent_DCS;
|
|
myOffsetPoint = Offset_Point;
|
|
myEffectTrigger = Effect_Trigger;
|
|
myEffectTriggerOld = myEffectTrigger->GetState();
|
|
myEffectTriggerState = Trigger_State;
|
|
myEffectType = Effect_Type;
|
|
mEmitter.SetEffect(myEffectType);
|
|
myRepeatSpeed = 1.0/(Repeat_Speed * DPLSFXRenderable_MAX_RATE);
|
|
myLastEffect = 0.0;
|
|
//
|
|
// Register this effect as a dynamic renderable of the entity
|
|
//
|
|
myEntity->AddDynamicVideoComponent(this);
|
|
//
|
|
// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
myEntity->AddStaticVideoComponent(this);
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLSFXRenderable
|
|
//
|
|
DPLSFXRenderable::~DPLSFXRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLSFXRenderable
|
|
//
|
|
Logical
|
|
DPLSFXRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check(myEntity);
|
|
#if DEBUG_LEVEL > 0
|
|
if(myParentDCS != NULL)
|
|
Check_Pointer(myParentDCS);
|
|
#endif
|
|
Check(&myOffsetPoint)
|
|
Check_Pointer(myEffectTrigger);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLSFXRenderable.
|
|
// This watches the pre-assigned attribute pointer and triggers a special effect
|
|
// whenever that attribute changes.
|
|
//
|
|
void
|
|
DPLSFXRenderable::Execute()
|
|
{
|
|
Scalar current_time;
|
|
|
|
Matrix4x4 mat;
|
|
mat = myEntity->localToWorld;
|
|
D3DXMATRIX transform = mat.ToD3DMatrix();
|
|
D3DXVECTOR4 v4;
|
|
D3DXVECTOR3 v3(myOffsetPoint.x, myOffsetPoint.y, myOffsetPoint.z);
|
|
D3DXVec3Transform(&v4, &v3, &transform);
|
|
|
|
mEmitter.SetPosition(v4.x, v4.y, v4.z);
|
|
|
|
mEmitter.Execute();
|
|
|
|
//
|
|
// Is the attribute in the trigger state?
|
|
//
|
|
if(myEffectTrigger->GetState() == myEffectTriggerState)
|
|
{
|
|
//
|
|
// The effect is on, see if this is an edge
|
|
//
|
|
if(myEffectTriggerOld != myEffectTrigger->GetState())
|
|
{
|
|
//
|
|
// An edge, reset the repeat timers so we will get an effect right now.
|
|
//
|
|
myLastEffect = 0.0;
|
|
}
|
|
//
|
|
// Is it time for another effect yet?
|
|
//
|
|
current_time = Now();
|
|
if((myLastEffect + myRepeatSpeed) < current_time)
|
|
{
|
|
//
|
|
// Trigger the effect
|
|
//
|
|
// dpl_EXPLOSION_EFFECT_INFO my_explosion;
|
|
// my_explosion.type = myEffectType;
|
|
// my_explosion.x = myOffsetPoint.x;
|
|
// my_explosion.y = myOffsetPoint.y;
|
|
// my_explosion.z = myOffsetPoint.z;
|
|
// dpl_Effect ( dpl_effect_type_explosion, myParentDCS, &my_explosion );
|
|
mEmitter.Fire();
|
|
myLastEffect = current_time;
|
|
}
|
|
}
|
|
myEffectTriggerOld = myEffectTrigger->GetState();
|
|
//HierarchicalDrawComponent::Execute();
|
|
}
|
|
//#############################################################################
|
|
// This is the DPLRepeatSFXRenderable class. This renderable is used to trigger
|
|
// a special effect that repeats periodically with the repeat rate under program
|
|
// control. The most common use will probably be generating smoke trails. If
|
|
// the density argument is set to zero, no smoke will be generated.
|
|
//#############################################################################
|
|
#define DPLRepeatSFXRenderable_MAX_RATE 30.0
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLRepeatSFXRenderable
|
|
//
|
|
DPLRepeatSFXRenderable::DPLRepeatSFXRenderable(
|
|
Entity *This_Entity,
|
|
bool isDeathZone , //*This_Zone,
|
|
const Point3D &Offset_Point,
|
|
HierarchicalDrawComponent *Parent, // offset is relative to this
|
|
int Effect_Type, // type code for the effect
|
|
Scalar *Speed
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID, Parent)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//
|
|
// Check the inbound data
|
|
//
|
|
Check(This_Entity);
|
|
// Check_Pointer(This_Zone);
|
|
Check(&Offset_Point);
|
|
#if DEBUG_LEVEL > 0
|
|
if(Parent_DCS != NULL)
|
|
Check_Pointer(Parent_DCS); // it is allowed to be null
|
|
#endif
|
|
Check_Pointer(Speed);
|
|
//
|
|
// Remember the entity and DCS this renderable is attached to
|
|
//
|
|
myEntity = This_Entity;
|
|
// myParentDCS = Parent_DCS;
|
|
myParent = Parent;
|
|
myOffsetPoint = Offset_Point;
|
|
myEffectType = Effect_Type;
|
|
mEmitter.SetEffect(myEffectType);
|
|
mySpeed = Speed;
|
|
myLastSmoke = 0.0;
|
|
mOldLocalToWorld = This_Entity->localToWorld;
|
|
mTransMatrix = This_Entity->localToWorld;
|
|
//
|
|
// Setup as a dynamic renderable
|
|
//
|
|
// myEntity->AddDynamicVideoComponent(this);
|
|
//
|
|
// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
myEntity->AddStaticVideoComponent(this);
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLRepeatSFXRenderable
|
|
//
|
|
DPLRepeatSFXRenderable::~DPLRepeatSFXRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLRepeatSFXRenderable
|
|
//
|
|
Logical
|
|
DPLRepeatSFXRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check(myEntity);
|
|
#if DEBUG_LEVEL > 0
|
|
if(myParentDCS != NULL)
|
|
Check_Pointer(myParentDCS); // it is allowed to be null
|
|
#endif
|
|
Check(&myOffsetPoint);
|
|
Check_Pointer(mySpeed);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLRepeatSFXRenderable.
|
|
// This watches the pre-assigned attribute pointer and triggers a special effect
|
|
// whenever that attribute changes.
|
|
//
|
|
void DPLRepeatSFXRenderable::Execute()
|
|
{
|
|
Scalar current_time = Now();
|
|
|
|
if(mOldLocalToWorld != myEntity->localToWorld)
|
|
{
|
|
mOldLocalToWorld = myEntity->localToWorld;
|
|
mTransMatrix = mOldLocalToWorld;
|
|
}
|
|
|
|
Matrix4x4 mat;
|
|
mat = myEntity->localToWorld;
|
|
D3DXMATRIX transform = mat.ToD3DMatrix();
|
|
D3DXVECTOR4 v4;
|
|
D3DXVECTOR3 v3(myOffsetPoint.x, myOffsetPoint.y, myOffsetPoint.z);
|
|
D3DXVec3Transform(&v4, &v3, &transform);
|
|
|
|
mEmitter.SetPosition(v4.x, v4.y, v4.z);
|
|
|
|
mEmitter.Execute();
|
|
|
|
// If speed is zero, the effect is turned off so we do nothing
|
|
if(*mySpeed == 0.0)
|
|
{
|
|
myLastSmoke = 0.0;
|
|
return;
|
|
}
|
|
|
|
// Figure how often we should generate smoke, speed ranges from 0 to 1, with
|
|
// 1 being the fastest
|
|
if((myLastSmoke + (1.0 / ((*mySpeed) * mEmitter.GetMaxRepeat()))) < current_time)
|
|
{
|
|
//dpl_EXPLOSION_EFFECT_INFO my_explosion;
|
|
myLastSmoke = current_time;
|
|
//my_explosion.type = myEffectType;
|
|
//my_explosion.x = myOffsetPoint.x;
|
|
//my_explosion.y = myOffsetPoint.y;
|
|
//my_explosion.z = myOffsetPoint.z;
|
|
//dpl_Effect(dpl_effect_type_explosion, myParentDCS, &my_explosion);
|
|
mEmitter.Fire();
|
|
}
|
|
//HierarchicalDrawComponent::Execute();
|
|
}
|
|
|
|
//#############################################################################
|
|
// This is the DPLTranslocationRenderable class. This renderable handles the
|
|
// entire process of doing a UFT translocation effect from the perspective of
|
|
// people watching the player. This renderable is connected to the player object
|
|
// and manages positioning itself in the world based on information from that
|
|
// object. HACK HACK HACK (this will be obsolete when RP is fixed)
|
|
//#############################################################################
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for DPLTranslocationRenderable
|
|
//
|
|
DPLTranslocationRenderable::DPLTranslocationRenderable(
|
|
Entity *This_Entity, // Entity to attach the effect to
|
|
bool isDeathZone, // DPL zone everything will be in
|
|
StateIndicator *Effect_Trigger, // Trigger effects off of this state dial
|
|
Point3D *Drop_Zone_Location, // Attribute that holds where the new drop will be
|
|
unsigned Drop_Zone_State
|
|
):
|
|
HierarchicalDrawComponent(TrivialNodeClassID)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check the inbound data, note that the parent DCS could be a null pointer
|
|
////
|
|
// Check(This_Entity);
|
|
// Check_Pointer(This_Zone);
|
|
// Check(Effect_Trigger);
|
|
// Check(Drop_Zone_Location);
|
|
////
|
|
//// Remember the entity and DCS this renderable is attached to
|
|
////
|
|
// myEntity = This_Entity;
|
|
// myZone = This_Zone;
|
|
// myEffectTrigger = Effect_Trigger;
|
|
// myEffectTriggerOld = myEffectTrigger->GetState();
|
|
// myDropZoneLocation = Drop_Zone_Location;
|
|
// myDropZoneState = Drop_Zone_State;
|
|
// myState = IdleState;
|
|
////
|
|
//// Load up the object we're going to use for the translocation
|
|
////
|
|
// dpl_OBJECT* myTranslocateSphere = dpl_LoadObject ( "tsphere", dpl_load_normal );
|
|
// Check_Pointer(myTranslocateSphere);
|
|
////
|
|
//// Setup a DCS that we can put the effect on so it can be rotated, scaled and
|
|
//// placed anywhere we want in the world.
|
|
////
|
|
// myInstance = dpl_NewInstance();
|
|
// myDCS = dpl_NewDCS();
|
|
// Check_Pointer (myInstance);
|
|
// Check_Pointer (myDCS);
|
|
// dpl_AddDCSToScene (myDCS);
|
|
// dpl_SetDCSZone (myDCS, myZone);
|
|
// dpl_SetInstanceObject (myInstance, myTranslocateSphere);
|
|
// dpl_SetInstanceIntersect (myInstance, dpl_isect_mode_obj);
|
|
// dpl_SetInstanceSectMask (myInstance, NULL);
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
// dpl_AddInstanceToDCS (myDCS, myInstance);
|
|
// dpl_FlushInstance (myInstance);
|
|
// dpl_FlushDCS (myDCS);
|
|
////
|
|
//// Register this effect as a dynamic renderable of the entity
|
|
////
|
|
//// myEntity->AddDynamicVideoComponent(this);
|
|
////
|
|
//// HACK HACK this needs to be folded back into the new videorenderable hiearchy
|
|
// myEntity->AddStaticVideoComponent(this);
|
|
// L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// l4_application->GetVideoRenderer()->AddDynamicRenderable(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for DPLTranslocationRenderable
|
|
//
|
|
DPLTranslocationRenderable::~DPLTranslocationRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the DPLTranslocationRenderable
|
|
//
|
|
Logical
|
|
DPLTranslocationRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check(myEntity);
|
|
Check(myEffectTrigger);
|
|
Check_Pointer(myZone);
|
|
Check(myDropZoneLocation);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for DPLTranslocationRenderable.
|
|
// Note that the states listed here are temporary for testing and will be changed
|
|
// to player based effects as things are finalized.
|
|
//
|
|
void
|
|
DPLTranslocationRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// Scalar
|
|
// current_time,
|
|
// scale_factor;
|
|
// unsigned
|
|
// current_trigger_state;
|
|
// //
|
|
// // Check data we're going to use and get our current state to a local variable
|
|
// //
|
|
// Check_Pointer(myEffectTrigger);
|
|
// current_trigger_state = myEffectTrigger->GetState();
|
|
// // HACK, because this renderable doesn't know what renderer it's on yet.
|
|
// {L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
// Check(l4_application);
|
|
// current_time = l4_application->GetVideoRenderer()->GetCurrentFrameTime();}
|
|
//// current_time = myRenderer->GetCurrentFrameTime();
|
|
// //
|
|
// // Simple state engine to manage the death/translocation effect
|
|
// //
|
|
// switch(myState)
|
|
// {
|
|
// case IdleState:
|
|
// {
|
|
// //
|
|
// // Watch for transition to the dropzone acquired state
|
|
// //
|
|
// if(current_trigger_state == myDropZoneState)
|
|
// {
|
|
// myState = InitialExpandState;
|
|
// myEffectTimer = current_time;
|
|
// scale_factor = current_time - myEffectTimer;
|
|
// if(scale_factor < 0.05f)
|
|
// scale_factor = 0.05f;
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine(0,0) = scale_factor;
|
|
// tempAffine(1,1) = scale_factor;
|
|
// tempAffine(2,2) = scale_factor;
|
|
// tempAffine = *myDropZoneLocation;
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// dpl_SetInstanceVisibility (myInstance, True);
|
|
// dpl_FlushInstance (myInstance);
|
|
// HACK_DPL_FLUSH_DCS (myDCS);
|
|
// }
|
|
// break;
|
|
// }
|
|
// case InitialExpandState:
|
|
// {
|
|
// scale_factor = current_time - myEffectTimer;
|
|
// if(scale_factor < 0.05f)
|
|
// scale_factor = 0.05f;
|
|
// if(scale_factor >= 1.0)
|
|
// {
|
|
// scale_factor = 1.0;
|
|
// myState = HoldAtSizeState;
|
|
// }
|
|
// // Below is a hack to build a scaling identity matrix
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine(0,0) = scale_factor;
|
|
// tempAffine(1,1) = scale_factor;
|
|
// tempAffine(2,2) = scale_factor;
|
|
// tempAffine = *myDropZoneLocation;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// HACK_DPL_FLUSH_DCS (myDCS);
|
|
// break;
|
|
// }
|
|
// case HoldAtSizeState:
|
|
// {
|
|
// if((current_time - myEffectTimer) >= 3.0)
|
|
// {
|
|
// myState = ColapseState;
|
|
// myEffectTimer = current_time + 1.0;
|
|
// }
|
|
// break;
|
|
// }
|
|
// case ColapseState:
|
|
// {
|
|
// scale_factor = myEffectTimer - current_time;
|
|
// if(scale_factor < 0.05f)
|
|
// {
|
|
// scale_factor = 0.05f;
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
// dpl_FlushInstance (myInstance);
|
|
// myState = IdleState;
|
|
// }
|
|
// // Below is a hack to build a scaling identity matrix
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine(0,0) = scale_factor;
|
|
// tempAffine(1,1) = scale_factor;
|
|
// tempAffine(2,2) = scale_factor;
|
|
// tempAffine = *myDropZoneLocation;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// HACK_DPL_FLUSH_DCS (myDCS);
|
|
// break;
|
|
// }
|
|
// }
|
|
HierarchicalDrawComponent::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// This is brand new stuff as of 5/12/96
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for OnePSFXRenderable
|
|
// This renderable triggers off a single PSFX effect and then hangs around and
|
|
// kills the effect when the renderable goes away. This is useful for things
|
|
// like missiles which you want to leave a smoke trail that stops if the object
|
|
// is destroyed. You REALLY want to do this whenever you attach an effect to
|
|
// a DCS since if the DCS goes away the DPL renderer will go wackey.
|
|
//
|
|
OnePSFXRenderable::OnePSFXRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
dpl_PARTICLESTART_EFFECT_INFO *psfx_definition, // name of file with the PFX description in it
|
|
HierarchicalDrawComponent *parent, // DCS the effect is relative to (may be NULL)
|
|
Point3D *offset_point // Offset (or world coordinants if DCS is NULL)
|
|
):
|
|
VideoRenderable(entity, execution_type, parent)
|
|
{
|
|
//
|
|
// Check the inbound data, note that the parent DCS could be a null pointer
|
|
//
|
|
#if DEBUG_LEVEL > 0
|
|
if(effect_DCS != NULL)
|
|
Check_Pointer(effect_DCS);
|
|
#endif
|
|
Check(offset_point);
|
|
if(!psfx_definition)
|
|
{
|
|
Fail("A pfx was not defined in the .ini file\n");
|
|
}
|
|
//
|
|
// Initialze the local variables
|
|
//
|
|
myPSFXInfo = *psfx_definition;
|
|
//
|
|
// Start the PFX immediately
|
|
//
|
|
// myPSFXInfo.identifier = (myPSFXInfo.identifier & 0xffff0000) | myRenderer->GetUniqueID();
|
|
// dpl_Effect ( dpl_effect_type_particlestart, effect_DCS, &myPSFXInfo );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for OnePSFXRenderable
|
|
//
|
|
OnePSFXRenderable::~OnePSFXRenderable()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Since this renderable only sends one PSFX ID down, we only have to kill
|
|
//// one PSFX, no need to track how many are spawned.
|
|
////
|
|
//Check(this);
|
|
//dpl_Effect ( dpl_effect_type_particlestop, NULL, &myPSFXInfo );
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the OnePSFXRenderable
|
|
//
|
|
Logical
|
|
OnePSFXRenderable::TestInstance() const
|
|
{
|
|
VideoRenderable::TestInstance();
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for OnePSFXRenderable.
|
|
//
|
|
void
|
|
OnePSFXRenderable::Execute()
|
|
{
|
|
// Call the next lower execute method
|
|
VideoRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for TranslocationRenderable
|
|
// This renderable does the UFT translocation effect from the perspective of
|
|
// someone else watching the person translocating. We connect this to the
|
|
// player object and uses information from that object to position itself.
|
|
//
|
|
TranslocationRenderable::TranslocationRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
bool isDeathZone, // DPL zone everything will be in
|
|
StateIndicator *effect_trigger, // Trigger effects off of this state dial
|
|
Point3D *drop_zone_location, // Attribute that holds where the new drop will be
|
|
unsigned drop_zone_state // State that indicates drop zone is valid (starts effect)
|
|
):
|
|
VideoRenderable(entity, execution_type)
|
|
{
|
|
isDeathDraw = isDeathZone;
|
|
|
|
//STUBBED: DPL RB 1/14/07
|
|
////
|
|
//// Check the inbound data, note that the parent DCS could be a null pointer
|
|
////
|
|
// Check_Pointer(this_zone);
|
|
Check(effect_trigger);
|
|
Check(drop_zone_location);
|
|
////
|
|
//// Remember the entity and DCS this renderable is attached to
|
|
////
|
|
// myZone = this_zone;
|
|
myEffectTrigger = effect_trigger;
|
|
myDropZoneLocation = drop_zone_location;
|
|
myDropZoneState = drop_zone_state;
|
|
myState = IdleState;
|
|
|
|
L4Application *l4_application = Cast_Object(L4Application*, application);
|
|
Check(l4_application);
|
|
|
|
////
|
|
//// Load up the object we're going to use for the translocation
|
|
////
|
|
// dpl_OBJECT* myTranslocateSphere = dpl_LoadObject ( "tsphere", dpl_load_normal );
|
|
myDevice = l4_application->GetVideoRenderer()->GetDevice();
|
|
myTranslocateSphere = d3d_OBJECT::LoadObject(myDevice, "tsphere.bgf");
|
|
// Check_Pointer(myTranslocateSphere);
|
|
////
|
|
//// Setup a DCS that we can put the effect on so it can be rotated, scaled and
|
|
//// placed anywhere we want in the world.
|
|
////
|
|
// myInstance = dpl_NewInstance();
|
|
// myDCS = dpl_NewDCS();
|
|
// Check_Pointer (myInstance);
|
|
// Check_Pointer (myDCS);
|
|
// dpl_AddDCSToScene (myDCS);
|
|
l4_application->GetVideoRenderer()->AddRenderable(this);
|
|
// dpl_SetDCSZone (myDCS, myZone);
|
|
// dpl_SetInstanceObject (myInstance, myTranslocateSphere);
|
|
// dpl_SetInstanceIntersect (myInstance, dpl_isect_mode_obj);
|
|
// dpl_SetInstanceSectMask (myInstance, NULL);
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
//TODO set visibility
|
|
// dpl_AddInstanceToDCS (myDCS, myInstance);
|
|
// dpl_FlushInstance (myInstance);
|
|
// dpl_FlushDCS (myDCS);
|
|
////
|
|
//// Plug us into the watcher hook of the effect trigger state dial
|
|
////
|
|
myEffectTrigger->AddVideoWatcher(this);
|
|
visible = false;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for TranslocationRenderable
|
|
//
|
|
TranslocationRenderable::~TranslocationRenderable()
|
|
{
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the TranslocationRenderable
|
|
//
|
|
Logical
|
|
TranslocationRenderable::TestInstance() const
|
|
{
|
|
Component::TestInstance();
|
|
|
|
Check(myEffectTrigger);
|
|
Check_Pointer(myZone);
|
|
Check(myDropZoneLocation);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute method for TranslocationRenderable.
|
|
// Note that the states listed here are temporary for testing and will be changed
|
|
// to player based effects as things are finalized.
|
|
//
|
|
void
|
|
TranslocationRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
Scalar
|
|
current_time,
|
|
scale_factor;
|
|
unsigned
|
|
current_trigger_state;
|
|
//
|
|
// Check data we're going to use and get our current state to a local variable
|
|
//
|
|
Check(myEffectTrigger);
|
|
current_trigger_state = myEffectTrigger->GetState();
|
|
current_time = myRenderer->GetCurrentFrameTime();
|
|
//
|
|
// Simple state engine to manage the death/translocation effect
|
|
//
|
|
// std::cout<<"TranslocationRenderable::Execute\n";
|
|
switch(myState)
|
|
{
|
|
case IdleState:
|
|
{
|
|
//
|
|
// Watch for transition to the dropzone acquired state
|
|
//
|
|
if(current_trigger_state == myDropZoneState)
|
|
{
|
|
myState = InitialExpandState;
|
|
myEffectTimer = current_time;
|
|
scale_factor = current_time - myEffectTimer;
|
|
if(scale_factor < 0.05f)
|
|
scale_factor = 0.05f;
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine(0,0) = scale_factor;
|
|
tempAffine(1,1) = scale_factor;
|
|
tempAffine(2,2) = scale_factor;
|
|
tempAffine = *myDropZoneLocation;
|
|
localToWorld = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// dpl_SetInstanceVisibility (myInstance, True);
|
|
visible = true;
|
|
// dpl_FlushInstance (myInstance);
|
|
// DPL_FLUSH_DCS (myDCS);
|
|
myRenderer->AddDynamicRenderable(this);
|
|
// std::cout<<"TranslocationRenderable Going Dynamic\n";
|
|
}
|
|
break;
|
|
}
|
|
case InitialExpandState:
|
|
{
|
|
scale_factor = current_time - myEffectTimer;
|
|
if(scale_factor < 0.05f)
|
|
scale_factor = 0.05f;
|
|
if(scale_factor >= 1.0)
|
|
{
|
|
scale_factor = 1.0;
|
|
myState = HoldAtSizeState;
|
|
}
|
|
// // Below is a hack to build a scaling identity matrix
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine(0,0) = scale_factor;
|
|
tempAffine(1,1) = scale_factor;
|
|
tempAffine(2,2) = scale_factor;
|
|
tempAffine = *myDropZoneLocation;
|
|
localToWorld = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// DPL_FLUSH_DCS (myDCS);
|
|
break;
|
|
}
|
|
case HoldAtSizeState:
|
|
{
|
|
if((current_time - myEffectTimer) >= 3.0)
|
|
{
|
|
myState = ColapseState;
|
|
myEffectTimer = current_time + 1.0;
|
|
}
|
|
break;
|
|
}
|
|
case ColapseState:
|
|
{
|
|
scale_factor = myEffectTimer - current_time;
|
|
if(scale_factor < 0.05f)
|
|
{
|
|
scale_factor = 0.05f;
|
|
visible = false;
|
|
// dpl_SetInstanceVisibility (myInstance, False);
|
|
// dpl_FlushInstance (myInstance);
|
|
myState = IdleState;
|
|
myRenderer->RemoveDynamicRenderable(this);
|
|
//// std::cout<<"TranslocationRenderable Going Static\n";
|
|
}
|
|
// Below is a hack to build a scaling identity matrix
|
|
// float32* tempMatrix2 = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix2 );
|
|
AffineMatrix tempAffine(True);
|
|
tempAffine(0,0) = scale_factor;
|
|
tempAffine(1,1) = scale_factor;
|
|
tempAffine(2,2) = scale_factor;
|
|
tempAffine = *myDropZoneLocation;
|
|
localToWorld = tempAffine;
|
|
// *(Matrix4x4*)tempMatrix2 = tempAffine;
|
|
// DPL_FLUSH_DCS (myDCS);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!visible)
|
|
{
|
|
graphicalObject = NULL;
|
|
} else
|
|
{
|
|
graphicalObject = myTranslocateSphere;
|
|
myRenderer->GetMatrixStack()->Push();
|
|
D3DXMATRIX transform = localToWorld.ToD3DMatrix();
|
|
myRenderer->GetMatrixStack()->MultMatrixLocal(&transform);
|
|
//myLocalToWorld = *myRenderer->GetMatrixStack()->GetTop();
|
|
HierarchicalDrawComponent::SetLocalToWorld(myRenderer->GetMatrixStack()->GetTop());
|
|
VideoRenderable::Execute();
|
|
myRenderer->GetMatrixStack()->Pop();
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for SpinScaleQuatWatcherRenderable
|
|
//
|
|
SpinScaleQuatWatcherRenderable::SpinScaleQuatWatcherRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
StateIndicator *control, // the state dial that controls this renderable
|
|
unsigned effect_trigger_state,// the state that turns on the renderable
|
|
Quaternion *rotation_quaternion,// rotates the object
|
|
Vector3D *scale_vector, // Scales the object
|
|
Scalar z_spin_rate // spins the object about z (radians/frame)
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check the inbound data
|
|
// //
|
|
// Check(control);
|
|
// Check(rotation_quaternion);
|
|
// Check(scale_vector);
|
|
// //
|
|
// // Remember the entity that this renderable is attached to and the
|
|
// // orientation matrix that offsets it to the correct position.
|
|
// //
|
|
// myControl = control;
|
|
// myTriggerState = effect_trigger_state;
|
|
// myVisible = False;
|
|
// myRotationQuaternion = rotation_quaternion;
|
|
// myScaleVector = scale_vector;
|
|
// myZSpinRate = z_spin_rate;
|
|
// OldZSpin = 0;
|
|
// //
|
|
// // Setup the dcs matrix to it's initial state
|
|
// //
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine *= (*myScaleVector);
|
|
// tempAffine *= (*myRotationQuaternion);
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// dpl_FlushDCS ( myDCS );
|
|
// //
|
|
// // Set the instance visibility correctly
|
|
// //
|
|
// dpl_SetInstanceVisibility ( myInstance, myVisible );
|
|
// dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Plug us into the watcher hook of the effect trigger state dial
|
|
////
|
|
// myControl->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for SpinScaleQuatWatcherRenderable
|
|
//
|
|
SpinScaleQuatWatcherRenderable::~SpinScaleQuatWatcherRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the SpinScaleQuatWatcherRenderable
|
|
//
|
|
Logical
|
|
SpinScaleQuatWatcherRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
Check(myControl);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the SpinScaleQuatWatcherRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
SpinScaleQuatWatcherRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check our variables
|
|
// //
|
|
// Check(this);
|
|
// //
|
|
// // Check data we're going to use and get our current state to a local variable
|
|
// //
|
|
//// std::cout<<"SpinScaleQuatWatcherRenderable::Execute "<<myControl->GetState()<<"\n";
|
|
// if(myControl->GetState() == myTriggerState)
|
|
// {
|
|
// //
|
|
// // We're in the trigger state, if we aren't already visible, make us
|
|
// // visible and dynamic now.
|
|
// //
|
|
// if(!myVisible)
|
|
// {
|
|
// myVisible = True;
|
|
// dpl_SetInstanceVisibility ( myInstance, True );
|
|
// dpl_FlushInstance ( myInstance );
|
|
// myRenderer->AddDynamicRenderable(this);
|
|
//// std::cout<<"SpinScaleQuatWatcherRenderable Going Dynamic\n";
|
|
// }
|
|
// //
|
|
// // Now update the beam
|
|
// //
|
|
// OldZSpin += myZSpinRate;
|
|
// if(OldZSpin > TWO_PI)
|
|
// OldZSpin -= TWO_PI;
|
|
// Hinge temp_hinge(Z_Axis, OldZSpin);
|
|
//
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
//
|
|
// AffineMatrix tempAffine(True);
|
|
// Quaternion temp_quaternion;
|
|
// temp_quaternion = temp_hinge;
|
|
// tempAffine = temp_quaternion;
|
|
// tempAffine *= (*myScaleVector);
|
|
// tempAffine *= (*myRotationQuaternion);
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// // We've left the trigger state, so if we're visible we make the beam
|
|
// // invisible and go static.
|
|
// //
|
|
// if(myVisible)
|
|
// {
|
|
// myVisible = False;
|
|
// dpl_SetInstanceVisibility ( myInstance, False );
|
|
// dpl_FlushInstance ( myInstance );
|
|
// myRenderer->RemoveDynamicRenderable(this);
|
|
//// std::cout<<"SpinScaleQuatWatcherRenderable Going Static\n";
|
|
// }
|
|
// }
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
ChildOffsetRenderable::Execute();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Constructor for ScaleQuatWatcherRenderable
|
|
//
|
|
ScaleQuatWatcherRenderable::ScaleQuatWatcherRenderable(
|
|
Entity *entity, // Entity to attach the renderable to
|
|
ExecutionType execution_type, // How/when to execute the renderable
|
|
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
bool isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
dpl_ISECT_MODE intersect_mode, // type of intersections to do on this object
|
|
uint32 intersect_mask, // intersection mask for the object
|
|
HierarchicalDrawComponent *parent, // the parent DCS we will be offsetting from
|
|
LinearMatrix *offset_matrix, // offset matrix to be applied prior to joint DCS
|
|
StateIndicator *control, // the state dial that controls this renderable
|
|
unsigned effect_trigger_state,// the state that turns on the renderable
|
|
Quaternion *rotation_quaternion,// rotates the object
|
|
Vector3D *scale_vector // Scales the object
|
|
):
|
|
ChildOffsetRenderable(
|
|
entity, // Entity to attach the renderable to
|
|
execution_type, // How/when to execute the renderable
|
|
graphical_object, // object to hang on the DCS, may be a list later <NULL>
|
|
isDeathZone, // DPL Zone this stuff will live in (for culling)
|
|
intersect_mode, // type of intersections to do on this object
|
|
intersect_mask, // intersection mask for the object
|
|
parent, // the parent DCS we will be offsetting from
|
|
offset_matrix) // offset matrix to be applied prior to joint DCS
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check the inbound data
|
|
// //
|
|
// Check(control);
|
|
// Check(rotation_quaternion);
|
|
// Check(scale_vector);
|
|
// //
|
|
// // Remember the entity that this renderable is attached to and the
|
|
// // orientation matrix that offsets it to the correct position.
|
|
// //
|
|
// myControl = control;
|
|
// myTriggerState = effect_trigger_state;
|
|
// myVisible = False;
|
|
// myRotationQuaternion = rotation_quaternion;
|
|
// myScaleVector = scale_vector;
|
|
// //
|
|
// // Setup the dcs matrix to it's initial state
|
|
// //
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine *= (*myScaleVector);
|
|
// tempAffine *= (*myRotationQuaternion);
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// dpl_FlushDCS ( myDCS );
|
|
// //
|
|
// // Set the instance visibility correctly
|
|
// //
|
|
// dpl_SetInstanceVisibility ( myInstance, myVisible );
|
|
// dpl_FlushInstance ( myInstance );
|
|
////
|
|
//// Plug us into the watcher hook of the effect trigger state dial
|
|
////
|
|
// myControl->AddVideoWatcher(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Destructor for ScaleQuatWatcherRenderable
|
|
//
|
|
ScaleQuatWatcherRenderable::~ScaleQuatWatcherRenderable()
|
|
{
|
|
//
|
|
// Check our structure before we do anything
|
|
//
|
|
Check(this);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// TestInstance for the ScaleQuatWatcherRenderable
|
|
//
|
|
Logical
|
|
ScaleQuatWatcherRenderable::TestInstance() const
|
|
{
|
|
//
|
|
// Call our parent's TestInstance first
|
|
//
|
|
ChildOffsetRenderable::TestInstance();
|
|
Check(myControl);
|
|
return True;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execute for the ScaleQuatWatcherRenderable
|
|
// Nothing to execute here so we just pass it down to the next lower level.
|
|
//
|
|
void
|
|
ScaleQuatWatcherRenderable::Execute()
|
|
{
|
|
//STUBBED: DPL RB 1/14/07
|
|
// //
|
|
// // Check our variables
|
|
// //
|
|
// Check(this);
|
|
// //
|
|
// // Check data we're going to use and get our current state to a local variable
|
|
// //
|
|
// //std::cout<<"ScaleQuatWatcherRenderable::Execute "<<myControl->GetState()<<"\n";
|
|
// if(myControl->GetState() == myTriggerState)
|
|
// {
|
|
// //
|
|
// // We're in the trigger state, if we aren't already visible, make us
|
|
// // visible and dynamic now.
|
|
// //
|
|
// if(!myVisible)
|
|
// {
|
|
// myVisible = True;
|
|
// dpl_SetInstanceVisibility ( myInstance, True );
|
|
// dpl_FlushInstance ( myInstance );
|
|
// myRenderer->AddDynamicRenderable(this);
|
|
//// std::cout<<"ScaleQuatWatcherRenderable Going Dynamic\n";
|
|
// }
|
|
// //
|
|
// // Now update the beam
|
|
// //
|
|
// float32* tempMatrix = dpl_GetDCSMatrix( myDCS );
|
|
// Check_Pointer ( tempMatrix );
|
|
// AffineMatrix tempAffine(True);
|
|
// tempAffine *= (*myScaleVector);
|
|
// tempAffine *= (*myRotationQuaternion);
|
|
// *(Matrix4x4*)tempMatrix = tempAffine;
|
|
// DPL_FLUSH_DCS ( myDCS );
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// // We've left the trigger state, so if we're visible we make the beam
|
|
// // invisible and go static.
|
|
// //
|
|
// if(myVisible)
|
|
// {
|
|
// myVisible = False;
|
|
// dpl_SetInstanceVisibility ( myInstance, False );
|
|
// dpl_FlushInstance ( myInstance );
|
|
// myRenderer->RemoveDynamicRenderable(this);
|
|
//// std::cout<<"ScaleQuatWatcherRenderable Going Static\n";
|
|
// }
|
|
// }
|
|
//// if(*myTest != myVisible)
|
|
//// {
|
|
//// std::cout<<"myTest="<<*myTest<<" myVisible="<<myVisible<<"\n";
|
|
//// }
|
|
//
|
|
// Call the execute method in our parent
|
|
//
|
|
ChildOffsetRenderable::Execute();
|
|
}
|