Files
Cyd 2b8ca921cb 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.
2026-06-24 21:28:16 -05:00

728 lines
20 KiB
C++

#include "ElementRendererHeaders.hpp"
//#define SCALE_BUG "your_loginname_here"
//############################################################################
//############################ ScalableShapeElement ################################
//############################################################################
HGOSHEAP
ElementRenderer::ScalableShapeElement::s_Heap = NULL;
ElementRenderer::ScalableShapeElement::ClassData*
ElementRenderer::ScalableShapeElement::DefaultData = NULL;
ElementRenderer::Element::SyncMethod
ElementRenderer::ScalableShapeElement::SyncMethods[SyncStateCount]=
{
//
// Root mode
//
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
//
// Sphere Cull
//
SYNC_METHOD(ScalableShapeElement, CleanSphere),
SYNC_METHOD(ScalableShapeElement, DirtySphere),
SYNC_METHOD(ScalableShapeElement, CleanSphere),
SYNC_METHOD(ScalableShapeElement, DirtySphere),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
//
// OBB Cull
//
SYNC_METHOD(ScalableShapeElement, CleanOBB),
SYNC_METHOD(ScalableShapeElement, DirtyOBB),
SYNC_METHOD(ScalableShapeElement, CleanOBB),
SYNC_METHOD(ScalableShapeElement, DirtyOBB),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
//
// Never Cull
//
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, Clean),
SYNC_METHOD(Element, Dirty),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, Defer),
//
// Always Cull
//
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None),
SYNC_METHOD(Element, None)
};
ElementRenderer::Element::DrawMethod
ElementRenderer::ScalableShapeElement::DrawMethods[DrawStateCount]=
{
//
// No billboarding
//
DRAW_METHOD(ScalableShapeElement, Inherit),
DRAW_METHOD(ScalableShapeElement, Override)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::InitializeClass()
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("Scalable Shape", 0, g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
ScalableShapeElementClassID,
"ElementRenderer::ScalableShapeElement",
BaseClass::DefaultData,
reinterpret_cast<Factory>(&Make)
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::ScalableShapeElement::ScalableShapeElement(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes,
bool read_scale_from_stream
):
ShapeElement(DefaultData, stream, version, shapes)
{
Check_Pointer(this);
Check_Object(stream);
unsigned index = (m_state>>SyncStateBit) & SyncStateMask;
Verify(index < SyncStateCount);
m_sync = SyncMethods[index];
index = (m_state>>CullStateBit) & CullStateMask;
Verify(index < CullStateCount);
m_cameraCull = CullMethods[index].m_cameraCull;
m_rayCull = CullMethods[index].m_rayCull;
m_sphereTest = CullMethods[index].m_sphereTest;
index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
//
//------------------------
// Get the scale and color
//------------------------
//
if (read_scale_from_stream)
*stream >> m_scale >> m_color;
else
{
m_scale.x = 1.0f;
m_scale.y = 1.0f;
m_scale.z = 1.0f;
m_color.red = 1.0f;
m_color.green = 1.0f;
m_color.blue = 1.0f;
m_color.alpha = 1.0f;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::ScalableShapeElement::ScalableShapeElement():
ShapeElement(DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>SyncStateBit) & SyncStateMask;
Verify(index < SyncStateCount);
m_sync = SyncMethods[index];
index = (m_state>>CullStateBit) & CullStateMask;
Verify(index < CullStateCount);
m_cameraCull = CullMethods[index].m_cameraCull;
m_rayCull = CullMethods[index].m_rayCull;
m_sphereTest = CullMethods[index].m_sphereTest;
index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
m_scale.x = 1.0f;
m_scale.y = 1.0f;
m_scale.z = 1.0f;
m_color.red = 1.0f;
m_color.green = 1.0f;
m_color.blue = 1.0f;
m_color.alpha = 1.0f;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::ScalableShapeElement::ScalableShapeElement(ScalableShapeElement *shape):
ShapeElement(shape, DefaultData)
{
Check_Pointer(this);
unsigned index = (m_state>>SyncStateBit) & SyncStateMask;
Verify(index < SyncStateCount);
m_sync = SyncMethods[index];
index = (m_state>>CullStateBit) & CullStateMask;
Verify(index < CullStateCount);
m_cameraCull = CullMethods[index].m_cameraCull;
m_rayCull = CullMethods[index].m_rayCull;
m_sphereTest = CullMethods[index].m_sphereTest;
index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
m_scale.x = 1.0f;
m_scale.y = 1.0f;
m_scale.z = 1.0f;
m_color.red = 1.0f;
m_color.green = 1.0f;
m_color.blue = 1.0f;
m_color.alpha = 1.0f;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::ScalableShapeElement*
ElementRenderer::ScalableShapeElement::Make(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
gos_PushCurrentHeap(s_Heap);
ScalableShapeElement *element =
new ScalableShapeElement(stream, version, shapes, true);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::ScalableShapeElement*
ElementRenderer::ScalableShapeElement::MakeFromShape(
Stuff::MemoryStream *stream,
int version,
ShapeHolder shapes
)
{
Check_Object(stream);
RegisteredClass::ClassID class_id;
*stream >> class_id;
Verify(class_id == ShapeElementClassID);
gos_PushCurrentHeap(s_Heap);
ScalableShapeElement *element =
new ScalableShapeElement(stream, version, shapes, false);
gos_PopCurrentHeap();
return element;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
//
//-----------------------------
// Save the shape to the stream
//-----------------------------
//
*stream << m_scale << m_color;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::SetSyncState()
{
Check_Object(this);
Verify(
GetCullMode() != VolumeCullMode
|| AreBoundsWrong()
|| IsSyncDeferred()
|| (
m_localOBB.sphereRadius>0.0f
&& (IsMatrixDirty() || m_worldOBB.sphereRadius>0.0f
)
)
);
Verify(
GetCullMode() == RootMode || m_parent != NULL || AreBoundsWrong()
);
unsigned index = (m_state>>SyncStateBit) & SyncStateMask;
Verify(index < SyncStateCount);
m_sync = SyncMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::CleanSphereSyncMethod()
{
Check_Object(this);
Verify(m_localOBB.sphereRadius > 0.0f);
Verify(
!IsMatrixDirty() && GetCullMode()==VolumeCullMode && IsBoundedBySphere()
);
SYNC_LOGIC("Sphere::Clean::ScalableShape");
//
//-------------------------------
// Update our m_localToWorld matrix
//-------------------------------
//
Check_Object(m_parent);
if (!IsLocalToParentIdentity())
m_localToWorld.Multiply(m_localToParent, m_parent->GetLocalToWorld());
else
m_localToWorld = m_parent->GetLocalToWorld();
//
//------------------------------
// Transform the bounding sphere
//------------------------------
//
Stuff::Point3D local_origin(m_localOBB.localToParent);
local_origin *= m_scale;
m_worldOBB.localToParent(3,0) =
local_origin.x*m_localToWorld(0,0)
+ local_origin.y*m_localToWorld(1,0)
+ local_origin.z*m_localToWorld(2,0)
+ m_localToWorld(3,0);
m_worldOBB.localToParent(3,1) =
local_origin.x*m_localToWorld(0,1)
+ local_origin.y*m_localToWorld(1,1)
+ local_origin.z*m_localToWorld(2,1)
+ m_localToWorld(3,1);
m_worldOBB.localToParent(3,2) =
local_origin.x*m_localToWorld(0,2)
+ local_origin.y*m_localToWorld(1,2)
+ local_origin.z*m_localToWorld(2,2)
+ m_localToWorld(3,2);
m_worldOBB.sphereRadius = m_localOBB.sphereRadius * m_scale.GetLength();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::DirtySphereSyncMethod()
{
Check_Object(this);
Verify(m_localOBB.sphereRadius > 0.0f);
Verify(
IsMatrixDirty() && GetCullMode()==VolumeCullMode && IsBoundedBySphere()
);
SYNC_LOGIC("Sphere::Dirty::ScalableShape");
//
//--------------------
// 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();
//
//------------------------------
// Transform the bounding sphere
//------------------------------
//
Stuff::Point3D local_origin(m_localOBB.localToParent);
local_origin *= m_scale;
m_worldOBB.localToParent(3,0) =
local_origin.x*m_localToWorld(0,0)
+ local_origin.y*m_localToWorld(1,0)
+ local_origin.z*m_localToWorld(2,0)
+ m_localToWorld(3,0);
m_worldOBB.localToParent(3,1) =
local_origin.x*m_localToWorld(0,1)
+ local_origin.y*m_localToWorld(1,1)
+ local_origin.z*m_localToWorld(2,1)
+ m_localToWorld(3,1);
m_worldOBB.localToParent(3,2) =
local_origin.x*m_localToWorld(0,2)
+ local_origin.y*m_localToWorld(1,2)
+ local_origin.z*m_localToWorld(2,2)
+ m_localToWorld(3,2);
m_worldOBB.sphereRadius = m_localOBB.sphereRadius * m_scale.GetLength();
MatrixIsClean();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::CleanOBBSyncMethod()
{
Check_Object(this);
Verify(
!IsMatrixDirty() && GetCullMode()==VolumeCullMode && IsBoundedByOBB()
);
Verify(Stuff::Close_Enough(m_localOBB.sphereRadius, m_localOBB.axisExtents.GetLength(), m_localOBB.sphereRadius*0.02f));
Verify(
Stuff::Close_Enough(m_localOBB.localToParent(0,0), 1.0f) &&
Stuff::Close_Enough(m_localOBB.localToParent(1,1), 1.0f) &&
Stuff::Close_Enough(m_localOBB.localToParent(2,2), 1.0f)
);
SYNC_LOGIC("OBB::Clean::ScalableShape");
//
//-------------------------------
// Update our m_localToWorld matrix
//-------------------------------
//
Check_Object(m_parent);
if (!IsLocalToParentIdentity())
m_localToWorld.Multiply(m_localToParent, m_parent->GetLocalToWorld());
else
m_localToWorld = m_parent->GetLocalToWorld();
//
//------------------------------
// Transform the bounding sphere
//------------------------------
//
Stuff::LinearMatrix4D scaled_transform = m_localOBB.localToParent;
scaled_transform(3,0) *= m_scale.x;
scaled_transform(3,1) *= m_scale.y;
scaled_transform(3,2) *= m_scale.z;
m_worldOBB.localToParent.Multiply(scaled_transform, m_localToWorld);
m_worldOBB.axisExtents.Multiply(m_localOBB.axisExtents, m_scale);
m_worldOBB.sphereRadius = m_worldOBB.axisExtents.GetLength();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::DirtyOBBSyncMethod()
{
Check_Object(this);
Verify(
IsMatrixDirty() && GetCullMode()==VolumeCullMode && IsBoundedByOBB()
);
Verify(Stuff::Close_Enough(m_localOBB.sphereRadius, m_localOBB.axisExtents.GetLength(), m_localOBB.sphereRadius*0.02f));
Verify(
Stuff::Close_Enough(m_localOBB.localToParent(0,0), 1.0f) &&
Stuff::Close_Enough(m_localOBB.localToParent(1,1), 1.0f) &&
Stuff::Close_Enough(m_localOBB.localToParent(2,2), 1.0f)
);
SYNC_LOGIC("OBB::Dirty::ScalableShape");
//
//--------------------
// 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();
//
//------------------------------
// Transform the bounding sphere
//------------------------------
//
Stuff::LinearMatrix4D scaled_transform = m_localOBB.localToParent;
scaled_transform(3,0) *= m_scale.x;
scaled_transform(3,1) *= m_scale.y;
scaled_transform(3,2) *= m_scale.z;
m_worldOBB.localToParent.Multiply(scaled_transform, m_localToWorld);
m_worldOBB.axisExtents.Multiply(m_localOBB.axisExtents, m_scale);
m_worldOBB.sphereRadius = m_worldOBB.axisExtents.GetLength();
#if defined(SCALE_BUG)
SPEW((SCALE_BUG, "m_worldOBB = "));
Spew(SCALE_BUG, m_worldOBB);
SPEW((SCALE_BUG, ""));
#endif
MatrixIsClean();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementRenderer::ScalableShapeElement::CastCulledRay(CollisionQuery *query)
{
Check_Object(this);
Check_Object(query);
STOP(("ScalableShape is not collidable!"));
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::Element*
ElementRenderer::ScalableShapeElement::FindSmallestElementContainingCulled(SphereTest *test)
{
Check_Object(this);
Check_Object(test);
STOP(("ScalableShape is not collidable!"));
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::SetDrawState()
{
Check_Object(this);
unsigned index = (m_state>>DrawStateBit) & DrawStateMask;
Verify(index < DrawStateCount);
m_draw = DrawMethods[index];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::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);
}
else if (s_ShowClippedBounds && GetCullMode() == VolumeCullMode && culling_state)
{
Stuff::RGBAColor color(1.0f, 0.5f, 0.5f, 0.3f);
if (IsBoundedBySphere())
DrawSphere(m_worldOBB, color, camera, inherited_state, culling_state);
else
DrawOBB(m_worldOBB, color, camera, inherited_state, culling_state);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawScalableShapeInformation info;
Check_Object(m_MLRShape);
info.shape = m_MLRShape;
info.clippingFlags.SetClippingState(culling_state);
Check_Object(&m_localToWorld);
info.shapeToWorld = &m_localToWorld;
info.worldToShape = NULL;
info.state = inherited_state->GetMLRState();
LightList culled_lights;
info.nrOfActiveLights = CullLights(culled_lights, inherited_state->m_lights);
info.activeLights = (info.nrOfActiveLights>0) ? &culled_lights[0] : NULL;
info.scaling = &m_scale;
info.paintMeColor = &m_color;
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::ScalableShape::Inherited");
Start_Timer(Draw_Scalable);
clipper->DrawScalableShape(&info);
Stop_Timer(Draw_Scalable);
Start_Timer(Graph_Traversal);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementRenderer::ScalableShapeElement::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);
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, &mixed, culling_state, this);
}
else if (s_ShowClippedBounds && GetCullMode() == VolumeCullMode && culling_state)
{
Stuff::RGBAColor color(1.0f, 0.5f, 0.5f, 0.3f);
if (IsBoundedBySphere())
DrawSphere(m_worldOBB, color, camera, &mixed, culling_state);
else
DrawOBB(m_worldOBB, color, camera, &mixed, culling_state);
}
#endif
//
//----------------------------
// Set up the draw information
//----------------------------
//
MidLevelRenderer::DrawScalableShapeInformation info;
Check_Object(m_MLRShape);
info.shape = m_MLRShape;
info.clippingFlags.SetClippingState(culling_state);
Check_Object(&m_localToWorld);
info.shapeToWorld = &m_localToWorld;
info.worldToShape = NULL;
info.state = mixed.GetMLRState();
LightList culled_lights;
info.nrOfActiveLights = CullLights(culled_lights, mixed.m_lights);
info.activeLights = (info.nrOfActiveLights>0) ? &culled_lights[0] : NULL;
info.scaling = &m_scale;
info.paintMeColor = &m_color;
//
//---------------
// Draw the shape
//---------------
//
MidLevelRenderer::MLRClipper *clipper = camera->GetClipper();
Check_Object(clipper);
Stop_Timer(Graph_Traversal);
ELEMENT_RENDER("Culling::ScalableShape::Overridden");
Start_Timer(Draw_Scalable);
clipper->DrawScalableShape(&info);
Stop_Timer(Draw_Scalable);
Start_Timer(Graph_Traversal);
}