//===========================================================================//
// File:	l4vidrnd.hpp																	 	  //
// Project: MUNGA           Brick: Video Renderer Manager	                 //
// Contents: Interface specification Video Renderer Manager       			  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 07/08/95  GAC  Took renderables out of l4video and moved them here        //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(L4VIDRND_HPP)
#	define L4VIDRND_HPP

#	if !defined(ROTATION_HPP)
#		include <rotation.hpp>
#	endif

#	if	!defined(RETICLE_HPP)
#		include <reticle.hpp>
#	endif

#	if !defined(SIMULATE_HPP)
#		include <simulate.hpp>
#	endif

#	if !defined(LINMTRX_HPP)
#		include <linmtrx.hpp>
#	endif

#	if !defined(CSTR_HPP)
#		include <cstr.hpp>
#	endif

#	if !defined(SLOT_HPP)
#		include <slot.hpp>
#	endif

#include <dpl.h>
#include	<dplutils.h>
#include	<dpl_2d.h>
//===========================================================================//
//===========================================================================//
//===========================================================================//
//===========================================================================//
// All the stuff between these big ugly bars is the new video component stuff//

	typedef enum
	{
		NullVideoControlID		= 0,
		StartVideoControlID		= 1,
		StopVideoControlID		= 2,
	} VideoControlID;

	typedef enum
	{
		StaticVideoExecutionType	=	0,
		DynamicVideoExecutionType	=	1,
		WatcherVideoExecutionType	=	2,
	} VideoExecutionType;

	typedef enum
	{
		NotDPLComponentType		= 0,
	} DPLComponentType;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Video component base class
