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.
951 lines
21 KiB
C++
951 lines
21 KiB
C++
#include "MLRHeaders.hpp"
|
|
#include "MLR\MLRFootstep.hpp"
|
|
|
|
//#############################################################################
|
|
//############################### MLRShape ##################################
|
|
//#############################################################################
|
|
|
|
// This switch is used by 3dsMax Animationsuite. Set to 0 when importing ERF
|
|
int g_bConvertMeshes = 1;
|
|
extern DWORD gEnableBumpMap;
|
|
|
|
MLRShape::ClassData*
|
|
MLRShape::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
Verify(gos_GetCurrentHeap() == StaticHeap);
|
|
DefaultData =
|
|
new ClassData(
|
|
MLRShapeClassID,
|
|
"MidLevelRenderer::MLRShape",
|
|
Plug::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRShape::MLRShape(
|
|
ClassData *class_data,
|
|
MemoryStream *stream,
|
|
int version
|
|
):
|
|
Plug(class_data)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(stream);
|
|
Verify(gos_GetCurrentHeap() == ShapeHeap);
|
|
|
|
if(version<15)
|
|
{
|
|
int np;
|
|
*stream >> np;
|
|
numPrimitives = static_cast<BYTE>(np);
|
|
}
|
|
else
|
|
{
|
|
*stream >> numPrimitives;
|
|
}
|
|
|
|
allPrimitives.SetLength(numPrimitives);
|
|
|
|
for(int i=0;i<numPrimitives;i++)
|
|
{
|
|
MLRPrimitiveBase *pt = NULL;
|
|
switch(version)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
{
|
|
STOP(("Lower than version 3 is not supported anymore !"));
|
|
/*
|
|
MLRPrimitive *pt_old;
|
|
|
|
RegisteredClass::ClassID class_id;
|
|
*stream >> class_id;
|
|
MLRPrimitive::ClassData* class_data =
|
|
Cast_Object(MLRPrimitive::ClassData*, FindClassData(class_id));
|
|
pt_old = (*class_data->primitiveFactory)(stream, version);
|
|
Register_Object(pt_old);
|
|
|
|
int i, nr, test;
|
|
|
|
if(pt_old->GetReferenceState().GetLightingMode() == MLRState::LightingOffMode)
|
|
{
|
|
test = 0;
|
|
}
|
|
else
|
|
{
|
|
test = 2;
|
|
}
|
|
|
|
#if COLOR_AS_DWORD
|
|
DWORD* colors;
|
|
#else
|
|
RGBAColor *colors, testColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
#endif
|
|
Cast_Pointer(MLRIndexedPolyMesh*, pt_old)->GetColorData(&colors, &nr);
|
|
|
|
for(i=0;i<nr;i++)
|
|
{
|
|
#if COLOR_AS_DWORD
|
|
if(colors[i] != 0xffffffff)
|
|
#else
|
|
if(colors[i] != testColor)
|
|
#endif
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(i<nr)
|
|
{
|
|
test |= 1;
|
|
}
|
|
|
|
switch (test)
|
|
{
|
|
case 0:
|
|
pt = new MLR_I_PMesh;
|
|
|
|
Cast_Pointer(MLR_I_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
|
|
break;
|
|
case 1:
|
|
pt = new MLR_I_C_PMesh;
|
|
|
|
Cast_Pointer(MLR_I_C_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
|
|
break;
|
|
default:
|
|
pt = new MLR_I_L_PMesh;
|
|
|
|
Cast_Pointer(MLR_I_L_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
|
|
break;
|
|
}
|
|
pt_old->DetachReference();
|
|
*/
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
RegisteredClass::ClassID class_id;
|
|
*stream >> class_id;
|
|
MLRPrimitiveBase::ClassData* class_data =
|
|
Cast_Pointer(MLRPrimitiveBase::ClassData*, FindClassData(class_id));
|
|
Check_Object(class_data);
|
|
pt = (*class_data->primitiveFactory)(stream, version);
|
|
Register_Object(pt);
|
|
|
|
if( g_bConvertMeshes &&
|
|
ConvertToTriangleMeshes == true && (
|
|
pt->IsDerivedFrom(MLR_I_PMesh::DefaultData) ||
|
|
pt->IsDerivedFrom(MLR_I_C_PMesh::DefaultData) ||
|
|
pt->IsDerivedFrom(MLR_I_L_PMesh::DefaultData)
|
|
)
|
|
)
|
|
{
|
|
const BYTE *length;
|
|
int i, num, threes, nonThrees;
|
|
|
|
pt->GetSubprimitiveLengths(&length, &num);
|
|
|
|
for(i=0,threes=0,nonThrees=0;i<num;i++)
|
|
{
|
|
if(length[i]==3)
|
|
{
|
|
threes++;
|
|
}
|
|
else
|
|
{
|
|
nonThrees++;
|
|
}
|
|
}
|
|
if(threes>0 && nonThrees==0) //threes > 9*nonThrees)
|
|
{
|
|
MLRPrimitiveBase *pt_old = pt;
|
|
|
|
if(pt->GetClassData() == MLR_I_L_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_L_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_L_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_C_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_C_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_L_DT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_L_DT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_L_DT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_DT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_C_DT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_C_DT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_DT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_DT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_DT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_L_DeT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_L_DeT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_L_DeT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DeT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_DeT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_C_DeT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_C_DeT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DeT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_DeT_PMesh::DefaultData)
|
|
{
|
|
gos_PushCurrentHeap(MLR_I_DeT_TMesh::PrimitiveHeap);
|
|
pt = new MLR_I_DeT_TMesh;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DeT_PMesh*, pt_old));
|
|
}
|
|
pt_old->DetachReference();
|
|
}
|
|
}
|
|
else if(gEnableBumpMap>0)
|
|
{
|
|
if(pt->IsDerivedFrom(MLR_Water::DefaultData))
|
|
{
|
|
MLRPrimitiveBase *pt_old = pt;
|
|
|
|
static MLRTexture *bumptex1 = NULL;
|
|
static MLRTexture *bumptex2 = NULL;
|
|
static MLRTexture *bumptex3 = NULL;
|
|
|
|
if(bumptex1 == NULL)
|
|
{
|
|
bumptex1 = MLRTexturePool::Instance->Add("waterbump");
|
|
bumptex2 = MLRTexturePool::Instance->Add("waterenv");
|
|
bumptex3 = MLRTexturePool::Instance->Add("waterbumpnormal");
|
|
}
|
|
|
|
if(bumptex1 != NULL && bumptex2 != NULL)
|
|
{
|
|
gos_PushCurrentHeap(MLR_Water::PrimitiveHeap);
|
|
pt = new MLR_BumpyWater;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_BumpyWater*, pt)->SetTextures(
|
|
bumptex1->GetTextureHandle(),
|
|
bumptex2->GetTextureHandle(),
|
|
bumptex3->GetTextureHandle()
|
|
);
|
|
Cast_Pointer(MLR_BumpyWater*, pt)->Copy(Cast_Pointer(MLR_Water*, pt_old));
|
|
|
|
pt_old->DetachReference();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
allPrimitives[i] = pt;
|
|
}
|
|
|
|
referenceCount = 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRShape::MLRShape(int nr, ClassData *class_data):
|
|
Plug(class_data), allPrimitives(nr ? nr : 4)
|
|
{
|
|
Verify(gos_GetCurrentHeap() == ShapeHeap);
|
|
numPrimitives = 0;
|
|
referenceCount = 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRShape::~MLRShape()
|
|
{
|
|
int i;
|
|
MLRPrimitiveBase *pt;
|
|
|
|
for(i=numPrimitives-1;i>=0;i--)
|
|
{
|
|
pt = allPrimitives[i];
|
|
allPrimitives[i] = NULL;
|
|
|
|
pt->DetachReference();
|
|
|
|
}
|
|
|
|
Verify(referenceCount==0);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRShape*
|
|
MLRShape::Make(
|
|
MemoryStream *stream,
|
|
int version
|
|
)
|
|
{
|
|
Check_Object(stream);
|
|
|
|
gos_PushCurrentHeap(ShapeHeap);
|
|
MLRShape *shape = new MLRShape(DefaultData, stream, version);
|
|
gos_PopCurrentHeap();
|
|
|
|
return shape;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::Save(MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
*stream << GetClassID();
|
|
*stream << numPrimitives;
|
|
|
|
MLRPrimitiveBase *pt = NULL;
|
|
int i;
|
|
|
|
gos_PushCurrentHeap(ShapeHeap);
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
pt = allPrimitives[i];
|
|
Check_Object(pt);
|
|
|
|
|
|
if( g_bConvertMeshes && ConvertToTriangleMeshes == true && (
|
|
pt->IsDerivedFrom(MLR_I_PMesh::DefaultData) ||
|
|
pt->IsDerivedFrom(MLR_I_C_PMesh::DefaultData) ||
|
|
pt->IsDerivedFrom(MLR_I_L_PMesh::DefaultData)
|
|
)
|
|
)
|
|
{
|
|
const BYTE *length;
|
|
int i, num, threes, nonThrees;
|
|
|
|
pt->GetSubprimitiveLengths(&length, &num);
|
|
|
|
for(i=0,threes=0,nonThrees=0;i<num;i++)
|
|
{
|
|
if(length[i]==3)
|
|
{
|
|
threes++;
|
|
}
|
|
else
|
|
{
|
|
nonThrees++;
|
|
}
|
|
}
|
|
if(threes>0 && nonThrees==0) //threes > 9*nonThrees)
|
|
{
|
|
MLRPrimitiveBase *pt_old = pt;
|
|
|
|
if(pt->GetClassData() == MLR_I_L_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_L_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_C_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_L_DT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_L_DT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_DT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_C_DT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_DT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_DT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_L_DeT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_L_DeT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_L_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DeT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_C_DeT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_C_DeT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_C_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DeT_PMesh*, pt_old));
|
|
}
|
|
else if(pt->GetClassData() == MLR_I_DeT_PMesh::DefaultData)
|
|
{
|
|
pt = new MLR_I_DeT_TMesh;
|
|
Register_Object(pt);
|
|
|
|
Cast_Pointer(MLR_I_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DeT_PMesh*, pt_old));
|
|
}
|
|
pt_old->DetachReference();
|
|
}
|
|
}
|
|
allPrimitives[i] = pt;
|
|
allPrimitives[i]->Save(stream);
|
|
}
|
|
gos_PopCurrentHeap();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::Add (MLRPrimitiveBase *p)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Verify(Find(p)<0);
|
|
|
|
if(numPrimitives >= allPrimitives.GetLength() || allPrimitives.GetLength() == 0)
|
|
{
|
|
gos_PushCurrentHeap(ShapeHeap);
|
|
allPrimitives.SetLength(numPrimitives + 4);
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
allPrimitives[numPrimitives] = p;
|
|
p->AttachReference();
|
|
|
|
numPrimitives++;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MLRShape::GetNumPrimitives()
|
|
{
|
|
int i, ret = 0;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
ret += allPrimitives[i]->GetNumPrimitives();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MLRShape::GetNumDrawnTriangles()
|
|
{
|
|
int i, j, ret = 0;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
if(allPrimitives[i]->IsDerivedFrom(MLRIndexedPrimitiveBase::DefaultData))
|
|
{
|
|
j = (Cast_Pointer(MLRIndexedPrimitiveBase*, allPrimitives[i]))->GetNumGOSIndices();
|
|
}
|
|
else
|
|
{
|
|
j = allPrimitives[i]->GetNumGOSVertices();
|
|
}
|
|
if(j!=0xffff)
|
|
{
|
|
ret += j;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRPrimitiveBase*
|
|
MLRShape::Find (int i)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Verify(i<numPrimitives);
|
|
|
|
return allPrimitives[i];
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MLRShape::Find (MLRPrimitiveBase *p)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(p);
|
|
|
|
int i;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
if(allPrimitives[i] == p)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MLRShape::Replace (MLRPrimitiveBase *pout, MLRPrimitiveBase *pin)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(pout);
|
|
Check_Object(pin);
|
|
|
|
int num = Find (pout);
|
|
|
|
if(num>=0)
|
|
{
|
|
pout->DetachReference();
|
|
allPrimitives[num] = pin;
|
|
pin->AttachReference();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRPrimitiveBase*
|
|
MLRShape::Remove(MLRPrimitiveBase *p)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(p);
|
|
|
|
int i, nr = Find(p);
|
|
|
|
if(nr < 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for(i=nr;i<numPrimitives-1;i++)
|
|
{
|
|
allPrimitives[i] = allPrimitives[i+1];
|
|
}
|
|
|
|
allPrimitives[i] = NULL;
|
|
|
|
numPrimitives--;
|
|
p->DetachReference();
|
|
|
|
return p;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRPrimitiveBase*
|
|
MLRShape::Remove(int nr)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i;
|
|
MLRPrimitiveBase *p = Find(nr);
|
|
|
|
if(nr < 0 || nr >= numPrimitives)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for(i=nr;i<numPrimitives-1;i++)
|
|
{
|
|
allPrimitives[i] = allPrimitives[i+1];
|
|
}
|
|
|
|
allPrimitives[i] = NULL;
|
|
|
|
numPrimitives--;
|
|
p->DetachReference();
|
|
|
|
return p;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MLRShape::Insert(MLRPrimitiveBase *p, int nr)
|
|
{
|
|
Check_Object(this);
|
|
|
|
if(nr >= numPrimitives)
|
|
{
|
|
Add(p);
|
|
|
|
return numPrimitives;
|
|
}
|
|
|
|
if(numPrimitives >= allPrimitives.GetLength() || allPrimitives.GetLength() == 0)
|
|
{
|
|
gos_PushCurrentHeap(ShapeHeap);
|
|
allPrimitives.SetLength(numPrimitives + 4);
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
|
|
int i;
|
|
|
|
for(i=numPrimitives;i>nr;i--)
|
|
{
|
|
allPrimitives[i] = allPrimitives[i-1];
|
|
}
|
|
|
|
allPrimitives[i] = p;
|
|
p->AttachReference();
|
|
|
|
numPrimitives++;
|
|
|
|
return numPrimitives;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::InitializePrimitives(BYTE vis, const MLRState& master, int parameter)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->InitializeDrawPrimitive(vis, parameter);
|
|
|
|
allPrimitives[i]->CombineStates(master);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::CleanMe()
|
|
{
|
|
for(int i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->CleanMe();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::HurtMe(const Stuff::LinearMatrix4D& pain, Stuff::Scalar radius)
|
|
{
|
|
for(int i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->HurtMe(pain, radius);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::HurtMe(const Stuff::LinearMatrix4D& pain, Stuff::Scalar radius, MLRTexture *tex)
|
|
{
|
|
int num = numPrimitives;
|
|
for(int i=0;i<num;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
MLRPrimitiveBase *p = allPrimitives[i]->HurtMe(pain, radius, tex);
|
|
|
|
if(p!=NULL)
|
|
{
|
|
Add(p);
|
|
p->DetachReference();
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::StepOnMe(
|
|
MLRShape *shape,
|
|
const Stuff::LinearMatrix4D& foot,
|
|
Stuff::Scalar radius,
|
|
MLRTexture *tex
|
|
)
|
|
{
|
|
Check_Object(&foot);
|
|
Check_Object(shape);
|
|
|
|
if(MLRFootStep::Instance == NULL || MLRFootStep::Instance->ShowSteps()==false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int num = numPrimitives;
|
|
|
|
UnitVector3D u;
|
|
|
|
for(int i=0;i<num;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
if(allPrimitives[i]->IsDerivedFrom(MLR_Terrain2::DefaultData))
|
|
{
|
|
MLRPrimitiveBase *p = (Cast_Pointer(MLR_Terrain2*, allPrimitives[i]))->StepOnMe(foot, radius, tex);
|
|
|
|
if(p!=NULL)
|
|
{
|
|
shape->Add(p);
|
|
p->DetachReference();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// point is at the center of the bottom edge of the texture, uvec is light
|
|
// direction and the direction the texture is oriented in
|
|
//
|
|
void
|
|
MLRShape::DrawMyShadow(const Stuff::LinearMatrix4D& point, Stuff::UnitVector3D& uvec, Stuff::Scalar radius, DWORD color)
|
|
{
|
|
for(int i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->DrawMyShadow(point, uvec, radius, color);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/* p is the eye point
|
|
int
|
|
MLRShape::FindBackFace(const Point3D& p, const Normal3D& n)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i, ret = 0;
|
|
|
|
Point3D sp;
|
|
sp.Multiply(p, *worldToShape);
|
|
|
|
Normal3D np;
|
|
np.Multiply(n, *worldToShape);
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
ret += allPrimitives[i]->FindBackFace(sp, np);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
*/
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/*
|
|
void
|
|
MLRShape::Transform(Matrix4D *mat)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->Transform(mat);
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::Transform()
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i;
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->Transform(&shapeToClipMatrix);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MLRShape::Clip(MLRClippingState clippingFlags, GOSVertexPool *vp)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i, ret = 0;
|
|
|
|
// gos_GetViewport( &ViewportScalars::MulX, &ViewportScalars::MulY, &ViewportScalars::AddX, &ViewportScalars::AddY );
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
ret += allPrimitives[i]->Clip(clippingFlags, vp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
*/
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRShape::Lighting (
|
|
const LinearMatrix4D& WorldToShape,
|
|
MLRLight* const* lights,
|
|
int nrLights,
|
|
BYTE what
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&WorldToShape);
|
|
|
|
if(nrLights == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
|
|
for(i=0;i<nrLights;i++)
|
|
{
|
|
lights[i]->SetLightToShapeMatrix(WorldToShape);
|
|
}
|
|
|
|
for(i=0;i<numPrimitives;i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
|
|
allPrimitives[i]->Lighting(lights, nrLights);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MLRShape::CastRay (
|
|
Line3D *line,
|
|
Normal3D *normal
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(line);
|
|
Check_Pointer(normal);
|
|
|
|
bool result = false;
|
|
for(int i=0; i<numPrimitives; i++)
|
|
{
|
|
Check_Object(allPrimitives[i]);
|
|
if (allPrimitives[i]->CastRay(line, normal))
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|