Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS

Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,936 @@
#include "ElementRendererHeaders.hpp"
#include <MLR\MLRFootstep.hpp>
#include <MLR\MLRSortByOrder.hpp>
#include <MLR\MLRTexturePool.hpp>
//############################################################################
//############################ CameraElement ###############################
//############################################################################
#if 0
MidLevelRenderer::MLRTexture *g_BergerName;
bool s_AbzugFlag = false;
bool g_AbzugFlag = false;
#endif
ElementRenderer::CameraElement::ClassData*
ElementRenderer::CameraElement::DefaultData = NULL;
ElementRenderer::Element::SyncMethod
ElementRenderer::CameraElement::SyncMethods[2]=
{
SYNC_METHOD(CameraElement, CleanCamera),
SYNC_METHOD(CameraElement, DirtyCamera)
};
ElementRenderer::Element::CullMethod
ElementRenderer::CameraElement::CullMethodObject=CULL_METHOD(CameraElement, CameraOnly, Always);
bool ElementRenderer::CameraElement::s_HideSky=false;
static bool __stdcall CheckHideSky() {return ElementRenderer::CameraElement::s_HideSky;}
static void __stdcall EnableHideSky() {ElementRenderer::CameraElement::s_HideSky = !ElementRenderer::CameraElement::s_HideSky;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::InitializeClass(Stuff::NotationFile *startup_ini)
{
Verify(!DefaultData);
DefaultData =
new ClassData(
CameraElementClassID,
"ElementRenderer::CameraElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Check_Object(DefaultData);
AddDebuggerMenuItem("Libraries\\Graphics Options\\Hide Sky", CheckHideSky, EnableHideSky, 0 );
if (startup_ini)
{
Check_Object(startup_ini);
Stuff::Page *page = startup_ini->FindPage("Graphics Options");
if (page)
{
Check_Object(page);
page->GetEntry("HideSky", &s_HideSky);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::TerminateClass(Stuff::NotationFile *startup_ini)
{
if (startup_ini)
{
Check_Object(startup_ini);
Stuff::Page *page = startup_ini->SetPage("Graphics Options");
Check_Object(page);
page->SetEntry("HideSky", s_HideSky);
}
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::CameraElement::CameraElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
):
GroupElement(DefaultData, stream, version, shapes),
m_scene(NULL)
{
Check_Pointer(this);
//
//----------------------------
// Initialize member variables
//----------------------------
//
m_state = NeverCullMode | MatrixDirtyFlag;
CameraElement::SetSyncState();
CameraElement::SetCullState();
CameraElement::SetDrawState();
//
//-----------------------------
// Create the attachment to MLR
//-----------------------------
//
gos_PushCurrentHeap(MidLevelRenderer::SorterHeap);
m_sorter = new MidLevelRenderer::MLRSortByOrder(MidLevelRenderer::MLRTexturePool::Instance);
Check_Object(m_sorter);
gos_PopCurrentHeap();
gos_PushCurrentHeap(MidLevelRenderer::ClipperHeap);
m_clipper = new MidLevelRenderer::MLRClipper(0, m_sorter);
Check_Object(m_clipper);
gos_PopCurrentHeap();
//
//-----------------------------------------
// Get the scene properties from the stream
//-----------------------------------------
//
m_viewingStateChange = new StateChange(stream, version);
Check_Object(m_viewingStateChange);
//
//----------------------------------
// Get the clip data from the stream
//----------------------------------
//
*stream >> m_nearLeft >> m_nearRight >> m_nearTop >> m_nearBottom;
*stream >> m_nearClip >> m_farClip;
SetPerspective(
m_nearClip,
m_farClip,
m_nearLeft,
m_nearRight,
m_nearTop,
m_nearBottom
);
//
//-----------------------------------
// Get the buffer flags and fog color
//-----------------------------------
//
*stream >> m_clearZBufferOnDraw >> m_clearBackBufferOnDraw;
if (version < 5)
{
Stuff::RGBAColor color;
*stream >> color;
}
m_viewPortLeft = 0.0f;
m_viewPortTop = 0.0f;
m_viewPortRight = 1.0f;
m_viewPortBottom = 1.0f;
m_acceptingElement = NULL;
m_drawSky = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::CameraElement::CameraElement(StateChange *properties):
GroupElement(DefaultData),
m_scene(NULL)
{
Check_Pointer(this);
Check_Object(properties);
//
//----------------------------
// Initialize member variables
//----------------------------
//
m_state = NeverCullMode | MatrixDirtyFlag;
CameraElement::SetSyncState();
CameraElement::SetCullState();
CameraElement::SetDrawState();
m_viewingStateChange = properties;
m_clearZBufferOnDraw = true;
m_clearBackBufferOnDraw = true;
m_drawSky = true;
m_fovAngle = Stuff::Pi_Over_3;
//m_scene = NULL;
m_useTintColor = false;
//
//--------------
// Build the sky
//--------------
//
//
//-----------------------------
// Create the attachment to MLR
//-----------------------------
//
gos_PushCurrentHeap(MidLevelRenderer::SorterHeap);
m_sorter = new MidLevelRenderer::MLRSortByOrder(MidLevelRenderer::MLRTexturePool::Instance);
Check_Object(m_sorter);
gos_PopCurrentHeap();
gos_PushCurrentHeap(MidLevelRenderer::ClipperHeap);
m_clipper = new MidLevelRenderer::MLRClipper(0, m_sorter);
Check_Object(m_clipper);
gos_PopCurrentHeap();
m_viewPortLeft = 0.0f;
m_viewPortTop = 0.0f;
m_viewPortRight = 1.0f;
m_viewPortBottom = 1.0f;
m_acceptingElement = NULL;
//상훈 앞
m_hsh_special_flag=false;
//상훈 뒤
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ElementRenderer::CameraElement::DeleteSky()
{
Element *sky = m_sky.GetCurrent();
if (sky)
{
Check_Object(sky);
delete sky;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::CameraElement::~CameraElement()
{
Check_Object(m_clipper);
delete m_clipper;
Check_Object(m_viewingStateChange);
delete m_viewingStateChange;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::CameraElement*
ElementRenderer::CameraElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(g_Heap);
CameraElement *element = new CameraElement(stream, version, shapes);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//--------------------------
// Save the scene properties
//--------------------------
//
Check_Object(m_viewingStateChange);
m_viewingStateChange->Save(stream);
//
//-------------------
// Save the clip data
//-------------------
//
*stream << m_nearLeft << m_nearRight << m_nearTop << m_nearBottom;
*stream << m_nearClip << m_farClip;
//
//--------------------------------
// Save buffer flags and fog color
//--------------------------------
//
*stream << m_clearZBufferOnDraw << m_clearBackBufferOnDraw;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::SetSyncState()
{
Check_Object(this);
Verify(GetCullMode() == NeverCullMode);
m_sync = SyncMethods[IsMatrixDirty()?1:0];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::CleanCameraSyncMethod()
{
Check_Object(this);
SYNC_LOGIC("Clean::Camera");
//
//------------------------------------------------------------------
// Concatenated our m_localToWorld from m_localToParent and our parent's
// m_localToWorld
//------------------------------------------------------------------
//
Check_Object(m_parent);
m_localToWorld.Multiply(m_localToParent, m_parent->GetLocalToWorld());
//
//--------------------------------------------
// Transform the local planes into world space
//--------------------------------------------
//
for (int i=0; i<CullingPlaneCount; ++i)
m_worldCullingPlanes[i].Multiply(
m_localCullingPlanes[i],
m_localToWorld
);
//
//--------------------------------------------
// Prepare 2D culling
//--------------------------------------------
//
m_cullFrustrumXZ[0] = m_localToWorld;
Stuff::UnitVector3D ur, uu, uf;
Stuff::Vector3D
right = Stuff::Vector3D::Identity,
forward = Stuff::Vector3D::Identity,
up = Stuff::Vector3D::Identity;
m_localToWorld.GetLocalRightInWorld(&ur);
m_localToWorld.GetLocalUpInWorld(&uu);
m_localToWorld.GetLocalForwardInWorld(&uf);
right.AddScaled(right, ur, Stuff::Fabs(m_nearRight*m_farClip/m_nearClip));
up.AddScaled(up, uu, Stuff::Fabs(m_nearTop*m_farClip/m_nearClip));
forward.AddScaled(forward, uf, Stuff::Fabs(m_farClip));
m_cullFrustrumXZ[1].Add(forward, up);
m_cullFrustrumXZ[2].Add(forward, up);
up.Negate(up);
m_cullFrustrumXZ[3].Add(forward, up);
m_cullFrustrumXZ[4].Add(forward, up);
m_cullFrustrumXZ[2].Add(m_cullFrustrumXZ[2], right);
m_cullFrustrumXZ[3].Add(m_cullFrustrumXZ[3], right);
right.Negate(right);
m_cullFrustrumXZ[1].Add(m_cullFrustrumXZ[1], right);
m_cullFrustrumXZ[4].Add(m_cullFrustrumXZ[4], right);
for(i=1;i<5;i++)
{
m_cullFrustrumXZ[i].Add(m_cullFrustrumXZ[i], m_cullFrustrumXZ[0]);
m_cullFrustrumXZ[i].y = 0.0f;
}
m_cullFrustrumXZ[0].y = 0.0f;
#if 0
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[0].x, m_cullFrustrumXZ[0].y, m_cullFrustrumXZ[0].z));
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[1].x, m_cullFrustrumXZ[1].y, m_cullFrustrumXZ[1].z));
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[2].x, m_cullFrustrumXZ[2].y, m_cullFrustrumXZ[2].z));
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[3].x, m_cullFrustrumXZ[3].y, m_cullFrustrumXZ[3].z));
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[4].x, m_cullFrustrumXZ[4].y, m_cullFrustrumXZ[4].z));
SPEW(("micgaert", "\n"));
#endif
//
//--------------------
// Update our children
//--------------------
//
Stuff::ChainIteratorOf<Element*> children(&m_group);
Element *child;
while ((child = children.ReadAndNext()) != NULL)
{
Check_Object(child);
child->Sync();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::DirtyCameraSyncMethod()
{
Check_Object(this);
SYNC_LOGIC("Dirty::Camera");
//
//------------------------------------------------------
// If the local-to-parent matrix is dirty, make it clean
//------------------------------------------------------
//
m_localToParent = m_newLocalToParent;
MatrixIsClean();
CleanCameraSyncMethod();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::SetCullState()
{
Check_Object(this);
m_cameraCull = CullMethodObject.m_cameraCull;
m_rayCull = CullMethodObject.m_rayCull;
m_sphereTest = CullMethodObject.m_sphereTest;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ElementRenderer::CameraElement::CameraOnlyCullMethod(CameraElement *camera)
{
Check_Object(this);
Check_Object(camera);
return (camera != this) ? -1 : 0;
}
//상훈 앞
void __cdecl ClearTargetCameraBackBuffer();
//상훈 뒤
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::DrawScene(bool gosClearedScreen)
{
Check_Object(this);
//
//-----------------------------
// Tell MLR where the camera is
//-----------------------------
//
ELEMENT_RENDER("DrawScene");
Start_Timer(Total_Video);
#if 0
if (g_AbzugFlag)
{
m_viewingStateChange->DisableChildTextureHandleControl();
m_viewingStateChange->DisableChildAlphaControl ();
m_viewingStateChange->SetAlphaMode (MidLevelRenderer::MLRState::AlphaMode::OneZeroMode);
m_viewingStateChange->SetTextureHandle (g_BergerName->GetTextureHandle ());
}
#endif
bool secondary = false;
{
ELEMENT_RENDER("Setup & Sky");
Start_Timer(Setup_Sky);
Check_Object(m_clipper);
Check_Object(m_viewingStateChange);
if(m_useTintColor)
{
FadeColor = m_tintColor;
}
else
{
FadeColor = Stuff::RGBAColor::White;
}
m_acceptingElement = NULL;
if (m_clearZBufferOnDraw)
{
Stuff::Scalar z=1.0f;
if (m_clearBackBufferOnDraw)
{
m_clipper->StartDraw(
m_localToWorld,
m_cameraToClip,
Stuff::RGBAColor::Unassigned,
&StateChange::GetFogColor(),
m_viewingStateChange->GetMLRState(),
&z
);
}
else
{
m_clipper->StartDraw(
m_localToWorld,
m_cameraToClip,
Stuff::RGBAColor::Unassigned,
NULL,
m_viewingStateChange->GetMLRState(),
&z
);
}
}
else
{
if (m_clearBackBufferOnDraw)
{
m_clipper->StartDraw(
m_localToWorld,
m_cameraToClip,
Stuff::RGBAColor::Unassigned,
&StateChange::GetFogColor(),
m_viewingStateChange->GetMLRState(),
NULL
);
}
else
{
//
//-----------------------------------------
//This means that we are a secondary camera
//-----------------------------------------
//
//상훈 앞
if(m_hsh_special_flag){
ClearTargetCameraBackBuffer();
}
//상훈 뒤
m_clipper->StartDraw(
m_localToWorld,
m_cameraToClip,
Stuff::RGBAColor::Unassigned,
NULL,
m_viewingStateChange->GetMLRState(),
NULL
);
secondary = true;
}
}
//
//---------------------------------
//Setup the Viewport for the camera
//---------------------------------
//
MidLevelRenderer::SetViewportScalars(
m_viewPortTop,
m_viewPortLeft,
m_viewPortBottom,
m_viewPortRight
);
if(secondary)
{
if(gosClearedScreen==false)
{
MidLevelRenderer::ClearZBuffer();
}
GetClipper()->SetCurrentState();
}
//
//------------------------------------------------------------------------
// If the sky is active, draw it first after moving it to where the camera
// is
//------------------------------------------------------------------------
//
else // Don't update LastCameraPosition for any camera but the main one.
{
gosFX::Effect::LastCameraPosition = GetLocalToWorld();
}
if (m_sky.GetCurrent() && !s_HideSky && m_drawSky && m_scene.GetCurrent())
{
Element *sky = m_sky.GetCurrent();
Check_Object(sky);
Stuff::LinearMatrix4D sky_to_parent = sky->GetLocalToParent();
sky_to_parent.BuildTranslation(gosFX::Effect::LastCameraPosition);
sky->SetLocalToParent(sky_to_parent);
sky->Sync();
DrawElement(sky, m_viewingStateChange);
}
Stop_Timer(Setup_Sky);
}
//
//---------------------------------------------
// Traverse the scene, and tell MLR we are done
//---------------------------------------------
//
if(m_scene.GetCurrent())
{
ELEMENT_RENDER("Culling");
Check_Object(m_scene.GetCurrent());
Start_Timer(Graph_Traversal);
DrawElement(m_scene.GetCurrent(), m_viewingStateChange);
Stop_Timer(Graph_Traversal);
}
if(!secondary && (MidLevelRenderer::MLRFootStep::Instance!=NULL) )
{
MidLevelRenderer::MLRFootStep::Instance->Draw(m_clipper, GetLocalToWorld());
}
{
ELEMENT_RENDER("Rasterizing");
Start_Timer(Render);
//상훈
extern bool sh_isdeathmode;
if(!sh_isdeathmode)
m_clipper->RenderNow();
Stop_Timer(Render);
}
FadeColor = Stuff::RGBAColor::White;
Stop_Timer(Total_Video);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::CastShadow(
const Stuff::LinearMatrix4D &shadow_to_world,
const Stuff::UnitVector3D &sun_in_world,
Stuff::Scalar radius
)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::MakeFootStep(
MidLevelRenderer::MLRShape *shape,
const Stuff::LinearMatrix4D &foot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *tex
)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::SetScene(Element *scene)
{
Check_Object(this);
m_scene.Remove();
if (scene != NULL)
{
m_scene.Add(scene);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::AdoptSkyElement(Element *sky)
{
Check_Object(this);
Check_Object(sky);
//
//----------------------------------------------------------------------
// Make sure that the sky element only writes to the z-buffer and is not
// fogged
//----------------------------------------------------------------------
//
m_sky.Remove();
m_sky.Add(sky);
StateChange *state = sky->GetStateChange();
if (!state)
{
state = new StateChange;
Check_Object(state);
sky->AdoptStateChange(state);
}
state->DisableBackfaceCulling();
state->DisableChildBackfaceControl();
state->SetFogMode(StateChange::DisableFogMode);
state->DisableChildFogControl();
state->DisableZBufferWrite();
state->DisableChildZBufferWriteControl();
state->DisableZBufferCompare();
state->DisableChildZBufferCompareControl();
state->DisableTextureWrap();
state->DisableChildTextureWrapControl();
state->SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode);
state->DisableChildFilterControl();
state->EnableDrawNow();
state->DisableChildDrawNowControl();
sky->SetRootMode();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::SetPerspective(
Stuff::Scalar near_clip,
Stuff::Scalar far_clip,
Stuff::Scalar left_clip,
Stuff::Scalar right_clip,
Stuff::Scalar top_clip,
Stuff::Scalar bottom_clip
)
{
Check_Object(this);
Verify(far_clip - near_clip > Stuff::SMALL);
Verify(left_clip - right_clip > Stuff::SMALL);
Verify(top_clip - bottom_clip > Stuff::SMALL);
m_nearClip = near_clip;
m_farClip = far_clip;
m_nearLeft = left_clip;
m_nearRight = right_clip;
m_nearTop = top_clip;
m_nearBottom = bottom_clip;
//
//-------------------------------------------------------
// Calculate the horizontal, vertical, and forward ranges
//-------------------------------------------------------
//
Stuff::Scalar horizontal_range = APPLY_LEFT_SIGN(1.0f) / (left_clip - right_clip);
Stuff::Scalar vertical_range = APPLY_UP_SIGN(1.0f) / (top_clip - bottom_clip);
Stuff::Scalar depth_range = APPLY_FORWARD_SIGN(1.0f) / (far_clip - near_clip);
//
//------------------------------------------------------------------------
// Set up the camera to clip matrix. This matrix takes camera space
// coordinates and maps them into a homogeneous culling space where valid
// X, Y, and Z axis values (when divided by W) will all be between 0 and 1
//------------------------------------------------------------------------
//
m_cameraToClip(LEFT_AXIS, LEFT_AXIS) = near_clip * horizontal_range;
m_cameraToClip(LEFT_AXIS, UP_AXIS) = 0.0f;
m_cameraToClip(LEFT_AXIS, FORWARD_AXIS) = 0.0f;
m_cameraToClip(LEFT_AXIS, 3) = 0.0f;
m_cameraToClip(UP_AXIS, LEFT_AXIS) = 0.0f;
m_cameraToClip(UP_AXIS, UP_AXIS) = near_clip * vertical_range;
m_cameraToClip(UP_AXIS, FORWARD_AXIS) = 0.0f;
m_cameraToClip(UP_AXIS, 3) = 0.0f;
m_cameraToClip(FORWARD_AXIS, LEFT_AXIS) = -right_clip * horizontal_range;
m_cameraToClip(FORWARD_AXIS, UP_AXIS) = -bottom_clip * vertical_range;
m_cameraToClip(FORWARD_AXIS, FORWARD_AXIS) = far_clip * depth_range;
m_cameraToClip(FORWARD_AXIS, 3) = 1.0f;
m_cameraToClip(3, LEFT_AXIS) = 0.0f;
m_cameraToClip(3, UP_AXIS) = 0.0f;
m_cameraToClip(3, FORWARD_AXIS) = -far_clip * near_clip * depth_range;
m_cameraToClip(3, 3) = 0.0f;
//
//-----------------------------------------------------------------------
// Now, set up the far and near clip planes. They are always parallel to
// the X-Y plane
//-----------------------------------------------------------------------
//
int index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::NearClipBit - 1;
m_localCullingPlanes[index].offset = -near_clip;
m_localCullingPlanes[index].normal = Stuff::UnitVector3D::Backward;
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::FarClipBit - 1;
m_localCullingPlanes[index].offset = far_clip;
m_localCullingPlanes[index].normal = Stuff::UnitVector3D::Forward;
//
//------------------------------------------------------------------------
// Set up the left culling plane. Given right-handed points, create three
// vertices from the clip data
//------------------------------------------------------------------------
//
Stuff::Scalar growth = far_clip / near_clip;
Stuff::Scalar far_left = left_clip * growth;
Stuff::Scalar far_right = right_clip * growth;
Stuff::Scalar far_top = top_clip * growth;
Stuff::Scalar far_bottom = bottom_clip * growth;
Stuff::Point3D
point1,
point2,
point3;
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
point1[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
point1[FORWARD_AXIS] = APPLY_FORWARD_SIGN(near_clip);
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
point2[UP_AXIS] = APPLY_UP_SIGN(top_clip);
point2[FORWARD_AXIS] = APPLY_FORWARD_SIGN(near_clip);
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_left);
point3[UP_AXIS] = APPLY_UP_SIGN(top_clip);
point3[FORWARD_AXIS] = APPLY_FORWARD_SIGN(far_clip);
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::LeftClipBit - 1;
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
//
//-------------------------------
// Set up the right culling plane
//-------------------------------
//
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
point1[UP_AXIS] = APPLY_UP_SIGN(top_clip);
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
point2[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_right);
point3[UP_AXIS] = APPLY_UP_SIGN(far_bottom);
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::RightClipBit - 1;
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
//
//-----------------------------
// Set up the top culling plane
//-----------------------------
//
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
point2[UP_AXIS] = APPLY_UP_SIGN(top_clip);
point3[UP_AXIS] = APPLY_UP_SIGN(far_top);
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::TopClipBit - 1;
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
//
//--------------------------------
// Set up the bottom culling plane
//--------------------------------
//
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
point1[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
point2[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_left);
point3[UP_AXIS] = APPLY_UP_SIGN(far_bottom);
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::BottomClipBit - 1;
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::SetPerspective(
Stuff::Scalar near_clip,
Stuff::Scalar far_clip,
const Stuff::Radian &horizontal_fov,
Stuff::Scalar height_to_width
)
{
Check_Object(this);
Verify(far_clip - near_clip > Stuff::SMALL);
Verify(horizontal_fov > Stuff::SMALL);
Verify(height_to_width > Stuff::SMALL);
//
//-------------------------------------------------------------
// Calculate the near plane offsets to the side culling planes
//-------------------------------------------------------------
//
Stuff::Scalar width = near_clip * Stuff::Tan(horizontal_fov*0.5f);
Stuff::Scalar height = width * height_to_width;
m_fovAngle = horizontal_fov;
SetPerspective(near_clip, far_clip, width, -width, height, -height);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::CameraElement::GetPerspective(
Stuff::Scalar &near_clip,
Stuff::Scalar &far_clip,
Stuff::Scalar &horizontal_fov,
Stuff::Scalar &height_to_width
)
{
near_clip = m_nearClip;
far_clip = m_farClip;
horizontal_fov = Stuff::Arctan(m_nearLeft, m_nearClip)*2.0f;
height_to_width = m_nearTop / m_nearLeft;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementRenderer::CameraElement::CastCulledRay(CollisionQuery *query)
{
Check_Object(this);
Check_Object(query);
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::Element*
ElementRenderer::CameraElement::FindSmallestElementContainingCulled(SphereTest *test)
{
Check_Object(this);
Check_Object(test);
return NULL;
}
@@ -0,0 +1,295 @@
#pragma once
#include "ElementRenderer.hpp"
#include "GroupElement.hpp"
#include "ListElement.hpp"
namespace MidLevelRenderer {
class MLRClipper;
class MLRSorter;
}
namespace ElementRenderer {
class ListElement;
//#########################################################################
//######################## CameraElement ################################
//#########################################################################
class CameraElement:
public GroupElement
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass(Stuff::NotationFile *startup_ini);
static void TerminateClass(Stuff::NotationFile *startup_ini);
static ClassData *DefaultData;
typedef GroupElement BaseClass;
static bool s_HideSky;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
CameraElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
public:
CameraElement(StateChange *properties);
~CameraElement();
static CameraElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Matrix support
//
protected:
void SetSyncState();
static SyncMethod SyncMethods[2];
void CleanCameraSyncMethod();
void DirtyCameraSyncMethod();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Culling
//
public:
void SetPerspective(
Stuff::Scalar near_clip,
Stuff::Scalar far_clip,
Stuff::Scalar left_clip,
Stuff::Scalar right_clip,
Stuff::Scalar top_clip,
Stuff::Scalar bottom_clip
);
void SetPerspective(
Stuff::Scalar near_clip,
Stuff::Scalar far_clip,
const Stuff::Radian &horizontal_fov,
Stuff::Scalar height_to_width = 0.75f
);
void GetPerspective(
Stuff::Scalar &near_clip,
Stuff::Scalar &far_clip,
Stuff::Scalar &horizontal_fov,
Stuff::Scalar &height_to_width
);
enum {
CullingPlaneCount = 6
};
const Stuff::Plane& GetLocalCullingPlane(int index)
{
Check_Object(this);
Verify(static_cast<unsigned>(index)<CullingPlaneCount);
return m_localCullingPlanes[index];
}
const Stuff::Plane& GetWorldCullingPlane(int index)
{
Check_Object(this);
Verify(static_cast<unsigned>(index)<CullingPlaneCount);
return m_worldCullingPlanes[index];
}
void GetNearPlaneBorders(
Stuff::Scalar *left,
Stuff::Scalar *right,
Stuff::Scalar *top,
Stuff::Scalar *bottom,
Stuff::Scalar *n,
Stuff::Scalar *f
)
{
Check_Object(this); Check_Pointer(left); Check_Pointer(right);
Check_Pointer(top); Check_Pointer(bottom); Check_Pointer(n);
Check_Pointer(f);
*left = m_nearLeft; *right = m_nearRight; *top = m_nearTop;
*bottom = m_nearBottom; *n = m_nearClip; *f = m_farClip;
}
const Stuff::Point3D* GetCullPoints()
{ Check_Object(this); return m_cullFrustrumXZ; }
Stuff::Radian GetFOVAngle()
{Check_Object(this); return m_fovAngle;}
Stuff::Matrix4D& GetCameraToClip()
{Check_Object(this); return m_cameraToClip;}
protected:
void SetCullState();
int CameraOnlyCullMethod(CameraElement *camera);
static CullMethod CullMethodObject;
Stuff::Plane
m_localCullingPlanes[CullingPlaneCount],
m_worldCullingPlanes[CullingPlaneCount];
Stuff::Scalar
m_nearLeft,
m_nearRight,
m_nearTop,
m_nearBottom,
m_nearClip,
m_farClip;
Stuff::Radian m_fovAngle;
Stuff::Point3D m_cullFrustrumXZ[5];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
public:
void DrawElement(
Element *element,
const StateChange *inherited_state
)
{
Check_Object(this); Check_Object(element);
#if 0
if (m_acceptingElement)
{
element->DrawTo(this, inherited_state, 0);
}
else
{
int culling_state = element->Cull(this);
if (culling_state != -1)
element->DrawTo(this, inherited_state, culling_state);
m_acceptingElement = NULL;
}
#else
int culling_state = element->Cull(this);
if (culling_state != -1)
element->DrawTo(this, inherited_state, culling_state);
#endif
}
void
DrawScene(bool gosClearedScreen=false);
void CastShadow(
const Stuff::LinearMatrix4D &shadow_to_world,
const Stuff::UnitVector3D &sun_in_world,
Stuff::Scalar radius
);
void MakeFootStep(
MidLevelRenderer::MLRShape *shape,
const Stuff::LinearMatrix4D &foot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *tex
);
void SetScene(Element *scene);
Element* GetScene()
{Check_Object(this); return m_scene.GetCurrent();}
void AdoptSkyElement(Element *sky);
Element* GetSky()
{Check_Object(this); return m_sky.GetCurrent();}
StateChange* GetViewingStateChange()
{Check_Object(this); return m_viewingStateChange;}
MidLevelRenderer::MLRClipper* GetClipper()
{Check_Object(this); return m_clipper;}
void ClearZBeforeDraw(bool flag)
{Check_Object(this); m_clearZBufferOnDraw = flag;}
void ClearBackBufferBeforeDraw(bool flag)
{Check_Object(this); m_clearBackBufferOnDraw = flag;}
void DrawSky(bool flag)
{Check_Object(this); m_drawSky = flag;}
void SetSecondaryCamera()
{Check_Object(this); m_clearZBufferOnDraw = false; m_clearBackBufferOnDraw = false;}
void DeleteSky();
void SetTintColor(Stuff::RGBAColor *tint_color)
{Check_Object(this); m_tintColor = *tint_color; m_useTintColor = true;}
void ClearTintColor(Stuff::RGBAColor *tint_color)
{Check_Object(this); m_tintColor = Stuff::RGBAColor::White; m_useTintColor = false;}
void SetViewport(
Stuff::Scalar x_position,
Stuff::Scalar y_position,
Stuff::Scalar width,
Stuff::Scalar height
)
{
Check_Object(this);
m_viewPortLeft = x_position;
m_viewPortTop = y_position;
m_viewPortRight = width;
m_viewPortBottom = height;
}
void GetViewport (Stuff::Scalar& left,Stuff::Scalar& top,Stuff::Scalar& right,Stuff::Scalar& bottom)
{
left = m_viewPortLeft;
top = m_viewPortTop;
right = m_viewPortRight;
bottom = m_viewPortBottom;
}
Element *m_acceptingElement;
protected:
bool
m_clearZBufferOnDraw,
m_clearBackBufferOnDraw,
m_drawSky;
MidLevelRenderer::MLRClipper *m_clipper;
MidLevelRenderer::MLRSorter *m_sorter;
Stuff::SlotOf<Element *> m_sky;
Stuff::SlotOf<Element*> m_scene;
Stuff::Matrix4D m_cameraToClip;
StateChange *m_viewingStateChange;
Stuff::Scalar
m_viewPortLeft,
m_viewPortTop,
m_viewPortRight,
m_viewPortBottom;
Stuff::RGBAColor m_tintColor;
bool m_useTintColor;
//»óÈÆ ¾Õ
public:
bool m_hsh_special_flag;
void SetHSHSpecialFlag(bool new_flag){
m_hsh_special_flag=new_flag;
}
//»óÈÆ µÚ
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,749 @@
#pragma once
#include "ElementRenderer.hpp"
#include <MLR\MLR.hpp>
#include <MLR\GOSVertex.hpp>
namespace MidLevelRenderer {
class MLRLight;
class MLRTexture;
class MLRShape;
}
namespace ElementRenderer {
class CameraElement;
class StateChange;
class Element__ClassData;
typedef MidLevelRenderer::MLRLight* LightList[MidLevelRenderer::Limits::Max_Number_Of_Lights_Per_Primitive];
class CollisionQuery
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
CollisionQuery(Stuff::Line3D *l, Stuff::Normal3D *n):
m_line(l),
m_normal(n),
m_data(NULL)
{Check_Pointer(this);}
Stuff::Line3D *m_line;
Stuff::Normal3D *m_normal;
void *m_data;
BYTE m_material;
void TestInstance() const
{}
};
class SphereTest
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
enum TestCase {
Disjoint=0,
Intersects=1,
Contains=2,
Contained=4
};
Stuff::Sphere m_sphere;
int m_type;
void TestInstance() const
{}
};
//#########################################################################
//########################### Element ###################################
//#########################################################################
class _declspec(novtable) Element:
public Stuff::Plug
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
typedef Element__ClassData ClassData;
static ClassData *DefaultData;
typedef Stuff::Plug BaseClass;
static Stuff::RGBAColor FadeColor;
typedef MidLevelRenderer::MLRShape* (*ShapeHolder)(
Stuff::MemoryStream *stream,
int version,
int length
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
Element(ClassData *class_data);
explicit Element(
ClassData *class_data,
Element *element
);
Element(
ClassData *class_data,
Stuff::MemoryStream *stream,
int version
);
public:
~Element();
typedef Element* (*Factory)(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
virtual void Save(Stuff::MemoryStream *stream);
static Element* Create(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
Element* GetParentElement()
{Check_Object(this); return m_parent;}
void DetachFromParent()
{
Check_Object(this); Check_Object(m_parent);
m_parent->DetachChild(this); Verify(!m_parent);
}
void AttachToParent(Element *parent)
{
Check_Object(this); Check_Object(parent);
Verify(!m_parent); parent->AttachChild(this);
Check_Object(m_parent);
}
virtual void AttachChild(Element *child)=0;
virtual void DetachChild(Element *child)=0;
void SetClientData(void *data)
{Check_Object(this); m_data = data;}
void* GetClientData()
{Check_Object(this); return m_data;}
protected:
static void SetParentElement(
Element *child,
Element *parent
)
{Check_Object(child); child->m_parent = parent;}
Element *m_parent;
void *m_data;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// States
//
public:
enum {
LocalToParentIsIdentityBit = 0,
BoundsLockedBit,
SyncStateBit,
MatrixDirtyBit = SyncStateBit,
BoundsWrongBit,
SyncOnCullBit,
CullStateBit,
OBBBit = CullStateBit,
CullBit,
CullBits = 2,
AlignXBit = CullBit+CullBits,
SyncStateBits = AlignXBit - SyncStateBit,
AlignYBit = AlignXBit+1,
DrawStateBit,
CullStateBits = DrawStateBit - CullStateBit,
PropertyChangeBit = DrawStateBit,
DrawStateBits = 1,
CallbackBit = DrawStateBit+1,
CallbackBits = 3,
NoShadowBit = CallbackBit+CallbackBits
};
enum {
LocalToParentIsIdentityFlag = 1<<LocalToParentIsIdentityBit,
BoundsLockedFlag = 1<<BoundsLockedBit,
SyncStateMask = 0xFFFFFFFF >> (Stuff::INT_BITS - SyncStateBits),
SyncStateCount = 1<<SyncStateBits,
MatrixDirtyFlag = 1<<MatrixDirtyBit,
BoundsWrongFlag = 1<<BoundsWrongBit,
SyncOnCullFlag = 1<<SyncOnCullBit,
OBBFlag = 1<<OBBBit,
CullMask = (0xFFFFFFFF >> (Stuff::INT_BITS - CullBits)) << CullBit,
RootMode = 0,
VolumeCullMode = 1<<CullBit,
NeverCullMode = 2<<CullBit,
AlwaysCullMode = 3<<CullBit,
CullStateMask = 0xFFFFFFFF >> (Stuff::INT_BITS - CullStateBits),
CullStateCount = 1<<CullStateBits,
AlignXFlag = 1<<AlignXBit,
AlignYFlag = 1<<AlignYBit,
DrawStateMask = 0xFFFFFFFF >> (Stuff::INT_BITS - DrawStateBits),
DrawStateCount = 1<<DrawStateBits,
PropertyChangeFlag = 1<<PropertyChangeBit,
CallbackMask = (0xFFFFFFFF >> (Stuff::INT_BITS - CallbackBits)) << CallbackBit,
NoShadowFlag = 1<<NoShadowBit
};
bool IsLocalToParentIdentity()
{Check_Object(this); return (m_state & LocalToParentIsIdentityFlag) != 0;}
void LockBounds()
{Check_Object(this); m_state |= BoundsLockedFlag;}
void UnlockBounds()
{Check_Object(this); m_state &= ~BoundsLockedFlag;}
bool AreBoundsLocked()
{Check_Object(this); return (m_state & BoundsLockedFlag) != 0;}
void NeedMatrixSync()
{Check_Object(this); m_state |= MatrixDirtyFlag; SetSyncState();}
bool IsMatrixDirty()
{Check_Object(this); return (m_state & MatrixDirtyFlag) != 0;}
void NeedNewBounds()
{
Check_Object(this);
m_state &= ~CullMask;
m_state |= BoundsWrongFlag|VolumeCullMode;
Verify(!IsBoundedByOBB());
SetSyncState(); SetCullState();
}
bool AreBoundsWrong()
{Check_Object(this); return (m_state & BoundsWrongFlag) != 0;}
void ImmediateSync()
{Check_Object(this); m_state &= ~SyncOnCullFlag;}
void DeferredSync()
{Check_Object(this); m_state |= SyncOnCullFlag;}
bool IsSyncDeferred()
{Check_Object(this); return (m_state & SyncOnCullFlag) != 0;}
void SetOBBMode()
{
Check_Object(this); m_state |= OBBFlag;
SetSyncState(); SetCullState();
}
void SetSphereMode()
{
Check_Object(this); m_state &= ~OBBFlag;
SetSyncState(); SetCullState();
}
bool IsBoundedByOBB()
{Check_Object(this); return (m_state&OBBFlag) != 0;}
bool IsBoundedBySphere()
{Check_Object(this); return !(m_state&OBBFlag);}
void SetRootMode()
{
Check_Object(this);
m_parent = NULL;
m_state &= ~CullMask;
m_state |= RootMode;
SetSyncState(); SetCullState();
}
void SetAlwaysCullMode()
{
Check_Object(this);
Check_Object(m_parent);
m_state &= ~CullMask;
m_state |= AlwaysCullMode;
SetSyncState(); SetCullState();
}
void SetVolumeCullMode()
{
Check_Object(this);
Check_Object(m_parent);
m_state &= ~CullMask;
m_state |= VolumeCullMode|MatrixDirtyFlag;
SetSyncState(); SetCullState();
}
void SetNeverCullMode()
{
Check_Object(this);
Check_Object(m_parent);
m_state &= ~CullMask;
m_state |= NeverCullMode;
SetSyncState(); SetCullState();
}
unsigned GetCullMode()
{Check_Object(this); return m_state & CullMask;}
void SetCullMode(unsigned cullMode)
{
Check_Object(this);
m_state = (m_state & (~CullMask)) | cullMode;
SetSyncState(); SetCullState();
}
void SetAlignX()
{
Check_Object(this); m_state |= AlignXFlag|SyncOnCullFlag;
SetSyncState(); SetCullState();
}
void ClearAlignX()
{
Check_Object(this); m_state &= ~(AlignXFlag|SyncOnCullFlag);
SetSyncState(); SetCullState();
}
bool IsAlignX()
{Check_Object(this); return (m_state&AlignXFlag) != 0;}
void SetAlignY()
{
Check_Object(this); m_state |= AlignYFlag|SyncOnCullFlag;
SetSyncState(); SetCullState();
}
void ClearAlignY()
{
Check_Object(this); m_state &= ~(AlignYFlag|SyncOnCullFlag);
SetSyncState(); SetCullState();
}
bool IsShadowed()
{Check_Object(this); return (m_state&NoShadowFlag) == 0;}
void DisableShadow()
{Check_Object(this); m_state |= NoShadowFlag;}
void EnableShadow()
{Check_Object(this); m_state &= ~NoShadowFlag;}
bool IsAlignY()
{Check_Object(this); return (m_state&AlignYFlag) != 0;}
unsigned GetElementState()
{Check_Object(this); return m_state;}
void SetElementState(unsigned state)
{
Check_Object(this); m_state = state;
SetSyncState(); SetCullState(); SetDrawState();
}
static void ReadStateFromPage(
Stuff::Page *page,
const Stuff::MString &prefix,
unsigned *state,
unsigned *delta,
Stuff::OBB *bounds
);
protected:
unsigned m_state;
void MatrixIsClean()
{
Check_Object(this);
m_state &= ~MatrixDirtyFlag; SetSyncState();
}
void BoundsAreRight()
{
Check_Object(this);
m_state &= ~BoundsWrongFlag; SetSyncState();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sync support
//
public:
typedef void (Element::*SyncMethod)();
void SetLocalToParent(const Stuff::LinearMatrix4D& matrix)
{
Check_Object(this); Check_Object(&matrix);
m_state &= ~LocalToParentIsIdentityFlag;
NeedMatrixSync(); m_newLocalToParent = matrix;
}
void SetLocalToParentToIdentity()
{
Check_Object(this);
m_state |= LocalToParentIsIdentityFlag|MatrixDirtyFlag;
SetSyncState();
m_newLocalToParent = Stuff::LinearMatrix4D::Identity;
}
const Stuff::LinearMatrix4D& GetLocalToParent()
{Check_Object(this); return m_localToParent;}
const Stuff::LinearMatrix4D& GetNewLocalToParent()
{Check_Object(this); return m_newLocalToParent;}
const Stuff::LinearMatrix4D& GetLocalToWorld()
{
Check_Object(this); Check_Object(&m_localToWorld);
return m_localToWorld;
}
void Sync()
{
Check_Object(this);
Verify(m_sync != NULL);
(this->*m_sync)();
}
protected:
virtual void SetSyncState();
SyncMethod m_sync;
static SyncMethod SyncMethods[SyncStateCount];
Stuff::LinearMatrix4D
m_newLocalToParent,
m_localToParent,
m_localToWorld;
void NoneSyncMethod();
void DirtyRootSyncMethod();
void DeferSyncMethod();
void CleanSyncMethod();
void DirtySyncMethod();
void CleanSphereSyncMethod();
void DirtySphereSyncMethod();
void CleanOBBSyncMethod();
void DirtyOBBSyncMethod();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Culling
//
public:
typedef int (Element::*CameraCullMethod)(CameraElement *camera);
typedef bool (Element::*RayCullMethod)(CollisionQuery *query);
typedef int (Element::*SphereTestMethod)(SphereTest *test);
struct CullMethod {
CameraCullMethod m_cameraCull;
RayCullMethod m_rayCull;
SphereTestMethod m_sphereTest;
};
int Cull(CameraElement *camera)
{
Check_Object(this); Check_Pointer(camera);
Verify(m_cameraCull != NULL);
return (this->*m_cameraCull)(camera);
}
const Stuff::OBB& GetWorldOBB()
{Check_Object(this); return m_worldOBB;}
Stuff::OBB m_localOBB;
protected:
Stuff::OBB m_worldOBB;
virtual void SetCullState();
CameraCullMethod m_cameraCull;
RayCullMethod m_rayCull;
SphereTestMethod m_sphereTest;
static CullMethod CullMethods[CullStateCount];
int NeverCullMethod(CameraElement *camera);
int AlwaysCullMethod(CameraElement *camera);
int SphereCullMethod(CameraElement *camera);
int OBBCullMethod(CameraElement *camera);
void AlignX(CameraElement *camera);
int DeferredXNeverCullMethod(CameraElement *camera);
int DeferredXAlwaysCullMethod(CameraElement *camera);
int DeferredXSphereCullMethod(CameraElement *camera);
int DeferredXOBBCullMethod(CameraElement *camera);
void AlignY(CameraElement *camera);
int DeferredYNeverCullMethod(CameraElement *camera);
int DeferredYAlwaysCullMethod(CameraElement *camera);
int DeferredYSphereCullMethod(CameraElement *camera);
int DeferredYOBBCullMethod(CameraElement *camera);
void AlignXY(CameraElement *camera);
int DeferredXYNeverCullMethod(CameraElement *camera);
int DeferredXYAlwaysCullMethod(CameraElement *camera);
int DeferredXYSphereCullMethod(CameraElement *camera);
int DeferredXYOBBCullMethod(CameraElement *camera);
bool NeverRayCullMethod(CollisionQuery *query);
bool AlwaysRayCullMethod(CollisionQuery *query);
bool SphereRayCullMethod(CollisionQuery *query);
bool OBBRayCullMethod(CollisionQuery *query);
int NeverSphereTestMethod(SphereTest *test);
int AlwaysSphereTestMethod(SphereTest *test);
int SphereSphereTestMethod(SphereTest *test);
int OBBSphereTestMethod(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
public:
bool CastRay(CollisionQuery *query)
{
Check_Object(this); Check_Object(query);
Verify(m_rayCull != NULL);
if ((this->*m_rayCull)(query))
return CastCulledRay(query);
return false;
}
Element* FindSmallestElementContaining(SphereTest *test)
{
Check_Object(this); Check_Object(test);
Verify(m_sphereTest != NULL);
Verify(test->m_type == SphereTest::Contains);
if (((this->*m_sphereTest)(test)&SphereTest::Contains) != 0)
return FindSmallestElementContainingCulled(test);
return NULL;
}
protected:
virtual bool CastCulledRay(CollisionQuery *query)=0;
virtual Element* FindSmallestElementContainingCulled(SphereTest *test)=0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
public:
typedef void (Element::*DrawMethod)(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
);
void DrawTo(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this); Check_Pointer(camera);
Verify(m_draw != NULL);
(this->*m_draw)(
camera,
inherited_state,
culling_state
);
}
virtual int CountTriangles()=0;
static int MixLights(
LightList new_lights,
const LightList parent_lights,
const LightList child_lights
);
virtual void CleanDamage();
virtual void ApplyDamage(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius
);
virtual void ApplyDamageDecal(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *texture
);
virtual void CastShadow(
const Stuff::LinearMatrix4D &shadow_to_world,
const Stuff::UnitVector3D &sun_in_world,
Stuff::Scalar radius
);
virtual void MakeFootStep(
MidLevelRenderer::MLRShape *shape,
const Stuff::LinearMatrix4D &foot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *tex
);
virtual MidLevelRenderer::MLRShape* GetMLRShape(CameraElement *camera=NULL)
{Check_Object(this); return NULL;}
virtual void GetCoordData(Stuff::DynamicArrayOf<Stuff::Point3D> *array);
protected:
virtual void SetDrawState()=0;
DrawMethod m_draw;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Debugging aids
//
public:
typedef void (*Callback)(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
enum {
DrawGreenBounds=1,
DrawYellowBounds,
DrawRedBounds,
DrawGreenBoundsOnce,
DrawYellowBoundsOnce,
DrawRedBoundsOnce
};
void SetCallbackIndex(unsigned function)
{
Check_Object(this); Verify(function < 1<<CallbackBits);
m_state &= ~CallbackMask; m_state |= function << CallbackBit;
}
unsigned GetCallbackIndex()
{Check_Object(this); return (m_state&CallbackMask)>>CallbackBit;}
static Callback* GetCallbackSet()
{return CallbackSet;}
static void UseCallbackSet(Callback *callback)
{CallbackSet = callback;}
static void DrawOBB(
const Stuff::OBB& obb,
const Stuff::RGBAColor& color,
CameraElement *camera,
const StateChange *state,
int culling_state
);
static void DrawSphere(
const Stuff::OBB& obb,
const Stuff::RGBAColor& color,
CameraElement *camera,
const StateChange *state,
int culling_state
);
static void DrawGreenBoundsCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static void DrawYellowBoundsCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static void DrawRedBoundsCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static void DrawGreenBoundsOnceCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static void DrawYellowBoundsOnceCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static void DrawRedBoundsOnceCallback(
CameraElement *camera,
const StateChange *state,
int culling_state,
Element *element
);
static Callback Callbacks[1<<CallbackBits];
protected:
static Callback *CallbackSet;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Properties
//
public:
StateChange* GetStateChange()
{Check_Object(this); return m_stateChange;}
void AdoptStateChange(StateChange *set);
void DestroyStateChange();
protected:
StateChange *m_stateChange;
};
#define SYNC_METHOD(t, s) static_cast<SyncMethod>(&t::s##SyncMethod)
#define CULL_METHOD(t, c, r)\
{\
static_cast<CameraCullMethod>(&t::c##CullMethod),\
static_cast<RayCullMethod>(&t::r##RayCullMethod),\
static_cast<SphereTestMethod>(&t::r##SphereTestMethod)\
}
#define DRAW_METHOD(t, d) static_cast<DrawMethod>(&t::d##DrawMethod)
//##########################################################################
//####################### Element__ClassData #########################
//##########################################################################
class Element__ClassData:
public Stuff::Plug__ClassData
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
public:
Element__ClassData(
Stuff::RegisteredClass::ClassID class_id,
const char* class_name,
Stuff::Plug__ClassData *parent_class,
Element::Factory element_factory
):
RegisteredClass__ClassData(class_id, class_name, parent_class),
m_elementFactory(element_factory)
{}
Element::Factory m_elementFactory;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
public:
void TestInstance();
};
}
@@ -0,0 +1,147 @@
#include "ElementRendererHeaders.hpp"
HGOSHEAP
ElementRenderer::g_LibraryHeap = NULL,
ElementRenderer::g_Heap = NULL;
DEFINE_TIMER(ElementRenderer, Total_Video);
DEFINE_TIMER(ElementRenderer, Graph_Traversal);
DEFINE_TIMER(ElementRenderer, Draw_Shapes);
DEFINE_TIMER(ElementRenderer, Draw_Scalable);
DEFINE_TIMER(ElementRenderer, Draw_Effects);
DEFINE_TIMER(ElementRenderer, Draw_Quads);
DEFINE_TIMER(ElementRenderer, Setup_Sky);
DEFINE_TIMER(ElementRenderer, Render);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::InitializeClasses(Stuff::NotationFile *startup_ini)
{
Verify(FirstFreeElementRendererClassID <= Stuff::LastElementRendererClassID);
Verify(!g_LibraryHeap);
g_LibraryHeap = gos_CreateMemoryHeap("ElementRenderer(All)");
Check_Pointer(g_LibraryHeap);
Verify(!g_Heap);
g_Heap = gos_CreateMemoryHeap("ElementRenderer", 0, g_LibraryHeap);
Check_Pointer(g_Heap);
gos_PushCurrentHeap(g_Heap);
#if !(defined(NO_STATS) && defined(NO_TIMERS))
StatisticFormat("");
StatisticFormat("Element Renderer");
StatisticFormat("================");
StatisticFormat("");
#endif
Element::InitializeClass();
GroupElement::InitializeClass();
CameraElement::InitializeClass(startup_ini);
ShapeElement::InitializeClass(startup_ini);
ListElement::InitializeClass();
SwitchElement::InitializeClass();
LODElement::InitializeClass(startup_ini);
PointCloudElement::InitializeClass();
TriangleCloudElement::InitializeClass();
ScalableShapeElement::InitializeClass();
ScreenQuadsElement::InitializeClass();
gosFXElement::InitializeClass();
StateChange::InitializeClass();
GridElement::InitializeClass();
LineCloudElement::InitializeClass();
LightElement::InitializeClass();
MultiLODElement::InitializeClass();
ShapeLODElement::InitializeClass();
TreeElement::InitializeClass();
gos_PopCurrentHeap();
//
//---------------
// Setup the menu
//---------------
//
Initialize_Timer(Total_Video, "Total Video");
Initialize_Timer(Setup_Sky, " Setup and Sky");
Initialize_Timer(Graph_Traversal, " Culling");
Initialize_Timer(Draw_Shapes, " Draw Shapes");
Initialize_Timer(Draw_Scalable, " Draw Scaling Shapes");
Initialize_Timer(Draw_Effects, " Draw MLR Effects");
Initialize_Timer(Draw_Quads, " Draw Screen Quads");
Initialize_Timer(Render, " Render to MLR");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::TerminateClasses(Stuff::NotationFile *startup_ini)
{
TreeElement::TerminateClass();
ShapeLODElement::TerminateClass();
MultiLODElement::TerminateClass();
LightElement::TerminateClass();
LineCloudElement::TerminateClass();
GridElement::TerminateClass();
StateChange::TerminateClass();
gosFXElement::TerminateClass();
ScreenQuadsElement::TerminateClass();
ScalableShapeElement::TerminateClass();
TriangleCloudElement::TerminateClass();
PointCloudElement::TerminateClass();
LODElement::TerminateClass(startup_ini);
SwitchElement::TerminateClass();
ListElement::TerminateClass();
ShapeElement::TerminateClass(startup_ini);
CameraElement::TerminateClass(startup_ini);
GroupElement::TerminateClass();
Element::TerminateClass();
Check_Pointer(g_Heap);
gos_DestroyMemoryHeap(g_Heap);
g_Heap = NULL;
Check_Pointer(g_LibraryHeap);
gos_DestroyMemoryHeap(g_LibraryHeap);
g_LibraryHeap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ElementRenderer::ReadERFVersion(Stuff::MemoryStream *erf_stream)
{
Check_Object(erf_stream);
//
//------------------------------------------------------------------------
// See if this file has an erf signature. If so, the next int will be the
// version number. If not, assume it is version 1 and rewind the file
//------------------------------------------------------------------------
//
int version = 1;
int erf_signature;
*erf_stream >> erf_signature;
if (erf_signature == 'ERF#')
*erf_stream >> version;
else
erf_stream->RewindPointer(sizeof(erf_signature));
if (version > CurrentERFVersion)
STOP(("Application must be rebuilt to use this version of ERF data"));
return version;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::WriteERFVersion(Stuff::MemoryStream *erf_stream)
{
Check_Object(erf_stream);
*erf_stream << 'ERF#' << static_cast<int>(CurrentERFVersion);
}
@@ -0,0 +1,707 @@
# Microsoft Developer Studio Project File - Name="ElementRenderer" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=ElementRenderer - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ElementRenderer.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ElementRenderer.mak" CFG="ElementRenderer - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ElementRenderer - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "ElementRenderer - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE "ElementRenderer - Win32 Armor" (based on "Win32 (x86) Static Library")
!MESSAGE "ElementRenderer - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "ElementRenderer - Win32 icecap" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/GameLeapCode/CoreTech/Libraries/ElementRenderer", TOAAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ElementRenderer - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../rel.bin"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /GR /Oa /Og /Oi /Oy /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /I "..\..\Libraries\stlport" /D "RELEASE" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /Yu"ElementRendererHeaders.hpp" /Zl /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ElementRenderer - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../pro.bin"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /Zi /O2 /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /I "..\..\Libraries\stlport" /D "LAB_ONLY" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /Yu"ElementRendererHeaders.hpp" /Zl /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ElementRenderer - Win32 Armor"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Armor"
# PROP BASE Intermediate_Dir "Armor"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../arm.bin"
# PROP Intermediate_Dir "Armor"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /GR /Zi /Ox /Ot /Oa /Og /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /I "..\..\Libraries\stlport" /D "LAB_ONLY" /D "NDEBUG" /D "_ARMOR" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /Yu"ElementRendererHeaders.hpp" /Zl /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ElementRenderer - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../dbg.bin"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MDd /W4 /GR /Zi /Od /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /I "..\..\Libraries\stlport" /D "_ARMOR" /D "LAB_ONLY" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /Yu"ElementRendererHeaders.hpp" /Zl /FD /c
# SUBTRACT CPP /WX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ElementRenderer - Win32 icecap"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "icecap"
# PROP BASE Intermediate_Dir "icecap"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../ice.bin"
# PROP Intermediate_Dir "icecap"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /G6 /Zp4 /MD /W4 /WX /Zi /Ox /Ot /Oa /Og /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "LAB_ONLY" /D "NDEBUG" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /Yu"ElementRendererHeaders.hpp" /Zl /FD /GF /c
# SUBTRACT BASE CPP /Fr
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /Zi /Ot /Oa /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /I "..\..\Libraries\stlport" /D "LAB_ONLY" /D "NDEBUG" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /D "_ICECAP" /Yu"ElementRendererHeaders.hpp" /Zl /FD /GF /c
# SUBTRACT CPP /WX /Og /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "ElementRenderer - Win32 Release"
# Name "ElementRenderer - Win32 Profile"
# Name "ElementRenderer - Win32 Armor"
# Name "ElementRenderer - Win32 Debug"
# Name "ElementRenderer - Win32 icecap"
# Begin Group "Elements"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\CameraElement.cpp
# End Source File
# Begin Source File
SOURCE=.\CameraElement.hpp
# End Source File
# Begin Source File
SOURCE=.\Element.cpp
# End Source File
# Begin Source File
SOURCE=.\Element.hpp
# End Source File
# Begin Source File
SOURCE=.\gosFXElement.cpp
# End Source File
# Begin Source File
SOURCE=.\gosFXElement.hpp
# End Source File
# Begin Source File
SOURCE=.\GridElement.cpp
# End Source File
# Begin Source File
SOURCE=.\GridElement.hpp
# End Source File
# Begin Source File
SOURCE=.\GroupElement.cpp
# End Source File
# Begin Source File
SOURCE=.\GroupElement.hpp
# End Source File
# Begin Source File
SOURCE=.\LightElement.cpp
# End Source File
# Begin Source File
SOURCE=.\LightElement.hpp
# End Source File
# Begin Source File
SOURCE=.\LineCloudElement.cpp
# End Source File
# Begin Source File
SOURCE=.\LineCloudElement.hpp
# End Source File
# Begin Source File
SOURCE=.\ListElement.cpp
# End Source File
# Begin Source File
SOURCE=.\ListElement.hpp
# End Source File
# Begin Source File
SOURCE=.\LODElement.cpp
# End Source File
# Begin Source File
SOURCE=.\LODElement.hpp
# End Source File
# Begin Source File
SOURCE=.\MultiLODElement.cpp
# End Source File
# Begin Source File
SOURCE=.\MultiLODElement.hpp
# End Source File
# Begin Source File
SOURCE=.\PointCloudElement.cpp
# End Source File
# Begin Source File
SOURCE=.\PointCloudElement.hpp
# End Source File
# Begin Source File
SOURCE=.\ScalableShapeElement.cpp
# End Source File
# Begin Source File
SOURCE=.\ScalableShapeElement.hpp
# End Source File
# Begin Source File
SOURCE=.\ScreenQuadsElement.cpp
# End Source File
# Begin Source File
SOURCE=.\ScreenQuadsElement.hpp
# End Source File
# Begin Source File
SOURCE=.\ShapeElement.cpp
# End Source File
# Begin Source File
SOURCE=.\ShapeElement.hpp
# End Source File
# Begin Source File
SOURCE=.\ShapeLODElement.cpp
# End Source File
# Begin Source File
SOURCE=.\ShapeLODElement.hpp
# End Source File
# Begin Source File
SOURCE=.\SwitchElement.cpp
# End Source File
# Begin Source File
SOURCE=.\SwitchElement.hpp
# End Source File
# Begin Source File
SOURCE=.\TreeElement.cpp
# End Source File
# Begin Source File
SOURCE=.\TreeElement.hpp
# End Source File
# Begin Source File
SOURCE=.\TriangleCloudElement.cpp
# End Source File
# Begin Source File
SOURCE=.\TriangleCloudElement.hpp
# End Source File
# End Group
# Begin Group "States"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\StateChange.cpp
# End Source File
# Begin Source File
SOURCE=.\StateChange.hpp
# End Source File
# End Group
# Begin Group "Missed Dependencies"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\stuff\AffineMatrix.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Angle.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\ArmorOn.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Auto_Container.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Auto_Ptr.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Average.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Chain.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Color.hpp
# End Source File
# Begin Source File
SOURCE=..\gosfx\Effect.hpp
# End Source File
# Begin Source File
SOURCE=..\gosfx\EffectLibrary.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\ExtentBox.hpp
# End Source File
# Begin Source File
SOURCE=..\gosfx\Fcurve.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\FileStream.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\FileStreamManager.hpp
# End Source File
# Begin Source File
SOURCE=..\Adept\GameOS.HPP
# End Source File
# Begin Source File
SOURCE=..\gosfx\gosFX.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSImage.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSImagePool.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSVertex.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSVertex2UV.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSVertexManipulation.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\GOSVertexPool.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Hash.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Initialized_Ptr.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Iterator.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Line.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\LinearMatrix.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Link.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\MArray.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Matrix.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\MatrixStack.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\MemoryBlock.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\MemoryStream.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLR.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLR_I_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLR_I_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRClipper.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRClippingState.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRCulturShape.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLREffect.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRFootstep.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRIndexedPrimitiveBase.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRInfiniteLightWithFallOff.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRLight.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRLineCloud.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRPointCloud.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRPrimitiveBase.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRShape.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRSortByOrder.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRSorter.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRState.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRTexture.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRTexturePool.hpp
# End Source File
# Begin Source File
SOURCE=..\mlr\MLRTriangleCloud.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Motion.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\MString.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Node.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Noncopyable.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Normal.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\NotationFile.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Note.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\OBB.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Origin.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Page.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Plane.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Plug.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Point3D.hpp
# End Source File
# Begin Source File
SOURCE=..\gosfx\PointLight.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Polar.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Random.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\RegisteredClass.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Rotation.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\SafeChain.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\SafeSocket.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Scalar.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Slot.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Socket.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\SortedChain.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\SortedSocket.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Sphere.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Stuff.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Style.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Table.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\CoreTech\Libraries\GameOS\ToolOS.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Tree.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\UnitVector.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Vector2D.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Vector3D.hpp
# End Source File
# Begin Source File
SOURCE=..\stuff\Vector4D.hpp
# End Source File
# End Group
# Begin Source File
SOURCE=.\ElementRenderer.cpp
# End Source File
# Begin Source File
SOURCE=.\ElementRenderer.hpp
# End Source File
# Begin Source File
SOURCE=.\ElementRendererHeaders.cpp
# ADD CPP /Yc"ElementRendererHeaders.hpp"
# End Source File
# Begin Source File
SOURCE=.\ElementRendererHeaders.hpp
# End Source File
# End Target
# End Project
@@ -0,0 +1,61 @@
#pragma once
#include <Stuff\Stuff.hpp>
//
//-------------------------
// Element Renderer classes
//-------------------------
//
namespace ElementRenderer {
enum
{
ElementClassID = Stuff::FirstElementRendererClassID,
GroupElementClassID,
CameraElementClassID,
ShapeElementClassID,
ListElementClassID,
SwitchElementClassID,
LODElementClassID,
PointCloudElementClassID,
TriangleCloudElementClassID,
ScalableShapeElementClassID,
ScreenQuadsElementClassID,
gosFXElementClassID,
GridElementClassID,
LineCloudElementClassID,
LightElementClassID,
MultiLODElementClassID,
ShapeLODElementClassID,
TreeElementClassID,
FirstFreeElementRendererClassID
};
enum {CurrentERFVersion = 14};
int
ReadERFVersion(Stuff::MemoryStream *erf_stream);
void
WriteERFVersion(Stuff::MemoryStream *erf_stream);
void InitializeClasses(Stuff::NotationFile *startup_ini=NULL);
void TerminateClasses(Stuff::NotationFile *startup_ini=NULL);
extern HGOSHEAP g_LibraryHeap;
extern HGOSHEAP g_Heap;
DECLARE_TIMER(extern, Total_Video);
DECLARE_TIMER(extern, Graph_Traversal);
DECLARE_TIMER(extern, Setup_Sky);
DECLARE_TIMER(extern, Draw_Shapes);
DECLARE_TIMER(extern, Draw_Scalable);
DECLARE_TIMER(extern, Draw_Effects);
DECLARE_TIMER(extern, Draw_Quads);
DECLARE_TIMER(extern, Render);
}
#include "Element.hpp"
@@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: ElementRenderer - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
ElementRenderer.lib - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
@@ -0,0 +1,3 @@
#include "ElementRendererHeaders.hpp"
// This file is here to make the .pch file
@@ -0,0 +1,35 @@
#pragma once
#include "ElementRenderer.hpp"
#if 1
#define ELEMENT_RENDER(string) RENDER("Element::" string)
#else
#define ELEMENT_RENDER(string)
#endif
#if 0
#define SYNC_LOGIC(string) LOGIC("Sync::" string)
#else
#define SYNC_LOGIC(string)
#endif
#include <MLR\MLRTexture.hpp>
#include <MLR\MLRClipper.hpp>
#include "CameraElement.hpp"
#include "ShapeElement.hpp"
#include "LODElement.hpp"
#include "GridElement.hpp"
#include "PointCloudElement.hpp"
#include "TriangleCloudElement.hpp"
#include "ScalableShapeElement.hpp"
#include "ScreenQuadsElement.hpp"
#include "gosFXElement.hpp"
#include "LineCloudElement.hpp"
#include "LightElement.hpp"
#include "MultiLODElement.hpp"
#include "ShapeLODElement.hpp"
#include "TreeElement.hpp"
#include "StateChange.hpp"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,196 @@
#pragma once
#include "ElementRenderer.hpp"
#include "ListElement.hpp"
//#########################################################################
//######################### GridElement ###############################
//#########################################################################
namespace ElementRenderer {
class GroupElement;
class GridElement:
public ListElement
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef ListElement BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
GridElement(
ClassData *class_data,
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
public:
GridElement(
BYTE row_size,
BYTE column_size,
Stuff::Scalar row_offset,
Stuff::Scalar column_offset,
Stuff::Scalar total_row_size,
Stuff::Scalar total_column_size,
ClassData *class_data=DefaultData
);
~GridElement();
static GridElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
void AttachIndexedChild(
BYTE row,
BYTE column,
Element *element
);
Element* GetIndexedElement(
BYTE row,
BYTE column
)
{Check_Object(this); return m_list[row*m_columnCellCount+column];}
Element* GetIndexedElement(WORD index)
{Check_Object(this); return m_list[index];}
WORD FindElementIndex(
Stuff::Scalar row,
Stuff::Scalar column
);
void FindRowAndColumn(
WORD index,
BYTE *row,
BYTE *column
)
{
Check_Object(this);
if (index != 0)
*row = static_cast<BYTE>(index/m_columnCellCount);
else
*row = 0;
*column = static_cast<BYTE>(index-(*row*m_columnCellCount));
}
void SetSize(WORD total_cells);
void SetSize(
BYTE row_size,
BYTE column_size
);
void GetSize(
BYTE* row_size,
BYTE* column_size
)
{
Check_Object(this); Check_Pointer(row_size); Check_Pointer(column_size);
*row_size = m_rowCellCount; *column_size = m_columnCellCount;
}
void GetDimensions(
Stuff::Scalar *row_offset,
Stuff::Scalar *column_offset,
Stuff::Scalar *row_cell_size,
Stuff::Scalar *column_cell_size
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sync support
//
protected:
void SetSyncState();
static SyncMethod SyncMethods[4];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Culling
//
protected:
virtual void SetCullState();
static CullMethod CullMethods;
int GridCullMethod(CameraElement *camera);
bool GridRayCullMethod(CollisionQuery *query);
int GridSphereTestMethod(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
public:
typedef void* (*CellTest)(
GridElement *grid,
WORD cell,
CollisionQuery *query,
Stuff::Scalar enter,
Stuff::Scalar leave
);
void* IterateLine(
CollisionQuery *query,
CellTest test_function
);
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
static void* TestCell(
GridElement *grid,
WORD cell,
CollisionQuery *query,
Stuff::Scalar enter,
Stuff::Scalar leave
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
BYTE m_rowCellCount, m_columnCellCount;
Stuff::Scalar m_rowCellSize, m_columnCellSize;
Stuff::Scalar m_rowOffset, m_columnOffset;
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
#pragma once
#include "ElementRenderer.hpp"
#include "Element.hpp"
namespace ElementProxies {
class ElementGroupProxy;
class ElementSceneProxy;
}
namespace ElementRenderer {
//#########################################################################
//######################### GroupElement ################################
//#########################################################################
class GroupElement:
public Element
{
friend class ElementProxies::ElementGroupProxy;
friend class ElementProxies::ElementSceneProxy;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef Element BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
GroupElement(
ClassData *class_data,
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
public:
GroupElement(ClassData *class_data=DefaultData);
~GroupElement();
static GroupElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
void AttachChild(Element *child);
void DetachChild(Element *child);
void DetachChildren();
Stuff::ChainIteratorOf<Element*>* MakeIterator()
{
Check_Object(this);
return new Stuff::ChainIteratorOf<Element*>(&m_group);
}
protected:
Stuff::ChainOf<Element*> m_group;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sync support
//
protected:
void SetSyncState();
static SyncMethod SyncMethods[SyncStateCount];
void CleanRootSyncMethod();
void DirtyRootSyncMethod();
void CleanSyncMethod();
void DirtySyncMethod();
void CleanSphereSyncMethod();
void MatrixDirtySphereSyncMethod();
void BoundsWrongSphereSyncMethod();
void FullSphereSyncMethod();
void CleanOBBSyncMethod();
void MatrixDirtyOBBSyncMethod();
void BoundsWrongOBBSyncMethod();
void FullOBBSyncMethod();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
public:
void CleanDamage();
void ApplyDamage(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius
);
void ApplyDamageDecal(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *texture
);
void CastShadow(
const Stuff::LinearMatrix4D &shadow_to_world,
const Stuff::UnitVector3D &sun_in_world,
Stuff::Scalar radius
);
void MakeFootStep(
MidLevelRenderer::MLRShape *shape,
const Stuff::LinearMatrix4D &foot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *tex
);
public:
int CountTriangles();
void GetCoordData(Stuff::DynamicArrayOf<Stuff::Point3D> *array);
};
}
@@ -0,0 +1,506 @@
#include "ElementRendererHeaders.hpp"
//############################################################################
//############################ LODElement ################################
//############################################################################
HGOSHEAP
ElementRenderer::LODElement::s_Heap = NULL;
ElementRenderer::LODElement::ClassData*
ElementRenderer::LODElement::DefaultData = NULL;
ElementRenderer::Element::DrawMethod
ElementRenderer::LODElement::DrawMethods[DrawStateCount]=
{
DRAW_METHOD(LODElement, Inherit),
DRAW_METHOD(LODElement, Override)
};
Stuff::Scalar ElementRenderer::LODElement::s_Offset = 0.0f;
bool ElementRenderer::LODElement::s_ShadeLODs = false;
Stuff::RGBAColor ElementRenderer::LODElement::s_Shades[6]={
Stuff::RGBAColor(1.0f, 1.0f, 1.0f, 1.0),
Stuff::RGBAColor(1.0f, 0.0f, 0.0f, 1.0),
Stuff::RGBAColor(0.0f, 1.0f, 0.0f, 1.0),
Stuff::RGBAColor(0.0f, 0.0f, 1.0f, 1.0),
Stuff::RGBAColor(1.0f, 1.0f, 0.0f, 1.0),
Stuff::RGBAColor(1.0f, 0.0f, 1.0f, 1.0)
};
static bool
__stdcall Check100m()
{
return ElementRenderer::LODElement::s_Offset == 625.0f;
}
static bool
__stdcall Check250m()
{
return ElementRenderer::LODElement::s_Offset == 2500.0f;
}
static bool
__stdcall Check500m()
{
return ElementRenderer::LODElement::s_Offset == 10000.0f;
}
static void
__stdcall Enable100m()
{
ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 625.0f) ? 0.0f : 625.0f;
}
static void
__stdcall Enable250m()
{
ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 2500.0f) ? 0.0f : 2500.0f;
}
static void
__stdcall Enable500m()
{
ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 10000.0f) ? 0.0f : 10000.0f;
}
extern DWORD Disable_Lights;
static bool __stdcall CheckShadeLODs() {return ElementRenderer::LODElement::s_ShadeLODs;}
static void __stdcall EnableShadeLODs()
{
ElementRenderer::LODElement::s_ShadeLODs = !ElementRenderer::LODElement::s_ShadeLODs;
if (ElementRenderer::LODElement::s_ShadeLODs)
Disable_Lights = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::InitializeClass(Stuff::NotationFile *startup_ini)
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("LOD", 0, g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
LODElementClassID,
"ElementRenderer::LODElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Register_Object(DefaultData);
AddDebuggerMenuItem("Libraries\\ElementRenderer\\Shade LODs", CheckShadeLODs, EnableShadeLODs, 0 );
AddDebuggerMenuItem("Libraries\\Graphics Options\\+25m Shape LODs", Check100m, Enable100m, 0 );
AddDebuggerMenuItem("Libraries\\Graphics Options\\+50m Shape LODs", Check250m, Enable250m, 0 );
AddDebuggerMenuItem("Libraries\\Graphics Options\\+100m Shape LODs", Check500m, Enable500m, 0 );
if (startup_ini)
{
Check_Object(startup_ini);
Stuff::Page *page = startup_ini->FindPage("Graphics Options");
if (page)
{
Check_Object(page);
page->GetEntry("LOD", &s_Offset);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::TerminateClass(Stuff::NotationFile *startup_ini)
{
if (startup_ini)
{
Check_Object(startup_ini);
Stuff::Page *page = startup_ini->SetPage("Graphics Options");
Check_Object(page);
page->SetEntry("LOD", s_Offset);
}
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LODElement::LODElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
):
SwitchElement(DefaultData, stream, version, shapes)
{
Check_Pointer(this);
Check_Object(stream);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
//
//---------------------------------
// Create the shape from the stream
//---------------------------------
//
Verify(m_list.GetLength() < 65536);
WORD lod_count = static_cast<WORD>(m_list.GetLength());
m_LODs.SetLength(lod_count);
for (WORD lod=0; lod<lod_count; ++lod)
*stream >> m_LODs[lod].m_nearSquared >> m_LODs[lod].m_farSquared;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LODElement::LODElement():
SwitchElement(DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LODElement::~LODElement()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LODElement*
ElementRenderer::LODElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(s_Heap);
LODElement *element = new LODElement(stream, version, shapes);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//--------------------
// Save each LOD entry
//--------------------
//
Verify(m_list.GetLength() < 65536);
WORD lod_count = static_cast<WORD>(m_LODs.GetLength());
for (WORD lod=0; lod<lod_count; ++lod)
*stream << m_LODs[lod].m_nearSquared << m_LODs[lod].m_farSquared;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::AttachLOD(
WORD index,
Element *element,
const Entry &entry
)
{
Check_Object(this);
Verify(index < m_LODs.GetLength());
m_LODs[index] = entry;
AttachIndexedChild(index, element);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::SetSize(WORD max_size)
{
Check_Object(this);
m_LODs.SetLength(max_size);
for (WORD i=0; i<max_size; ++i)
{
m_LODs[i].m_nearSquared = 0.0f;
m_LODs[i].m_farSquared = 0.0f;
}
BaseClass::SetSize(max_size);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::DetachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
//
//-------------------------------
// Find the element and unhook it
//-------------------------------
//
Verify(m_list.GetLength() < 65536);
WORD lod_count = static_cast<WORD>(m_LODs.GetLength());
for (WORD i=0; i<lod_count; ++i)
{
Entry *entry = &m_LODs[i];
if (m_list[i] == child)
{
entry->m_nearSquared = 0.0f;
entry->m_farSquared = 0.0f;
break;
}
}
BaseClass::DetachChild(child);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::SetDrawState()
{
Check_Object(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------------------------------------------------
// We need to find out which lod the camera should traverse into, so
// transform the camera into LOD space and get the distance from the LOD
//----------------------------------------------------------------------
//
Stuff::Point3D camera_origin(camera->GetLocalToWorld());
Stuff::Point3D lod_origin(GetLocalToWorld());
camera_origin -= lod_origin;
Stuff::Scalar distance = camera_origin.GetLengthSquared() + s_Offset;
Min_Clamp(distance, 0.0f);
//
//---------------------------------------------------
// Search the lod entries looking for the first match
//---------------------------------------------------
//
for (WORD i=0; i<m_LODs.GetLength(); ++i)
{
Entry *entry = &m_LODs[i];
if (entry->m_nearSquared <= distance && entry->m_farSquared >= distance)
{
#if defined(LAB_ONLY)
Stuff::RGBAColor old_fade;
if (s_ShadeLODs && i<ELEMENTS(s_Shades))
{
old_fade = FadeColor;
FadeColor = s_Shades[i];
}
#endif
Element *element = m_list[i];
Check_Object(element);
SetSwitch(i);
camera->DrawElement(element, inherited_state);
#if defined(LAB_ONLY)
if (s_ShadeLODs && i<ELEMENTS(s_Shades))
FadeColor = old_fade;
#endif
break;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//-------------------
// Mix the properties
//-------------------
//
Check_Object(m_stateChange);
StateChange mixed;
mixed.Mix(*inherited_state, *m_stateChange);
MixLights(
mixed.m_lights,
inherited_state->m_lights,
m_stateChange->m_lights
);
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------------------------------------------------
// We need to find out which lod the camera should traverse into, so
// transform the camera into LOD space and get the distance from the LOD
//----------------------------------------------------------------------
//
Stuff::Point3D camera_origin(camera->GetLocalToWorld());
Stuff::Point3D lod_origin(GetLocalToWorld());
camera_origin -= lod_origin;
Stuff::Scalar distance = camera_origin.GetLengthSquared() + s_Offset;
Min_Clamp(distance, 0.0f);
//
//---------------------------------------------------
// Search the lod entries looking for the first match
//---------------------------------------------------
//
for (WORD i=0; i<m_LODs.GetLength(); ++i)
{
Entry *entry = &m_LODs[m_switch];
if (entry->m_nearSquared <= distance && entry->m_farSquared >= distance)
{
#if defined(LAB_ONLY)
Stuff::RGBAColor old_fade;
if (s_ShadeLODs && i<ELEMENTS(s_Shades))
{
old_fade = FadeColor;
FadeColor = s_Shades[i];
}
#endif
Element *element = m_list[m_switch];
Check_Object(element);
SetSwitch(i);
camera->DrawElement(element, &mixed);
#if defined(LAB_ONLY)
if (s_ShadeLODs && i<ELEMENTS(s_Shades))
FadeColor = old_fade;
#endif
break;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::CleanDamage()
{
Check_Object(this);
for(WORD i=0;i<GetActiveCount();i++)
{
Element *child = GetIndexedElement(i);
Check_Object(child);
child->CleanDamage();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::ApplyDamage(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius
)
{
Check_Object(this);
for(WORD i=0;i<GetActiveCount();i++)
{
Element *child = GetIndexedElement(i);
Check_Object(child);
child->ApplyDamage(damage_spot, radius);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LODElement::ApplyDamageDecal(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *texture
)
{
Check_Object(this);
Check_Object(texture);
for(WORD i=0;i<GetActiveCount();i++)
{
Element *child = GetIndexedElement(i);
Check_Object(child);
child->ApplyDamageDecal(damage_spot, radius, texture);
}
}
@@ -0,0 +1,117 @@
#pragma once
#include "ElementRenderer.hpp"
#include "SwitchElement.hpp"
namespace ElementRenderer {
//#########################################################################
//######################### LODElement ################################
//#########################################################################
class LODElement:
public SwitchElement
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass(Stuff::NotationFile *startup_ini);
static void TerminateClass(Stuff::NotationFile *startup_ini);
static ClassData *DefaultData;
typedef SwitchElement BaseClass;
static Stuff::Scalar s_Offset;
static bool s_ShadeLODs;
static Stuff::RGBAColor s_Shades[6];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
LODElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
public:
LODElement();
~LODElement();
static LODElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
struct Entry
{
Stuff::Scalar
m_nearSquared,
m_farSquared;
};
void AttachLOD(
WORD index,
Element *element,
const Entry &entry
);
void SetSize(WORD max_size);
protected:
void DetachChild(Element *child);
Stuff::DynamicArrayOf<Entry> m_LODs;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
public:
void CleanDamage();
void ApplyDamage(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius
);
void ApplyDamageDecal(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *texture
);
};
}
@@ -0,0 +1,382 @@
#include "ElementRendererHeaders.hpp"
#include <gosFX\PointLight.hpp>
#include <MLR\MLRInfiniteLightWithFalloff.hpp>
//###########################################################################
//############################# gosFX::Light ##############################
//###########################################################################
DWORD Disable_Lights=0;
static bool
__stdcall Check_DisableLights()
{
return Disable_Lights!=0;
}
static void
__stdcall Activate_DisableLights()
{
Disable_Lights = !Disable_Lights;
}
//------------------------------------------------------------------------------
//
gosFX::Light::Light(MidLevelRenderer::MLRLight *light):
Plug(DefaultData),
m_light(light)
{
Check_Pointer(this);
Check_Object(light);
}
//------------------------------------------------------------------------------
//
gosFX::Light::~Light()
{
Check_Object(this);
Check_Object(m_light);
delete m_light;
}
//------------------------------------------------------------------------------
//
void
gosFX::Light::ChangeLight(gosFX::LightManager::Info *info)
{
Check_Object(this);
Check_Pointer(info);
m_light->SetIntensity(info->m_intensity);
m_light->SetColor(info->m_color);
m_light->SetLightToWorldMatrix(info->m_origin);
}
//------------------------------------------------------------------------------
//
void
gosFX::Light::GetInfo(gosFX::LightManager::Info *info)
{
Check_Object(this);
Check_Pointer(info);
Check_Object(m_light);
m_light->GetColor(info->m_color);
info->m_origin = m_light->GetLightToWorldMatrix();
info->m_intensity = m_light->GetIntensity();
}
//############################################################################
//######################## LightElementManager #############################
//############################################################################
ElementRenderer::LightElementManager*
&ElementRenderer::LightElementManager::Instance=
*Cast_Pointer(
ElementRenderer::LightElementManager**,
&gosFX::LightManager::Instance
);
//------------------------------------------------------------------------------
//
ElementRenderer::LightElementManager::LightElementManager()
{
}
//------------------------------------------------------------------------------
//
ElementRenderer::LightElementManager::~LightElementManager()
{
}
//------------------------------------------------------------------------------
//
void
ElementRenderer::LightElementManager::ChangeLight(
gosFX::Light* light,
Info *info
)
{
Check_Object(this);
Check_Object(light);
light->ChangeLight(info);
}
//------------------------------------------------------------------------------
//
void
ElementRenderer::LightElementManager::DeleteLight(gosFX::Light *light)
{
Check_Object(this);
Check_Object(light);
delete light;
}
//############################################################################
//############################ LightElement ################################
//############################################################################
HGOSHEAP
ElementRenderer::LightElement::s_Heap = NULL;
ElementRenderer::LightElement::ClassData*
ElementRenderer::LightElement::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::InitializeClass()
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("Light", 0, g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
LightElementClassID,
"ElementRenderer::LightElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Check_Object(DefaultData);
AddDebuggerMenuItem("Libraries\\ElementRenderer\\Disable Lighting", Check_DisableLights, Activate_DisableLights, 0 );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LightElement::LightElement(
Stuff::MemoryStream *stream,
int version
):
Element(DefaultData, stream, version)
{
Check_Pointer(this);
Check_Object(stream);
m_draw = static_cast<DrawMethod>(&ElementRenderer::LightElement::Draw);
//
//---------------------------------
// Create the shape from the stream
//---------------------------------
//
gos_PushCurrentHeap(MidLevelRenderer::LightsHeap);
MidLevelRenderer::MLRLight *light =
MidLevelRenderer::MLRLight::Make(
stream,
MidLevelRenderer::ReadMLRVersion(stream)
);
gos_PopCurrentHeap();
Check_Object(light);
m_light = ElementRenderer::LightElementManager::Instance->MakeLight(light);
Check_Object(m_light);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LightElement::LightElement():
Element(DefaultData)
{
Check_Pointer(this);
m_draw = static_cast<DrawMethod>(&ElementRenderer::LightElement::Draw);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LightElement::~LightElement()
{
Check_Object(this);
Check_Object(m_light);
delete m_light;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LightElement*
ElementRenderer::LightElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(s_Heap);
LightElement *element = new LightElement(stream, version);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//-----------------------------
// Save the shape to the stream
//-----------------------------
//
MidLevelRenderer::WriteMLRVersion(stream);
Check_Object(m_light);
MidLevelRenderer::MLRLight *light = m_light->m_light;
Check_Object(light);
light->Save(stream);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::AttachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("Light elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::DetachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("Light elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::SetSyncState()
{
Check_Object(this);
m_sync = static_cast<SyncMethod>(&ElementRenderer::LightElement::LightSync);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::LightSync()
{
Check_Object(this);
//
//--------------------
// Update our matrices
//--------------------
//
m_localToParent = m_newLocalToParent;
Check_Object(m_parent);
if (!IsLocalToParentIdentity())
m_localToWorld.Multiply(m_localToParent, m_parent->GetLocalToWorld());
else
m_localToWorld = m_parent->GetLocalToWorld();
MatrixIsClean();
//
//-----------------
// Update the light
//-----------------
//
m_lightInfo.m_origin = m_localToWorld;
Check_Object(m_light);
m_light->ChangeLight(&m_lightInfo);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementRenderer::LightElement::CastCulledRay(CollisionQuery *query)
{
Check_Object(this);
Check_Object(query);
STOP(("Light is not collidable!"));
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::Element*
ElementRenderer::LightElement::FindSmallestElementContainingCulled(SphereTest *test)
{
Check_Object(this);
Check_Object(test);
STOP(("Light is not collidable!"));
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::SetDrawState()
{
Check_Object(this);
m_draw = static_cast<DrawMethod>(&ElementRenderer::LightElement::Draw);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::Draw(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ElementRenderer::LightElement::CountTriangles()
{
Check_Object(this);
return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LightElement::AdoptLight(gosFX::Light* light)
{
Check_Object(this);
Check_Object(light);
m_light = light;
light->GetInfo(&m_lightInfo);
}
@@ -0,0 +1,146 @@
#pragma once
#include "ElementRenderer.hpp"
#include <gosFX\PointLight.hpp>
namespace gosFX
{
//########################################################################
//############################# Light ##################################
//########################################################################
class __declspec(novtable) Light:
public Stuff::Plug
{
protected:
Light(MidLevelRenderer::MLRLight* light);
public:
virtual ~Light();
virtual void ChangeLight(gosFX::LightManager::Info *info);
virtual void GetInfo(gosFX::LightManager::Info *info);
MidLevelRenderer::MLRLight *m_light;
};
}
namespace ElementRenderer {
//############################################################################
//######################## LightElementManager #############################
//############################################################################
class LightElementManager:
public gosFX::LightManager
{
public:
static LightElementManager* &Instance;
LightElementManager();
~LightElementManager();
virtual gosFX::Light* MakeLight(MidLevelRenderer::MLRLight *light)=0;
void ChangeLight(
gosFX::Light* light,
Info *info
);
void DeleteLight(gosFX::Light *light);
};
//#########################################################################
//######################### LightElement ################################
//#########################################################################
class LightElement:
public Element
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef Element BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
LightElement(
Stuff::MemoryStream *stream,
int version
);
public:
LightElement();
~LightElement();
static LightElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
protected:
void AttachChild(Element *child);
void DetachChild(Element *child);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sync support
//
protected:
void SetSyncState();
void LightSync();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
void Draw(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
int CountTriangles();
public:
gosFX::Light* GetLight()
{Check_Object(this); return m_light;}
void AdoptLight(gosFX::Light* light);
LightElementManager::Info m_lightInfo;
protected:
gosFX::Light *m_light;
};
}
@@ -0,0 +1,405 @@
#include "ElementRendererHeaders.hpp"
#include "LineCloudElement.hpp"
#include <MLR\MLRLineCloud.hpp>
//############################################################################
//########################## LineCloudElement ##############################
//############################################################################
//#define BOUNDS_BUG
ElementRenderer::LineCloudElement::ClassData*
ElementRenderer::LineCloudElement::DefaultData = NULL;
ElementRenderer::Element::DrawMethod
ElementRenderer::LineCloudElement::DrawMethods[DrawStateCount]=
{
//
// No billboarding
//
DRAW_METHOD(LineCloudElement, Inherit),
DRAW_METHOD(LineCloudElement, Override)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
LineCloudElementClassID,
"ElementRenderer::LineCloudElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LineCloudElement::LineCloudElement(
Stuff::MemoryStream *stream,
int version
):
Element(DefaultData, stream, version)
{
Check_Pointer(this);
Check_Object(stream);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
//
//---------------------------------
// Create the shape from the stream
//---------------------------------
//
#if 0
m_MLRLineCloud = MidLevelRenderer::MLRLineCloud::Make(stream);
Register_Object(m_MLRLineCloud);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LineCloudElement::LineCloudElement(unsigned max_points):
Element(DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
gos_PushCurrentHeap(MidLevelRenderer::EffectHeap);
m_MLRLineCloud = new MidLevelRenderer::MLRLineCloud(max_points);
Register_Object(m_MLRLineCloud);
gos_PopCurrentHeap();
m_MLRLineCloud->TurnAllOn();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LineCloudElement::~LineCloudElement()
{
Check_Object(this);
Unregister_Object(m_MLRLineCloud);
delete m_MLRLineCloud;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::LineCloudElement*
ElementRenderer::LineCloudElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(g_Heap);
LineCloudElement *element = new LineCloudElement(stream, version);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//-----------------------------
// Save the shape to the stream
//-----------------------------
//
#if 0
Check_Object(m_MLRLineCloud);
m_MLRLineCloud->Save(stream);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::AttachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("LineCloud elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::DetachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("LineCloud elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementRenderer::LineCloudElement::CastCulledRay(CollisionQuery *query)
{
Check_Object(this);
Check_Object(query);
STOP(("LineCloud is not collidable!"));
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::Element*
ElementRenderer::LineCloudElement::FindSmallestElementContainingCulled(SphereTest *test)
{
Check_Object(this);
Check_Object(test);
STOP(("LineCloud is not collidable!"));
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::SetDrawState()
{
Check_Object(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//----------------------------------------------------------------------
// If we are running slow enough, go ahead and check our vertices to see
// that they are in the bounds
//----------------------------------------------------------------------
//
#if defined(_ARMOR) && defined(BOUNDS_BUG)
if (!culling_state && ArmorLevel > 3)
{
Point3D center(m_localOBB.localToParent);
Scalar radius_squared = m_localOBB.sphereRadius*m_localOBB.sphereRadius;
const Point3D *verts;
int count;
m_MLRLineCloud->GetCoordData(&verts, &count);
for (int v=0; v<count; ++v)
{
Vector3D diff;
diff.Subtract(verts[v], center);
Verify(diff.GetLengthSquared() <= radius_squared);
}
}
#endif
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawEffectInformation info;
Check_Object(m_MLRLineCloud);
info.effect = m_MLRLineCloud;
info.clippingFlags.SetClippingState(0x2f);
Check_Object(&m_localToWorld);
info.effectToWorld = &m_localToWorld;
info.state = inherited_state->GetMLRState();
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::LineCloud::Inherited");
Start_Timer(Draw_Effects);
clipper->DrawEffect(&info);
Stop_Timer(Draw_Effects);
Start_Timer(Graph_Traversal);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//-------------------
// Mix the properties
//-------------------
//
Check_Object(m_stateChange);
StateChange mixed;
mixed.Mix(*inherited_state, *m_stateChange);
//
//----------------------------------------------------------------------
// If we are running slow enough, go ahead and check our vertices to see
// that they are in the bounds
//----------------------------------------------------------------------
//
#if defined(_ARMOR) && defined(BOUNDS_BUG)
if (!culling_state && ArmorLevel > 3)
{
Point3D center(m_localOBB.localToParent);
Scalar radius_squared = m_localOBB.sphereRadius*m_localOBB.sphereRadius;
const Point3D *verts;
int count;
m_MLRLineCloud->GetCoordData(&verts, &count);
for (int v=0; v<count; ++v)
{
Vector3D diff;
diff.Subtract(verts[v], center);
Verify(diff.GetLengthSquared() <= radius_squared);
}
}
#endif
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawEffectInformation info;
Check_Object(m_MLRLineCloud);
info.effect = m_MLRLineCloud;
info.clippingFlags.SetClippingState(0x2f);
Check_Object(&m_localToWorld);
info.effectToWorld = &m_localToWorld;
info.state = mixed.GetMLRState();
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::LineCloud::Overridden");
Start_Timer(Draw_Effects);
clipper->DrawEffect(&info);
Stop_Timer(Draw_Effects);
Start_Timer(Graph_Traversal);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ElementRenderer::LineCloudElement::CountTriangles()
{
Check_Object(this);
STOP(("Not implemented"));
return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::LineCloudElement::SetDataPointers(
const unsigned *used_points,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
)
{
Check_Pointer(this);
Check_Pointer(used_points);
Check_Pointer(point_data);
Check_Pointer(color_data);
Check_Object(m_MLRLineCloud);
m_MLRLineCloud->SetData(
reinterpret_cast<const int*>(used_points),
point_data,
color_data
);
}
@@ -0,0 +1,103 @@
#pragma once
#include "ElementRenderer.hpp"
namespace MidLevelRenderer {
class MLRLineCloud;
}
namespace ElementRenderer {
//#########################################################################
//####################### LineCloudElement ##############################
//#########################################################################
class LineCloudElement:
public Element
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef Element BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
LineCloudElement(
Stuff::MemoryStream *stream,
int version
);
public:
LineCloudElement(unsigned max_points);
~LineCloudElement();
static LineCloudElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
void Save(Stuff::MemoryStream *stream);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
protected:
void AttachChild(Element *child);
void DetachChild(Element *child);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
int CountTriangles();
public:
MidLevelRenderer::MLRLineCloud* GetLineCloud()
{Check_Object(this); return m_MLRLineCloud;}
void SetDataPointers(
const unsigned *used_points,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
);
protected:
MidLevelRenderer::MLRLineCloud *m_MLRLineCloud;
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,173 @@
#pragma once
#include "ElementRenderer.hpp"
//#########################################################################
//######################### ListElement ###############################
//#########################################################################
namespace ElementRenderer {
class GroupElement;
class ListElement:
public Element
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef Element BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
ListElement(
ClassData *class_data,
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes,
bool load_children=true
);
public:
ListElement(ClassData *class_data=DefaultData);
explicit ListElement(
GroupElement *group,
ClassData *class_data = DefaultData
);
~ListElement();
static ListElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
void AttachIndexedChild(
WORD index,
Element *element
);
Element* GetIndexedElement(WORD index)
{Check_Object(this); return m_list[index];}
virtual void SetSize(WORD max_size);
virtual size_t GetLength()
{Check_Object(this); return m_list.GetLength();};
virtual void ReSize(WORD max_size);
void SetActiveCount(WORD active)
{
Check_Object(this);
Verify(m_activeChildren<=m_list.GetLength());
m_activeChildren = active;
}
WORD GetActiveCount()
{Check_Object(this); return m_activeChildren;}
protected:
void AttachChild(Element *child);
void DetachChild(Element *child);
Stuff::DynamicArrayOf<Element*> m_list;
WORD m_activeChildren;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Sync support
//
protected:
void SetSyncState();
static SyncMethod SyncMethods[SyncStateCount];
void CleanRootSyncMethod();
void DirtyRootSyncMethod();
void CleanSyncMethod();
void DirtySyncMethod();
void CleanSphereSyncMethod();
void MatrixDirtySphereSyncMethod();
void BoundsWrongSphereSyncMethod();
void FullSphereSyncMethod();
void CleanOBBSyncMethod();
void MatrixDirtyOBBSyncMethod();
void BoundsWrongOBBSyncMethod();
void FullOBBSyncMethod();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
public:
void CleanDamage();
void ApplyDamage(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius
);
void ApplyDamageDecal(
const Stuff::LinearMatrix4D &damage_spot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *texture
);
void CastShadow(
const Stuff::LinearMatrix4D &shadow_to_world,
const Stuff::UnitVector3D &sun_in_world,
Stuff::Scalar radius
);
void MakeFootStep(
MidLevelRenderer::MLRShape *shape,
const Stuff::LinearMatrix4D &foot,
Stuff::Scalar radius,
MidLevelRenderer::MLRTexture *tex
);
int CountTriangles();
void GetCoordData(Stuff::DynamicArrayOf<Stuff::Point3D> *array);
};
}
@@ -0,0 +1,576 @@
#include "ElementRendererHeaders.hpp"
#include "MultiLODElement.hpp"
//#define SPEW_CULL_INFO "your_name_here"
//############################################################################
//############################ MultiLODElement ################################
//############################################################################
HGOSHEAP
ElementRenderer::MultiLODElement::s_Heap = NULL;
ElementRenderer::MultiLODElement::ClassData*
ElementRenderer::MultiLODElement::DefaultData = NULL;
ElementRenderer::Element::DrawMethod
ElementRenderer::MultiLODElement::DrawMethods[DrawStateCount]=
{
DRAW_METHOD(MultiLODElement, Inherit),
DRAW_METHOD(MultiLODElement, Override)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::InitializeClass()
{
Verify(!DefaultData);
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("MultiLOD", 0, g_LibraryHeap);
Check_Pointer(s_Heap);
DefaultData =
new ClassData(
MultiLODElementClassID,
"ElementRenderer::MultiLODElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::MultiLODElement::MultiLODElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
):
ListElement(DefaultData, stream, version, shapes, false)
{
Check_Pointer(this);
Check_Object(stream);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
//
//------------------------------------------------------
// Older Multi-LOD versions just read in the whole thing
//------------------------------------------------------
//
if (version < 13)
{
if (version >= 11)
*stream >> m_activeChildren;
else
{
int count;
*stream >> count;
Verify(static_cast<unsigned>(count) < 65536);
m_activeChildren = static_cast<WORD>(count);
}
m_list.SetLength(m_activeChildren);
for (WORD s=0; s<m_activeChildren; ++s)
{
m_list[s] = Create(stream, version);
Element *child = m_list[s];
SetParentElement(child, this);
if (child->GetCullMode() != AlwaysCullMode)
{
if (child->m_localOBB.sphereRadius > 0.0f || child->AreBoundsWrong())
child->SetVolumeCullMode();
else
child->SetNeverCullMode();
}
}
//
//-------------------------
// Load in the LOD settings
//-------------------------
//
Verify(m_list.GetLength() < 65536);
WORD lod_count = static_cast<WORD>(m_list.GetLength());
m_LODs.SetLength(lod_count);
for (WORD lod=0; lod<lod_count; ++lod)
{
*stream >> m_LODs[lod].m_nearSquared >> m_LODs[lod].m_fadeInSquared;
*stream >> m_LODs[lod].m_fadeOutSquared >> m_LODs[lod].m_farSquared;
}
}
//
//------------------------------------------------------------------------
// Newer versions only load in the parts of the Multi-LOD that are visible
//------------------------------------------------------------------------
//
else
{
*stream >> m_activeChildren;
m_list.SetLength(m_activeChildren);
m_LODs.SetLength(m_activeChildren);
WORD used=0;
for (WORD i=0; i<m_activeChildren; ++i)
{
*stream >> m_LODs[used].m_nearSquared >> m_LODs[used].m_fadeInSquared;
*stream >> m_LODs[used].m_fadeOutSquared >> m_LODs[used].m_farSquared;
//
//-----------------------------------------------------
// If this can't be seen because of the offset, dump it
//-----------------------------------------------------
//
int length;
*stream >> length;
if (i<m_activeChildren-1 && LODElement::s_Offset > m_LODs[used].m_farSquared)
{
stream->AdvancePointer(length);
continue;
}
//
//------------------------------------------------------------------------------------
// If this is the first visible LOD after we have dropped one, reset the near clipping
// plane to zero
//------------------------------------------------------------------------------------
//
else if (!used && i>0)
{
m_LODs[used].m_nearSquared = 0.0f;
m_LODs[used].m_fadeInSquared = 0.0f;
}
//
//-----------------------------------
// Now go ahead and read in the child
//-----------------------------------
//
m_list[used] = Create(stream, version);
Element *child = m_list[used];
SetParentElement(child, this);
if (child->GetCullMode() != AlwaysCullMode)
{
if (child->m_localOBB.sphereRadius > 0.0f || child->AreBoundsWrong())
child->SetVolumeCullMode();
else
child->SetNeverCullMode();
}
++used;
}
Verify(used>0);
if (used < m_activeChildren)
{
m_list.SetLength(used);
m_LODs.SetLength(used);
m_activeChildren = used;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::MultiLODElement::MultiLODElement():
ListElement(DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::MultiLODElement::~MultiLODElement()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::MultiLODElement*
ElementRenderer::MultiLODElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(s_Heap);
MultiLODElement *element = new MultiLODElement(stream, version, shapes);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
//
//-----------------------------------------
// We don't want ListElement doing anything
//-----------------------------------------
//
BaseClass::BaseClass::Save(stream);
//
//--------------------
// Save each LOD entry
//--------------------
//
WORD child_count = (WORD)m_list.GetLength();
Verify((unsigned)m_list.GetLength() < 65536);
Verify(m_list.GetLength() == child_count);
*stream << child_count;
for (WORD i=0; i<child_count; ++i)
{
Check_Object(m_list[i]);
*stream << m_LODs[i].m_nearSquared << m_LODs[i].m_fadeInSquared;
*stream << m_LODs[i].m_fadeOutSquared << m_LODs[i].m_farSquared;
//
//------------------------------------------------------------
// Make sure to include the length of the child substream here
//------------------------------------------------------------
//
*stream << (int)0;
unsigned index = stream->GetIndex();
m_list[i]->Save(stream);
unsigned length = stream->GetIndex() - index;
stream->RewindPointer(length + sizeof(int));
*stream << length;
stream->AdvancePointer(length);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::AttachLOD(
WORD index,
Element *element,
const Entry &entry
)
{
Check_Object(this);
Verify(index < m_LODs.GetLength());
m_LODs[index] = entry;
AttachIndexedChild(index, element);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This is necessary for attaching LOD's into the list that might miss certain
// meshes in the middle ie.. 4/5 of the LOD's have a toe, but lod 2 doesn't
// Needed for the exporter. The grouping there doesn't allow counters.
int
ElementRenderer::MultiLODElement::AttachLODFirstAvailableSlot(
Element *element,
const Entry &entry
)
{
Check_Object(this);
for (unsigned short index = 0; index < m_LODs.GetLength(); index ++)
{
//
// When initialized these distances are set to 0 (in SetSize)
//
if (Stuff::Small_Enough(m_LODs[index].m_nearSquared) && Stuff::Small_Enough( m_LODs[index].m_farSquared))
{
m_LODs[index] = entry;
AttachIndexedChild(index, element);
return index;
}
}
STOP(("MultiLODElement: Can't attach another LOD, already full!"));
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::SetSize(WORD max_size)
{
Check_Object(this);/*
gos_PushCurrentHeap(s_Heap);
for (WORD i=0; i<max_size; ++i)
{
m_LODs[i].m_nearSquared = 0.0f;
m_LODs[i].m_fadeInSquared = 0.0f;
m_LODs[i].m_fadeOutSquared = 0.0f;
m_LODs[i].m_farSquared = 0.0f;
}
*/
DWORD i = m_LODs.GetLength();
m_LODs.SetLength(max_size);
for (;i<max_size; ++i)
{
m_LODs[i].m_nearSquared = 0.0f;
m_LODs[i].m_fadeInSquared = 0.0f;
m_LODs[i].m_fadeOutSquared = 0.0f;
m_LODs[i].m_farSquared = 0.0f;
}
BaseClass::SetSize(max_size);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::DetachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
//
//-------------------------------
// Find the element and unhook it
//-------------------------------
//
Verify(m_LODs.GetLength() < 65536);
WORD lod_count = static_cast<WORD>(m_LODs.GetLength());
for (WORD i=0; i<lod_count; ++i)
{
Entry *entry = &m_LODs[i];
if (m_list[i] == child)
{
entry->m_nearSquared = 0.0f;
entry->m_fadeInSquared = 0.0f;
entry->m_fadeOutSquared = 0.0f;
entry->m_farSquared = 0.0f;
break;
}
}
BaseClass::DetachChild(child);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::SetDrawState()
{
Check_Object(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------------------------------------------------
// We need to find out which lod the camera should traverse into, so
// transform the camera into LOD space and get the distance from the LOD
//----------------------------------------------------------------------
//
Stuff::Point3D camera_origin(camera->GetLocalToWorld());
Stuff::Point3D lod_origin(GetLocalToWorld());
camera_origin -= lod_origin;
Stuff::Scalar distance = camera_origin.GetLengthSquared() + LODElement::s_Offset;
Min_Clamp(distance, 0.0f);
//
//-------------------------------------------------
// Evaluate each LOD to see if it needs to be drawn
//-------------------------------------------------
//
for (int i=m_LODs.GetLength()-1; i>=0; --i)
{
Entry *entry = &m_LODs[i];
if (entry->m_nearSquared <= distance && entry->m_farSquared >= distance)
{
Element *element = m_list[i];
Check_Object(element);
//
//-----------------------------------------
// Set the fade color if we are in the band
//-----------------------------------------
//
StateChange mixed(*inherited_state);
unsigned j;
for (j=0; j<MidLevelRenderer::Limits::Max_Number_Of_Lights_Per_Primitive && inherited_state->m_lights[j]; ++j)
{
Check_Object(inherited_state->m_lights[j]);
mixed.m_lights[j] = inherited_state->m_lights[j];
}
if(j<MidLevelRenderer::Limits::Max_Number_Of_Lights_Per_Primitive)
{
mixed.m_lights[j] = NULL;
}
Stuff::Scalar fade = FadeColor.alpha;
if (distance < entry->m_fadeInSquared)
{
Stuff::Scalar temp =
(distance - entry->m_nearSquared) / (entry->m_fadeInSquared - entry->m_nearSquared);
Verify(temp >= 0.0f && temp <= 1.0f);
FadeColor.alpha *= temp;
mixed.SetAlphaMode(MidLevelRenderer::MLRState::AlphaInvAlphaMode);
mixed.DisableChildAlphaControl();
mixed.SetRenderPriority(StateChange::AlphaPriority);
mixed.DisableChildRenderPriorityControl();
}
else if (distance > entry->m_fadeOutSquared)
{
Stuff::Scalar temp =
(entry->m_farSquared - distance) / (entry->m_farSquared - entry->m_fadeOutSquared);
Verify(temp >= 0.0f && temp <= 1.0f);
FadeColor.alpha *= temp;
mixed.SetAlphaMode(MidLevelRenderer::MLRState::AlphaInvAlphaMode);
mixed.DisableChildAlphaControl();
mixed.SetRenderPriority(StateChange::AlphaPriority);
mixed.DisableChildRenderPriorityControl();
}
camera->DrawElement(element, &mixed);
FadeColor.alpha = fade;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::MultiLODElement::OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
//
//-------------------
// Mix the properties
//-------------------
//
Check_Object(m_stateChange);
StateChange mixed;
mixed.Mix(*inherited_state, *m_stateChange);
MixLights(
mixed.m_lights,
inherited_state->m_lights,
m_stateChange->m_lights
);
//
//----------------------------------------------------------------------
// We need to find out which lod the camera should traverse into, so
// transform the camera into LOD space and get the distance from the LOD
//----------------------------------------------------------------------
//
Stuff::Point3D camera_origin(camera->GetLocalToWorld());
Stuff::Point3D lod_origin(GetLocalToWorld());
camera_origin -= lod_origin;
Stuff::Scalar distance = camera_origin.GetLengthSquared() + LODElement::s_Offset;
Min_Clamp(distance, 0.0f);
//
//-------------------------------------------------
// Evaluate each LOD to see if it needs to be drawn
//-------------------------------------------------
//
for (int i=m_LODs.GetLength()-1; i>=0; --i)
{
Entry *entry = &m_LODs[i];
if (entry->m_nearSquared <= distance && entry->m_farSquared >= distance)
{
Element *element = m_list[i];
Check_Object(element);
//
//-----------------------------------------
// Set the fade color if we are in the band
//-----------------------------------------
//
Stuff::Scalar fade = FadeColor.alpha;
if (distance < entry->m_fadeInSquared)
{
Stuff::Scalar temp =
(distance - entry->m_nearSquared) / (entry->m_fadeInSquared - entry->m_nearSquared);
Verify(temp >= 0.0f && temp <= 1.0f);
FadeColor.alpha *= temp;
mixed.SetAlphaMode(MidLevelRenderer::MLRState::AlphaInvAlphaMode);
mixed.DisableChildAlphaControl();
mixed.SetRenderPriority(StateChange::AlphaPriority);
mixed.DisableChildRenderPriorityControl();
}
else if (distance > entry->m_fadeOutSquared)
{
Stuff::Scalar temp =
(entry->m_farSquared - distance) / (entry->m_farSquared - entry->m_fadeOutSquared);
Verify(temp >= 0.0f && temp <= 1.0f);
FadeColor.alpha *= temp;
mixed.SetAlphaMode(MidLevelRenderer::MLRState::AlphaInvAlphaMode);
mixed.DisableChildAlphaControl();
mixed.SetRenderPriority(StateChange::AlphaPriority);
mixed.DisableChildRenderPriorityControl();
}
camera->DrawElement(element, &mixed);
FadeColor.alpha = fade;
}
}
}
@@ -0,0 +1,108 @@
#pragma once
#include "ElementRenderer.hpp"
#include "ListElement.hpp"
//#########################################################################
//######################### MultiLODElement ###############################
//#########################################################################
namespace ElementRenderer {
class GroupElement;
class MultiLODElement:
public ListElement
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef ListElement BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
MultiLODElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
);
public:
MultiLODElement();
~MultiLODElement();
static MultiLODElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
static HGOSHEAP s_Heap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
public:
struct Entry
{
Stuff::Scalar
m_nearSquared,
m_fadeInSquared,
m_fadeOutSquared,
m_farSquared;
};
void AttachLOD(
WORD index,
Element *element,
const Entry &entry
);
int AttachLODFirstAvailableSlot(
Element *element,
const Entry &entry
);
void SetSize(WORD total_cells);
protected:
void DetachChild(Element *child);
Stuff::DynamicArrayOf<Entry> m_LODs;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
};
}
@@ -0,0 +1,366 @@
#include "ElementRendererHeaders.hpp"
#include "PointCloudElement.hpp"
#include <MLR\MLRPointCloud.hpp>
//############################################################################
//############################ PointCloudElement ################################
//############################################################################
ElementRenderer::PointCloudElement::ClassData*
ElementRenderer::PointCloudElement::DefaultData = NULL;
ElementRenderer::Element::DrawMethod
ElementRenderer::PointCloudElement::DrawMethods[DrawStateCount]=
{
//
// No billboarding
//
DRAW_METHOD(PointCloudElement, Inherit),
DRAW_METHOD(PointCloudElement, Override)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
PointCloudElementClassID,
"ElementRenderer::PointCloudElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::PointCloudElement::PointCloudElement(
Stuff::MemoryStream *stream,
int version
):
Element(DefaultData, stream, version)
{
Check_Pointer(this);
Check_Object(stream);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
//
//---------------------------------
// Create the shape from the stream
//---------------------------------
//
#if 0
m_MLRPointCloud = MidLevelRenderer::MLRPointCloud::Make(stream);
Register_Object(m_MLRPointCloud);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::PointCloudElement::PointCloudElement(unsigned max_points):
Element(DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
gos_PushCurrentHeap(MidLevelRenderer::Heap);
m_MLRPointCloud = new MidLevelRenderer::MLRPointCloud(max_points);
Register_Object(m_MLRPointCloud);
gos_PopCurrentHeap();
m_MLRPointCloud->TurnAllOn();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::PointCloudElement::~PointCloudElement()
{
Check_Object(this);
Unregister_Object(m_MLRPointCloud);
delete m_MLRPointCloud;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::PointCloudElement*
ElementRenderer::PointCloudElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(g_Heap);
PointCloudElement *element = new PointCloudElement(stream, version);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//-----------------------------
// Save the shape to the stream
//-----------------------------
//
#if 0
Check_Object(m_MLRPointCloud);
m_MLRPointCloud->Save(stream);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::AttachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("PointCloud elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::DetachChild(Element *child)
{
Check_Object(this);
Check_Object(child);
STOP(("PointCloud elements can't have children!"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementRenderer::PointCloudElement::CastCulledRay(CollisionQuery *query)
{
Check_Object(this);
Check_Object(query);
STOP(("PointCloud is not collidable!"));
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::Element*
ElementRenderer::PointCloudElement::FindSmallestElementContainingCulled(SphereTest *test)
{
Check_Object(this);
Check_Object(test);
STOP(("PointCloud is not collidable!"));
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::SetDrawState()
{
Check_Object(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
#if defined(_ARMOR)
if (!culling_state)
Verify(!Cull(camera));
#endif
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawEffectInformation info;
Check_Object(m_MLRPointCloud);
info.effect = m_MLRPointCloud;
info.clippingFlags.SetClippingState(culling_state);
Check_Object(&m_localToWorld);
info.effectToWorld = &m_localToWorld;
info.state = inherited_state->GetMLRState();
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::PointCloud::Inherited");
Start_Timer(Draw_Effects);
clipper->DrawEffect(&info);
Stop_Timer(Draw_Effects);
Start_Timer(Graph_Traversal);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int culling_state
)
{
Check_Object(this);
Check_Object(inherited_state);
Check_Object(camera);
Verify(culling_state != -1);
#if defined(_ARMOR)
if (!culling_state)
Verify(!Cull(camera));
#endif
//
//-------------------
// Mix the properties
//-------------------
//
Check_Object(m_stateChange);
StateChange mixed;
mixed.Mix(*inherited_state, *m_stateChange);
//
//--------------------------------------
// Draw our bounds if we are supposed to
//--------------------------------------
//
#if defined(LAB_ONLY)
Callback *callback = GetCallbackSet();
unsigned index = GetCallbackIndex();
if (callback && callback[index])
{
Check_Pointer(callback[index]);
(*callback[index])(camera, inherited_state, culling_state, this);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawEffectInformation info;
Check_Object(m_MLRPointCloud);
info.effect = m_MLRPointCloud;
info.clippingFlags.SetClippingState(culling_state);
Check_Object(&m_localToWorld);
info.effectToWorld = &m_localToWorld;
info.state = mixed.GetMLRState();
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::PointCloud::Overridden");
Start_Timer(Draw_Effects);
clipper->DrawEffect(&info);
Stop_Timer(Draw_Effects);
Start_Timer(Graph_Traversal);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
ElementRenderer::PointCloudElement::CountTriangles()
{
Check_Object(this);
STOP(("Not implemented"));
return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::PointCloudElement::SetDataPointers(
const unsigned *used_points,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
)
{
Check_Pointer(this);
Check_Pointer(used_points);
Check_Pointer(point_data);
Check_Pointer(color_data);
Check_Object(m_MLRPointCloud);
m_MLRPointCloud->SetData(
reinterpret_cast<const int*>(used_points),
point_data,
color_data
);
}
@@ -0,0 +1,103 @@
#pragma once
#include "ElementRenderer.hpp"
namespace MidLevelRenderer {
class MLRPointCloud;
}
namespace ElementRenderer {
//#########################################################################
//######################### PointCloudElement ################################
//#########################################################################
class PointCloudElement:
public Element
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
typedef Element BaseClass;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
PointCloudElement(
Stuff::MemoryStream *stream,
int version
);
public:
PointCloudElement(unsigned max_points);
~PointCloudElement();
static PointCloudElement* Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes=NULL
);
void Save(Stuff::MemoryStream *stream);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void TestInstance();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hierarchy
//
protected:
void AttachChild(Element *child);
void DetachChild(Element *child);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collision
//
protected:
bool CastCulledRay(CollisionQuery *query);
Element* FindSmallestElementContainingCulled(SphereTest *test);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Drawing
//
protected:
void SetDrawState();
static DrawMethod DrawMethods[DrawStateCount];
void InheritDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
void OverrideDrawMethod(
CameraElement *camera,
const StateChange *inherited_state,
int clipping_state
);
int CountTriangles();
public:
MidLevelRenderer::MLRPointCloud* GetPointCloud()
{Check_Object(this); return m_MLRPointCloud;}
void SetDataPointers(
const unsigned *used_points,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
);
protected:
MidLevelRenderer::MLRPointCloud *m_MLRPointCloud;
};
}

Some files were not shown because too many files have changed in this diff Show More