//
	class	VideoComponent:
		public Component
	{
		public:
			//
			//--------------------------------------------------------------------
			// Construction, Destruction, Testing
			//--------------------------------------------------------------------
			//
			VideoComponent(
				Entity					*entity,				// Entity to attach the renderable to
				VideoExecutionType	execution_type);	// How/when to execute the renderable

			~VideoComponent();

			Logical
				TestInstance() const;
			//
			//--------------------------------------------------------------------
			// Add, handles establishing graphical hiearchal links between
			// things like DCS's, Instances, geometry and so on.  This does not
			// establish a control path, only a graphical hiearchy.  For each
			// target type that something can be added to there is also an
			// AddMeToTYPE(component) virtual (ie: AddMeToDCS)
			//--------------------------------------------------------------------
			//
			virtual void
				Add(
					VideoComponent	*component_to_add);
			virtual void
				AddMeToDCS(
					VideoComponent	*component_to_add)
						{Fail("Don't know how to add this component to a DCS\n");};
			virtual void
				AddMeToInstance(
					VideoComponent	*component_to_add)
						{Fail("Don't know how to add this component to an Instance\n");};
			virtual void
				AddMeToScene(
					VideoComponent	*component_to_add)
						{Fail("Don't know how to add this component to a Scene\n");};
			//
			//--------------------------------------------------------------------
			// Connect, connects a control path between us and the component
			// in the argument.  The path goes from us to that element.
			//--------------------------------------------------------------------
			//
			virtual void
				Connect(
					VideoComponent	*component_to_connect);
			//
			//--------------------------------------------------------------------
			// ReceiveControl, called by people connected to us to send control
			// inputs to us.  For the moment we will have several virtuals that
			// accept different control types.
			//--------------------------------------------------------------------
			//
			virtual void
				ReceiveControl(
					VideoControlID control_ID,
					Scalar control_value
				);
			//
			//--------------------------------------------------------------------
			// Execute
			//--------------------------------------------------------------------
			//
			void
				Execute();

		protected:
			#if DEBUG_LEVEL > 0
			VideoExecutionType
				myExecutionType;		// We use this to test if the component is in the wrong list
			#endif

			SlotOf<VideoComponent*>
				videoComponentSocket;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DPLDCSWrapper class
//
	class	DPLDCSWrapper:
		public VideoComponent
	{
		public:
			//
			//--------------------------------------------------------------------
			// Construction, Destruction, Testing
			//--------------------------------------------------------------------
			//
			DPLDCSWrapper(
				Entity					*entity,				// Entity to attach the renderable to
				VideoExecutionType	execution_type,	// How/when to execute the renderable
				LinearMatrix         initial_matrix);	// Initial value to put into the matrix

			~DPLDCSWrapper();

			Logical
				TestInstance() const;

			void
				Add(
					VideoComponent	*component_to_add);
			void
				Connect(
					VideoComponent	*component_to_connect);
			void
				ReceiveControl(
					VideoControlID control_ID,
					Scalar control_value
				);
			void
				Execute();

		protected:
			dpl_DCS
				*my_DCS;
	};

//===========================================================================//
//===========================================================================//
//===========================================================================//
//===========================================================================//
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~New Class Hiearchy for Renderables~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Video renderable base class
//
	class	VideoRenderable:
		public Component
	{
		public:
			enum	ExecutionType
			{
				Static = 0,
				Dynamic,
				Watcher,
            Dependant,
				NextExecutionType
			};

			VideoRenderable(
				Entity			*entity,				// Entity to attach the renderable to
				ExecutionType	execution_type);	// How/when to execute the renderable

			~VideoRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			DPLRenderer
				*myRenderer;			// The renderer that owns this renderable

			Entity
				*myEntity;				// The entity we are linked to

			ExecutionType
				myExecutionType;		// How/when to execute the renderable
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~This is a special class to speed up projectiles~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	class	InnerProjectileRenderable:
		public Component
	{
		public:
			InnerProjectileRenderable(
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone);			// DPL Zone this stuff will live in (for culling)

			~InnerProjectileRenderable();

			Logical
				TestInstance() const;

			dpl_DCS*
				GetDCS()
					{return myDCS;}

			dpl_INSTANCE*
				GetInstance()
					{return myInstance;}

		protected:
			dpl_DCS
				*myDCS;
			dpl_INSTANCE
				*myInstance;
	};

	class	ProjectileRootRenderable:
		public VideoRenderable
	{
		public:
			ProjectileRootRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone);			// DPL Zone this stuff will live in (for culling)

			~ProjectileRootRenderable();

			Logical
				TestInstance() const;

			void
				Execute();
		protected:
			InnerProjectileRenderable
         	*myInnerProjectile;
			LinearMatrix
				oldLocalToWorld;		  // The value of this matrix the last time through
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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.
//
	class ChildLightRenderable:
		public VideoRenderable
	{
		public:

			ChildLightRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_ZONE					*this_zone,				// DPL Zone this stuff will live in (for culling)
				dpl_DCS					*parent_DCS,			// 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);

			~ChildLightRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_LIGHT
				*myLight;
			dpl_DCS
				*myDCS,
				*myParentDCS;
			dpl_ZONE
				*myZone;
			LinearMatrix
				myOffsetMatrix;
	};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DPLObjectWrapper is a wrapper class that holds on to one of DPL's objects
// so it can be deleted properly at a later time.
//
	class DPLObjectWrapper:
		public VideoRenderable
	{
		public:
			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)

			~DPLObjectWrapper();

			Logical
				TestInstance() const;

			dpl_OBJECT*
				GetDPLObject()
					{return myDPLObject;}

			CString*
				GetDPLObjectName()
					{return &myDPLObjectName;}

			void
				Execute();

		protected:
			CString
				myDPLObjectName;
			dpl_LOAD_MODE
         	myCacheMode;
			dpl_OBJECT
				*myDPLObject;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DCSObjectRenderable a subclass not intended to be used on it's own, it
// encapsulates the information that follows a DCS node around.  Parameters
// marked with <NULL> are allowed to be passed in as NULL values.
//
	class DCSObjectRenderable:
		public VideoRenderable
	{
		public:
			DCSObjectRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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();

			Logical
				TestInstance() const;

			dpl_DCS*
				GetDCS()
					{return myDCS;}
			dpl_INSTANCE*
				GetInstance()
					{return myInstance;}

			void
				Execute();

		protected:
			dpl_OBJECT
				*myDPLObject;
			dpl_ZONE
				*myDPLZone;
			dpl_ISECT_MODE
				myIntersectMode;
			uint32
				myIntersectMask;
			dpl_DCS
				*myDCS;				// The dpl DCS we create to hold the instance of this object
			dpl_INSTANCE
				*myInstance;		// Instance that we hang on the DCS
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DCSInstanceRenderable Creates a DPL instance and binds it to a DCS.  This
// is mainly used to insure these instances will be deleted properly when the
// object goes away.
//
	class DCSInstanceRenderable:
		public VideoRenderable
	{
		public:
			DCSInstanceRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to connect to the instance
				dpl_DCS					*parent_DCS,			// 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

			~DCSInstanceRenderable();

			Logical
				TestInstance() const;

			dpl_INSTANCE*
				GetInstance()
					{return myInstance;}

			void
				Execute();

		protected:
			dpl_OBJECT
				*myDPLObject;
			dpl_ISECT_MODE
				myIntersectMode;
			uint32
				myIntersectMask;
			dpl_DCS
				*myDCS;				// The dpl DCS we create to hold the instance of this object
			dpl_INSTANCE
				*myInstance;		// Instance that we hang on the DCS
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RootRenderable handles an entity that is assumed to be attached at the root
// of the DCS hiearchy.  That is, it's connected to the scene rather than to
// another DCS.  The root automatically connects up to entity->localToWorld
//
	class RootRenderable:
		public DCSObjectRenderable
	{
		public:
			RootRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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

			~RootRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			LinearMatrix
				oldLocalToWorld;		  // The value of this matrix the last time through

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ChildOffsetRenderable is an intermediate layer that establishes a DCS to handle
// a static offset matrix to be applied prior to the DCS that actually carries
// joint and geometry information.  This is not intended to ever be used
// directly.
//
	class ChildOffsetRenderable:
		public DCSObjectRenderable
	{
		public:
			ChildOffsetRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				LinearMatrix			*offset_matrix);		// offset matrix to be applied prior to joint DCS

			~ChildOffsetRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			LinearMatrix
				myOffsetMatrix;		  	// The offset to apply prior to the joint DCS
			dpl_DCS
				*myParentDCS,				// Pointer to our parent DCS
				*myOffsetDCS;				// The dpl DCS we create to hold the offset from our parent.
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// HingeRenderable Handles controlling a joint by way of a munga HINGE class
// attribute.
//
	class HingeRenderable:
		public ChildOffsetRenderable
	{
		public:
			HingeRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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

			~HingeRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			const Hinge
				*myHinge;			// Pointer to the hinge attribute we use to modify the DCS
			Hinge
				oldHinge;			// Copy of the last value of hinge
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SpinScaleQuatRenderable Handles creates a spinning scaled quaternion controlled
// effect.
//
	class SpinScaleQuatRenderable:
		public ChildOffsetRenderable
	{
		public:
			SpinScaleQuatRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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)

			~SpinScaleQuatRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			Quaternion
				*myRotationQuaternion;
			Vector3D
				*myScaleVector;
			Logical
				*myVisible,
				OldVisible;
			Scalar
				myZSpinRate,
				OldZSpin;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// BallJointRenderable Handles controlling a joint by way of a munga eulers
//
	class BallJointRenderable:
		public ChildOffsetRenderable
	{
		public:
			BallJointRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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

			~BallJointRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			const EulerAngles
				*myEuler;			// Pointer to the hinge attribute we use to modify the DCS
			EulerAngles
				oldEuler;			// Copy of the last value of hinge
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// BallTranslateJointRenderable Handles controlling a joint by way of a munga eulers
//
	class BallTranslateJointRenderable:
		public ChildOffsetRenderable
	{
		public:
			BallTranslateJointRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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

			~BallTranslateJointRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			const Point3D
				*myTranslation;
			Point3D
				oldTranslation;

			const EulerAngles
				*myEuler;			// Pointer to the hinge attribute we use to modify the DCS
			EulerAngles
				oldEuler;			// Copy of the last value of hinge
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  POVTranslocateRenderable generates a translocation effect from the point of
//  view of a player.
	class POVTranslocateRenderable:
		public VideoRenderable                     // from the POV of the player
	{
	public:
		POVTranslocateRenderable(
			Entity				*entity,						// Entity to attach the renderable to
			ExecutionType		execution_type,			// How/when to execute the renderable
			dpl_ZONE				*this_zone,					// DPL zone the world is in
			dpl_ZONE				*death_zone,				// DPL zone the player's VTV and death effect are in
			dpl_DCS				*parent_DCS,			   // 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

		~POVTranslocateRenderable();

		Logical
			TestInstance() const;

		void
			Execute();

	protected:
		enum TranslocateState
		{
			IdleState,
         FlashScreenState,
			InitialCollapseState,
			WaitForReincarnateState,
         ExpandRevealState
		};

		TranslocateState
			myState;

		int
			myEffectControlState;

		Scalar
			myRotateY,
         myRotateYSpeed,
			myCollapseEnd;

		StateIndicator
			*myEffectTrigger;		// trigger effect when this changes

		dpl_INSTANCE
			*myInstance;

		dpl_DCS
			*myParentDCS,				// Pointer to our parent DCS
			*myDCS;

		dpl_ZONE
			*myDeathZone,
			*myZone;

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  POVStartEndRenderable generates a translocation effect from the point of
//  view of a player.
	class POVStartEndRenderable:
		public VideoRenderable                     // from the POV of the player
	{
	public:
		POVStartEndRenderable(
			Entity				*entity,						// Entity to attach the renderable to
			ExecutionType		execution_type,			// How/when to execute the renderable
			dpl_ZONE				*this_zone,					// 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

		~POVStartEndRenderable();

		Logical
			TestInstance() const;

		void
			Execute();

	protected:
		enum StartEndState
		{
			WaitForStartState,
			FlashScreenState,
			FadeInState,
			MissionRunningState,
			FadeOutState
		};

		StartEndState
			myState;

		int
			myStartMissionState,		// Signals mission is starting but player can't move yet
			myEndMissionState;		// Signals mission is ending

		float
			myFogRed,
			myFogGreen,
			myFogBlue,
			myFogNear,
			myFogFar;

		Scalar
			myStateTimer;

		StateIndicator
			*myEffectTrigger;		// trigger effect when this changes

		dpl_ZONE
			*myDeathZone,
			*myZone;

		dpl_VIEW
			*myView;

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ReticleRenderable drawing a static or dynamic reticle in the 2D layer of the
// screen.
//
	class ReticleRenderable:
		public VideoRenderable
	{
		public:
			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

			~ReticleRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:

			Vector2DOf<float>
				myOldReticlePosition;     				// Last known position of the reticle

			Reticle::ReticleState
				myOldReticleState;						// Last known state of the reticle

			Reticle
				**rendererReticle,						// Points to renderer's reticle pointer
				*myReticle;                         // Points directly to reticle in entity

			dpl_VIEW
				*myView;

			dpl2d_DISPLAY
				*myReticleDisplayList,
				*myPositionDisplayList;

	};
#define	MAX_PLAYER_NAMES 12
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Shows Player bitmap for the CameraShip
//
//
	class CameraShipHUDRenderable :
		public VideoRenderable
	{
		public:

			CameraShipHUDRenderable(
				Entity				*entity,
				ExecutionType     execution_type,
				int					*player_index,
				Logical				*display_ranking_window
			);

			~CameraShipHUDRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:

			int
				playerCount;

			int
				oldFollowedPlayerIndex,
				*followedPlayerIndex;

			int
				**playerRank,
				*oldPlayerRank;

			Logical
				*displayRankingWindow,
				oldDisplayRankingWindow;

			dpl_OBJECT
				*playerNameObject[MAX_PLAYER_NAMES],
				*ordinalObject[MAX_PLAYER_NAMES];

			dpl_DCS
				*followedNameDCS,
				*followedOrdinalDCS;

			dpl_INSTANCE
				*followedNameInstance,
				*followedOrdinalInstance;

			dpl_DCS
				*rankingWindowDCS,
				**nameDCS,
				**rankDCS;

			dpl_INSTANCE
				**nameInstance,
				**rankInstance;
	};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This class is used to store a stack of threat vectors
//
	class	VectorStackElement:
		public Plug
	{
		public:
			VectorStackElement(
				float						add_time,					// Time when this threat was added
				Vector2DOf<float>    *vector_to_stack)			// The vector to stack up
				{myAddTime = add_time; myVector = *vector_to_stack;myRecent=True;}

			~VectorStackElement(){};

			Logical
				TestInstance() const
				{Check(&myVector);return(True);}

			Vector2DOf<float>
				myVector;
			float
				myAddTime;
			Logical
				myRecent;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DCSMorphObjectRenderable a subclass not intended to be used on it's own, it
// encapsulates the information that needed to construct a destination dpl_Object
// by morphing two existing objects into it.
//
	class DCSMorphObjectRenderable:
		public VideoRenderable
	{
		public:
			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
				dpl_ZONE					*this_zone,				// 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();

			Logical
				TestInstance() const;

			dpl_DCS*
				GetDCS()
					{return myDCS;}

			void
				Execute();

		protected:
			int32
         	myMorphMode;
			Scalar
         	oldMorphControl,
				*myMorphControl;
			dpl_OBJECT
				*myStartObject,
				*myEndObject,
				*myDPLObject;
			dpl_ZONE
				*myDPLZone;
			dpl_ISECT_MODE
				myIntersectMode;
			uint32
				myIntersectMask;
			dpl_DCS
				*myDCS;				// The dpl DCS we create to hold the instance of this object
			dpl_INSTANCE
         	*myInstance;		// Instance that we hang on the DCS
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ScalingExplosionRenderable Handles controlling a joint by way of a munga HINGE class
// attribute.
//
	class ScalingExplosionRenderable:
		public ChildOffsetRenderable
	{
		public:
			ScalingExplosionRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// This will be the scaling explosion object
				dpl_ZONE					*this_zone,				// 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
				LinearMatrix			*offset_matrix,		// offset matrix to be applied prior to joint DCS
				Vector3D					*control_vector,     	// Effect control vector, Y is acceleration, X, Z are velocity
				Vector3D					*accel_vector,			// rate of change of control vector
				Scalar					gravity,
				int						*trigger);

			~ScalingExplosionRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			int
         	*myTrigger;
			Scalar
         	myVelocity,
				myGravity;
			Point3D
				myTranslation;
			Vector3D
				myVelocityChange,
				myScalingVector,			// Controls scaling of the explosion
				myVelocityVector;       // Scaling velocity (rate of change)
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RootMorphRenderable handles an entity that is assumed to be attached at the root
// of the DCS hiearchy.  That is, it's connected to the scene rather than to
// another DCS.  The root automatically connects up to entity->localToWorld
//
	class RootMorphRenderable:
		public DCSMorphObjectRenderable
	{
		public:
			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
				dpl_ZONE					*this_zone,				// 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

			~RootMorphRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			LinearMatrix
				oldLocalToWorld;		  // The value of this matrix the last time through

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ChildMorphRenderable
//
	class ChildMorphRenderable:
		public DCSMorphObjectRenderable
	{
		public:
			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
				dpl_ZONE					*this_zone,				// 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

			~ChildMorphRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	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.

	class OneShotDelayRenderable:
		public VideoRenderable
	{
		public:
			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 = 0.0f	// How long trigger is up (0.0 == stay up)
			);

			~OneShotDelayRenderable();

			Logical
				TestInstance() const;

			int*
				GetTriggerAttribute()
					{return &myTriggerAttribute;}

			void
				Execute();

		protected:
			enum
			{
				WaitingForTriggerTime,
				WaitingForTriggerEndTime,
				WaitingForEternity
			}	myState;
			Logical
				myEndTimeFlag;
			Scalar
				myTriggerTime,
				myTriggerEndTime;
			int
				myTriggerAttribute;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	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.
	class SweepRenderable:
		public VideoRenderable
	{
		public:
			enum SweepFunction
			{
				Y_EQUALS_X = 0,
				Y_SQR_X
			};

			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,				// Starts the sweep generator when it goes 1
				Scalar					start_value = 0.0f,	// Initial value of sweep
				Scalar					end_value = 1.0f,		// Final value of sweep
				SweepFunction			sweep_function = Y_EQUALS_X	// function applied to sweep
			);

			~SweepRenderable();

			Logical
				TestInstance() const;

			Scalar*
				GetSweepAttribute()
					{return &mySweepAttribute;}

			void
				Execute();

		protected:
			int
				fakeTrigger,
				oldMyTrigger,
				*myTrigger,
				myCycleCount,
				myCyclesLeft;
			SweepFunction
				mySweepFunction;
			Scalar
				myStartValue,
				myEndValue,
				mySweepStart,
				mySweepTime,
				mySweepAttribute;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	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.

	class DPLEffectRenderable:
		public VideoRenderable
	{
		public:
			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
				dpl_DCS					*effect_DCS,			// DCS the effect is relative to (may be NULL)
				Point3D					*offset_point);		// Offset (or world coordinants if DCS is NULL)

			~DPLEffectRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			int
				*myTrigger,
				oldMyTrigger,
				myEffectType;
			dpl_DCS
				*myEffectDCS;
			Point3D
				myEffectOffset;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	class PullFogRenderable:
		public VideoRenderable
	{
		public:
			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
			~PullFogRenderable();
			Logical
				TestInstance() const;
			void
				Execute();
		protected:
			Logical
				*myLight1,
				*myLight2,
				myOldLight1,
				myOldLight2;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	DPLPSFXRenderable
// 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.

	class DPLPSFXRenderable:
		public VideoRenderable
	{
		public:
			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
				dpl_DCS					*effect_DCS,			// DCS the effect is relative to (may be NULL)
				Point3D					*offset_point);		// Offset (or world coordinants if DCS is NULL)

			~DPLPSFXRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_PARTICLESTART_EFFECT_INFO
				myPSFXInfo;
			int
				*myTrigger,
				myOldTrigger;
			dpl_DCS
				*myEffectDCS;
			Point3D
				myEffectOffset;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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.
//

	class DPLPSFXStateRenderable:
		public VideoRenderable
	{
		public:

			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
				dpl_DCS					*effect_DCS,			// DCS the effect is relative to (may be NULL)
				Point3D					*offset_point);		// Offset (or world coordinants if DCS is NULL)

			~DPLPSFXStateRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_PARTICLESTART_EFFECT_INFO
				myPSFXInfo;
			unsigned
				myTriggerState;
			StateIndicator
				*myStateDial;
			dpl_DCS
				*myEffectDCS;
			Point3D
				myEffectOffset;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	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.
	class DPLMaterialRenderable:
		public VideoRenderable
	{
		public:
			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

			~DPLMaterialRenderable();

		dpl_MATERIAL*
			GetMaterial()
				{return myMaterial;}

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_MATERIAL
				*myMaterial;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructor for MorphMaterialRenderable
// This renderable takes two material specifications and loads up a third
// material with a morph between the first two.
	class MorphMaterialRenderable:
		public DPLMaterialRenderable
	{
		public:
			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);

			~MorphMaterialRenderable();

		dpl_MATERIAL*
			GetMaterial()
				{return myMaterial;}

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			int
				myFogImmune1;
			dpl_TEXTURE
				*myTexture1;

			Scalar
				myAmbientRed1,
				myAmbientGreen1,
				myAmbientBlue1,
				myEmissiveRed1,
				myEmissiveGreen1,
				myEmissiveBlue1,
				myDiffuseRed1,
				myDiffuseGreen1,
				myDiffuseBlue1,
				mySpecularRed1,
				mySpecularGreen1,
				mySpecularBlue1,
				mySpecularShininess1,
				myOpacityRed1,
				myOpacityGreen1,
				myOpacityBlue1,
				myZDither1,
				myAmbientRed2,
				myAmbientGreen2,
				myAmbientBlue2,
				myEmissiveRed2,
				myEmissiveGreen2,
				myEmissiveBlue2,
				myDiffuseRed2,
				myDiffuseGreen2,
				myDiffuseBlue2,
				mySpecularRed2,
				mySpecularGreen2,
				mySpecularBlue2,
				mySpecularShininess2,
				myOpacityRed2,
				myOpacityGreen2,
				myOpacityBlue2,
				myZDither2,
				*myMorphControl,
				oldMorphControl,
				myAmbientRed,
				myAmbientGreen,
				myAmbientBlue,
				myEmissiveRed,
				myEmissiveGreen,
				myEmissiveBlue,
				myDiffuseRed,
				myDiffuseGreen,
				myDiffuseBlue,
				mySpecularRed,
				mySpecularGreen,
				mySpecularBlue,
				mySpecularShininess,
				myOpacityRed,
				myOpacityGreen,
				myOpacityBlue,
				myZDither;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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
	class DPLDamageMaterialRenderable:
		public VideoRenderable
	{
		public:
			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

			~DPLDamageMaterialRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_MATERIAL
         	*myMaterial;
			Scalar
				*myDamageAttribute,
				oldDamageAttribute,
				myAmbientRed1,
				myAmbientGreen1,
				myAmbientBlue1,
				myEmissiveRed1,
				myEmissiveGreen1,
				myEmissiveBlue1,
				myDiffuseRed1,
				myDiffuseGreen1,
				myDiffuseBlue1,
				mySpecularRed1,
				mySpecularGreen1,
				mySpecularBlue1,
				mySpecularShininess1,
				myOpacityRed1,
				myOpacityGreen1,
				myOpacityBlue1,
				myAmbientRed2,
				myAmbientGreen2,
				myAmbientBlue2,
				myEmissiveRed2,
				myEmissiveGreen2,
				myEmissiveBlue2,
				myDiffuseRed2,
				myDiffuseGreen2,
				myDiffuseBlue2,
				mySpecularRed2,
				mySpecularGreen2,
				mySpecularBlue2,
				mySpecularShininess2,
				myOpacityRed2,
				myOpacityGreen2,
				myOpacityBlue2,
				myAmbientRed,
				myAmbientGreen,
				myAmbientBlue,
				myEmissiveRed,
				myEmissiveGreen,
				myEmissiveBlue,
				myDiffuseRed,
				myDiffuseGreen,
				myDiffuseBlue,
				mySpecularRed,
				mySpecularGreen,
				mySpecularBlue,
				mySpecularShininess,
				myOpacityRed,
				myOpacityGreen,
				myOpacityBlue;
	};
// 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.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	InstanceSwitchRenderable
	class InstanceSwitchRenderable:
		public VideoRenderable
	{
		public:
			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

			~InstanceSwitchRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			Logical
         	mySense;
			dpl_INSTANCE
				*myInstance;
			int
				*myTriggerAttribute,
				oldTriggerAttribute;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	StateInstanceSwitchRenderable
	class StateInstanceSwitchRenderable:
		public VideoRenderable
	{
		public:
			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

			~StateInstanceSwitchRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			Logical
				myLastInstanceState,
         	mySense;
			dpl_INSTANCE
				*myInstance;
			unsigned
				myTriggerState;
			StateIndicator
				*myStateDial;

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	MakeDCSFall
	class MakeDCSFall:
		public VideoRenderable
	{
		public:
			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

			~MakeDCSFall();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_DCS
				*myDCS;
			int
				*myTrigger,
				fakeTrigger,
				oldMyTrigger;
			Point3D
				myDisplacement;
			Scalar
         	myFallStart,
				myHalfAcceleration;
	};


//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~End of the new renderable class hiearchy~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~Dynamic Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
	//##########################################################################
	class DPLEyeRenderable:     		// this renderable handles a dynamic eyepoint
		public Component
	{
	public:
		DPLEyeRenderable(
			Entity*			This_Entity,
			dpl_ZONE*		This_Zone,
			const LinearMatrix&	Offset_Matrix,
			dpl_DCS*			Parent_DCS,
			dpl_VIEW*		This_View,
			EulerAngles*	eyepoint_rotation
		);
		~DPLEyeRenderable();

		dpl_DCS*
			GetDCS()
				{return myDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();

		dpl_DCS
			*myDCS,
			*myParentDCS;

		LinearMatrix
			myOrientationMatrix;

		EulerAngles
			*myEyepointRotation,
			oldEyepointRotation;

		Entity
			*myEntity;
	};

	//##########################################################################
	class DPLChildPointRenderable:     		// this is a child DCS carrying an instance
		public Component
	{
	public:
		DPLChildPointRenderable(
			Entity					*This_Entity,
			dpl_ZONE					*This_Zone,
			dpl_OBJECT				*Graphic_Object,
			dpl_ISECT_MODE 		Intersect_Mode,
			uint32					Intersect_Mask,
			const LinearMatrix	&Offset_Matrix,
			dpl_DCS					*Parent_DCS,
			Point3D					*my_point
		);
		~DPLChildPointRenderable();

		dpl_DCS*
			GetDCS()
				{return myDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();

		dpl_DCS
      	*myOffsetDCS,
			*myDCS,
			*myParentDCS;

		dpl_INSTANCE
			*myInstance;

		LinearMatrix
			OrientationMatrix;

		Entity
			*myEntity;
		Point3D
			*myPoint,
			OldPoint;
	};
	//##########################################################################
	class DPLScaleRenderable:     		// This is a DCS that responds to scaling
		public Component
	{
	public:
		DPLScaleRenderable(
			Entity					*This_Entity,
			dpl_ZONE					*This_Zone,
			dpl_OBJECT				*Graphic_Object,
			dpl_ISECT_MODE 		Intersect_Mode,
			uint32					Intersect_Mask,
			const LinearMatrix	&Offset_Matrix,
			dpl_DCS					*Parent_DCS,
			Vector3D					*my_scale_vector,
			Logical					*visible
		);
		~DPLScaleRenderable();

//		dpl_DCS*                	// we don't allow this (yet) because it prevents
//			GetDCS()                // people from hooking up children to this renderable
//				{return myDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();
		Logical
			*myVisible,
			OldVisible;
		dpl_DCS
			*myDCS,
			*myParentDCS;

		dpl_INSTANCE
			*myInstance;

		AffineMatrix
			OffsetMatrix;

		Entity
			*myEntity;

		Vector3D
			*myScaleVector,
			OldScaleVector;
	};
	//##########################################################################
	class DPLScaleQuatRenderable:     		// This is a DCS that responds to scaling and quaterninons
		public Component
	{
	public:
		DPLScaleQuatRenderable(
			Entity					*This_Entity,
			dpl_ZONE					*This_Zone,
			dpl_OBJECT				*Graphic_Object,
			dpl_ISECT_MODE 		Intersect_Mode,
			uint32					Intersect_Mask,
			const LinearMatrix	&Offset_Matrix,
			dpl_DCS					*Parent_DCS,
			Quaternion				*rotation_quaternion,
			Vector3D					*my_scale_vector,
			Logical					*visible
		);
		~DPLScaleQuatRenderable();

//		dpl_DCS*                	// we don't allow this (yet) because it prevents
//			GetDCS()                // people from hooking up children to this renderable
//				{return myDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();

		Logical
			*myVisible,
			OldVisible;

		dpl_DCS
			*myDCS,
			*myParentDCS;

		dpl_INSTANCE
			*myInstance;

		AffineMatrix
			OffsetMatrix;

		Entity
			*myEntity;

		Quaternion
			*myRotationQuaternion,
			OldRotationQuaternion;

		Vector3D
			*myScaleVector,
			OldScaleVector;
	};
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~Static Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~these renderables remain constant after construction~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
	//##########################################################################
	class DPLStaticChildRenderable:     		// this is a child DCS carrying an instance
		public Component
	{
	public:
		DPLStaticChildRenderable(
			Entity					*This_Entity,
			dpl_ZONE					*This_Zone,
			dpl_OBJECT				*Graphic_Object,
			dpl_ISECT_MODE 		Intersect_Mode,
			uint32					Intersect_Mask,
			const LinearMatrix	&Offset_Matrix,
			dpl_DCS					*Parent_DCS
		);
		~DPLStaticChildRenderable();

		dpl_DCS*
			GetDCS()
				{return myDCS;}

		dpl_INSTANCE*
			GetInstance()
				{return myInstance;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute(){};

		dpl_DCS
			*myDCS,
			*myParentDCS;

		dpl_INSTANCE
			*myInstance;

		LinearMatrix
			OrientationMatrix;

		Entity
			*myEntity;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~Special Effects Renderables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	class DPLSFXRenderable:     		// A renderable that spawns special effects
		public Component
	{
	public:
		DPLSFXRenderable(
			Entity				*This_Entity,			// Entity to attach the effect to
			dpl_ZONE				*This_Zone,				// DPL zone everything will be in
			const Point3D		&Offset_Point,			// Point offset from the parent DCS
			dpl_DCS				*Parent_DCS,			// Parent DCS (can be NULL for world)
			StateIndicator		*Effect_Trigger,		// Trigger effect when this attribute changes
			int					Trigger_State,			// Trigger effect when in this state
			int					Effect_Type,			// Type of effect to trigger
			Scalar				Repeat_Speed			// Effect repeat speed.
			);

		~DPLSFXRenderable();

		dpl_DCS*
			GetDCS()
				{return myParentDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();

		int
			myEffectType,
			myEffectTriggerState,
			myEffectTriggerOld;

		StateIndicator
			*myEffectTrigger;		// trigger effect when this changes

		dpl_DCS
			*myParentDCS;

		Point3D
			myOffsetPoint;

		Scalar
			myRepeatSpeed,
			myLastEffect;

		Entity
			*myEntity;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	class DPLRepeatSFXRenderable:     		// A renderable that spawns special effects
		public Component
	{
	public:
		DPLRepeatSFXRenderable(
			Entity				*This_Entity,
			dpl_ZONE				*This_Zone,
			const Point3D		&Offset_Point,
			dpl_DCS				*Parent_DCS,			// offset is relative to this
			int					Effect_Type,			// type code for the effect
			Scalar				*Speed
			);

		~DPLRepeatSFXRenderable();

		dpl_DCS*
			GetDCS()
				{return myParentDCS;}

		Logical
			TestInstance() const;

	protected:

		void
			Execute();

		Entity
			*myEntity;

		dpl_DCS
			*myParentDCS;

		Point3D
			myOffsetPoint;

		int
			myEffectType;

		Scalar
			*mySpeed,
			myLastSmoke;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	class DPLTranslocationRenderable: 	    		// A renderable for the UFT translocation efffec
		public Component                          // from the POV of the player
	{
	public:
		DPLTranslocationRenderable(
			Entity				*This_Entity,			// Entity to attach the effect to
			dpl_ZONE				*This_Zone,				// 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
			);

		~DPLTranslocationRenderable();

//		dpl_DCS*
//			GetDCS()
//				{return myParentDCS;}

		Logical
			TestInstance() const;

	protected:
		enum TranslocateState
		{
			IdleState,
			InitialExpandState,
			HoldAtSizeState,
			ColapseState
		};

		TranslocateState
			myState;

		void
			Execute();

		int
			myDropZoneState,
			myEffectType,
			myEffectTriggerOld;

		Scalar
			myEffectTimer;

		StateIndicator
			*myEffectTrigger;		// trigger effect when this changes

		dpl_INSTANCE
			*myInstance;

		dpl_DCS
			*myDCS;

		dpl_ZONE
			*myZone;

		Entity
			*myEntity;

		Point3D
			*myDropZoneLocation;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This is brand new stuff as of 5/12/96
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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.
//
	class DependantRenderable:
		public VideoRenderable
	{
		public:
			DependantRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type			// How/when to execute the renderable
			);

			~DependantRenderable();

			void
				AddDependantRenderable(Component *dependant);

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			SChainOf<Component*>
				dependantRenderableSocket;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ScalarTriggerRenderable
// This renderable will run all it's dependants whenever a scalar value that
// it's watching changes.
//
	class ScalarTriggerRenderable:
		public DependantRenderable
	{
		public:
			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
			);

			~ScalarTriggerRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			Scalar
				*myWatchedValue,			// Pointer to the Scalar we're watching
				myOldWatchedValue,      // The last value of that scalar we saw
				myPrecision;				// Change must be at least this big to register

	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// TimeCullRenderable
// This renderable will run all it's dependants at a set frequency based on
// a clock value supplied by the culling system.
//
	class TimeCullRenderable:
		public DependantRenderable
	{
		public:
			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
			);

			~TimeCullRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			Scalar
				nextRunTime,
				delayBetweenRuns;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// MechCullRenderable
//
	class MechCullRenderable:
		public DependantRenderable
	{
		public:
			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
				dpl_ZONE					*my_zone             // Switch off this zone when the mech goes off screen
			);

			~MechCullRenderable();

			Logical
				TestInstance() const;
			void
				AddDependantLegRenderable(Component *dependant);
			void
				Execute();

		protected:
			Logical
				myMechWasVisible,
				myAlwaysRunAll;
			dpl_ZONE
				*myZone;
			Scalar
				myNextRootUpdate,
				myRootUpdateRate,
				myNextLegUpdate,
				myLegUpdateRate;
			SChainOf<Component*>
				legRenderableSocket;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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.
//

	class OnePSFXRenderable:
		public VideoRenderable
	{
		public:
			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
				dpl_DCS					*effect_DCS,			// DCS the effect is relative to (may be NULL)
				Point3D					*offset_point);		// Offset (or world coordinants if DCS is NULL)

			~OnePSFXRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			dpl_PARTICLESTART_EFFECT_INFO
				myPSFXInfo;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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.
//
	class TranslocationRenderable:
		public VideoRenderable
	{
	public:
		TranslocationRenderable(
			Entity					*entity,					// Entity to attach the renderable to
			ExecutionType			execution_type,		// How/when to execute the renderable
			dpl_ZONE					*this_zone,				// 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)
			);

		~TranslocationRenderable();

		Logical
			TestInstance() const;

	protected:
		enum TranslocateState
		{
			IdleState,
			InitialExpandState,
			HoldAtSizeState,
			ColapseState
		};

		TranslocateState
			myState;

		void
			Execute();

		int
			myDropZoneState,
			myEffectType;

		Scalar
			myEffectTimer;

		StateIndicator
			*myEffectTrigger;		// trigger effect when this changes

		dpl_INSTANCE
			*myInstance;

		dpl_DCS
			*myDCS;

		dpl_ZONE
			*myZone;

		Point3D
			*myDropZoneLocation;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SpinScaleQuatWatcherRenderable  This is used to create a laser style effect
// that has a directional control, scale and an axial spin at a pre-set speed
// (used for PPC's)
//
	class SpinScaleQuatWatcherRenderable:
		public ChildOffsetRenderable
	{
		public:
			SpinScaleQuatWatcherRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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)

			~SpinScaleQuatWatcherRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			StateIndicator
				*myControl;
			unsigned
				myTriggerState;
			Quaternion
				*myRotationQuaternion;
			Vector3D
				*myScaleVector;
			Logical
				myVisible;
			Scalar
				myZSpinRate,
				OldZSpin;
	};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ScaleQuatWatcherRenderable  This is used to create a laser style effect
// that has a directional control and scaling
//
	class ScaleQuatWatcherRenderable:
		public ChildOffsetRenderable
	{
		public:
			ScaleQuatWatcherRenderable(
				Entity					*entity,					// Entity to attach the renderable to
				ExecutionType			execution_type,		// How/when to execute the renderable
				dpl_OBJECT				*graphical_object,	// object to hang on the DCS, may be a list later <NULL>
				dpl_ZONE					*this_zone,				// 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
				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

			~ScaleQuatWatcherRenderable();

			Logical
				TestInstance() const;

			void
				Execute();

		protected:
			StateIndicator
				*myControl;
			unsigned
				myTriggerState;
			Quaternion
				*myRotationQuaternion;
			Vector3D
				*myScaleVector;
			Logical
				myVisible;
	};


#endif
