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.
385 lines
9.2 KiB
C++
385 lines
9.2 KiB
C++
#include "MLRHeaders.hpp"
|
|
|
|
//#############################################################################
|
|
//##################### MLRIndexedPrimitiveBase #########################
|
|
//#############################################################################
|
|
|
|
DynamicArrayOf<WORD>
|
|
*MLRIndexedPrimitiveBase::clipExtraIndex;
|
|
|
|
MLRIndexedPrimitiveBase::ClassData*
|
|
MLRIndexedPrimitiveBase::DefaultData = NULL;
|
|
|
|
WORD
|
|
*indexOffset;
|
|
|
|
Stuff::DynamicArrayOf<BYTE>
|
|
*MLRIndexedPrimitiveBase::visibleIndexedVertices = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
Verify(gos_GetCurrentHeap() == StaticHeap);
|
|
DefaultData =
|
|
new ClassData(
|
|
MLRIndexedPrimitiveBaseClassID,
|
|
"MidLevelRenderer::MLRIndexedPrimitiveBase",
|
|
MLRPrimitiveBase::DefaultData,
|
|
NULL
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
Verify(!clipExtraIndex);
|
|
clipExtraIndex = new DynamicArrayOf<WORD> (Limits::Max_Size_Of_Index_Buffer);
|
|
Check_Object(clipExtraIndex);
|
|
|
|
Verify(!indexOffset);
|
|
indexOffset = new WORD [Limits::Max_Size_Of_Index_Buffer];
|
|
Check_Pointer(indexOffset);
|
|
|
|
Verify(!visibleIndexedVertices);
|
|
visibleIndexedVertices = new DynamicArrayOf<BYTE>(Limits::Max_Number_Vertices_Per_Mesh);
|
|
Check_Object(visibleIndexedVertices);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::TerminateClass()
|
|
{
|
|
Check_Object(visibleIndexedVertices);
|
|
delete visibleIndexedVertices;
|
|
visibleIndexedVertices = NULL;
|
|
|
|
Check_Pointer(indexOffset);
|
|
delete [] indexOffset;
|
|
indexOffset = NULL;
|
|
|
|
Check_Object(clipExtraIndex);
|
|
delete clipExtraIndex;
|
|
clipExtraIndex = NULL;
|
|
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRIndexedPrimitiveBase::MLRIndexedPrimitiveBase(
|
|
ClassData *class_data,
|
|
MemoryStream *stream,
|
|
int version
|
|
):
|
|
MLRPrimitiveBase(class_data, stream, version)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(stream);
|
|
|
|
switch(version)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
{
|
|
STOP(("This class got created only after version 2 !"));
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
// Convert WORD indices to BYTE before version 18
|
|
if (version<18)
|
|
{
|
|
DynamicArrayOf<WORD> index_temp;
|
|
MemoryStreamIO_Read(stream, &index_temp);
|
|
if (dataStore == NULL)
|
|
{
|
|
dataStore = new DataStorage;
|
|
}
|
|
|
|
if((index_temp.GetLength()) % 3 != 0)
|
|
{
|
|
STOP(("Indices are not modula of 3"));
|
|
}
|
|
int len = index_temp.GetLength() / 3;
|
|
|
|
dataStore->index.SetLength(index_temp.GetLength());
|
|
|
|
int i, j;
|
|
for (i=0,j=0; i<len; ++i)
|
|
{
|
|
if(
|
|
index_temp[3*i] < Limits::Max_Number_Vertices_Per_Mesh &&
|
|
index_temp[3*i+1] < Limits::Max_Number_Vertices_Per_Mesh &&
|
|
index_temp[3*i+2] < Limits::Max_Number_Vertices_Per_Mesh
|
|
)
|
|
{
|
|
dataStore->index[3*j] = (BYTE) (index_temp[3*i] & 0xff);
|
|
dataStore->index[3*j+1] = (BYTE) (index_temp[3*i+1] & 0xff);
|
|
dataStore->index[3*j+2] = (BYTE) (index_temp[3*i+2] & 0xff);
|
|
|
|
j++;
|
|
}
|
|
}
|
|
|
|
dataStore->index.SetLength(3*j);
|
|
|
|
index.AssignData(dataStore->index.GetData(), dataStore->index.GetLength());
|
|
}
|
|
else
|
|
MemoryStreamIO_Read(stream, &index);
|
|
}
|
|
break;
|
|
}
|
|
|
|
visibleIndexedVerticesKey = false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::Save(MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
MLRPrimitiveBase::Save(stream);
|
|
|
|
MemoryStreamIO_Write(stream, &index);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRIndexedPrimitiveBase::MLRIndexedPrimitiveBase(ClassData *class_data):
|
|
MLRPrimitiveBase(class_data)
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRIndexedPrimitiveBase::~MLRIndexedPrimitiveBase()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::InitializeDrawPrimitive(BYTE vis, int parameter)
|
|
{
|
|
MLRPrimitiveBase::InitializeDrawPrimitive(vis, parameter);
|
|
|
|
gos_indices = NULL;
|
|
numGOSIndices = -1;
|
|
|
|
visibleIndexedVerticesKey = false;
|
|
int i, len = coords.GetLength();
|
|
|
|
for(i=0;i<len;i++)
|
|
{
|
|
(*visibleIndexedVertices)[i] = 0;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::SetCoordData(
|
|
const Point3D *data,
|
|
int dataSize
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(data);
|
|
|
|
// Verify(texCoords.GetLength() == 0 || dataSize == texCoords.GetLength());
|
|
|
|
#if defined (MAX_NUMBER_VERTICES)
|
|
Verify(dataSize <= MAX_NUMBER_VERTICES);
|
|
#endif
|
|
coords.AssignData(data, dataSize);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::SetIndexData(
|
|
const BYTE *index_array,
|
|
int index_count
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(index_array);
|
|
|
|
#ifdef _ARMOR
|
|
int len = coords.GetLength();
|
|
for(int i=0;i<index_count;i++)
|
|
{
|
|
Verify(index_array[i] < len);
|
|
}
|
|
#endif
|
|
|
|
index.AssignData(index_array, index_count);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::GetIndexData(
|
|
const BYTE **index_array,
|
|
int *index_count
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
|
|
*index_array = index.GetData();
|
|
*index_count = index.GetLength();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLRIndexedPrimitiveBase::Transform(Matrix4D *mat)
|
|
{
|
|
Check_Object(this);
|
|
|
|
int i, len = coords.GetLength();
|
|
|
|
for(i=0;i<len;i++)
|
|
{
|
|
(*transformedCoords)[i].Multiply(coords[i], *mat);
|
|
}
|
|
|
|
#ifdef LAB_ONLY
|
|
Set_Statistic(TransformedVertices, TransformedVertices+len);
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MLRIndexedPrimitiveBase::FogMesh(
|
|
const Stuff::LinearMatrix4D *worldToShape,
|
|
const Stuff::Point3D *cameraPos,
|
|
FogData *fogData
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
|
|
MLR_RENDER("Fog");
|
|
Start_Timer(Fog_Time);
|
|
|
|
int fogMode = state.GetFogMode();
|
|
if(fogMode == 0)
|
|
{
|
|
channelUse &= ~(1<<FogChannel);
|
|
Stop_Timer(Fog_Time);
|
|
return false;
|
|
}
|
|
fogMode--;
|
|
|
|
if(visibleIndexedVerticesKey == false)
|
|
{
|
|
FindVisibleVertices();
|
|
}
|
|
|
|
|
|
#if 1
|
|
fogData->cameraPos = *cameraPos;
|
|
fogData->near_fog = fogTable[fogMode][0];
|
|
fogData->far_fog = fogTable[fogMode][1];
|
|
fogData->one_over = fogTable[fogMode][3];
|
|
|
|
fogData->height_low_fog = fogTable[Limits::Max_Number_Of_FogStates-1][0];
|
|
fogData->height_top_fog = fogTable[Limits::Max_Number_Of_FogStates-1][1];
|
|
fogData->height_one_over = fogTable[Limits::Max_Number_Of_FogStates-1][3];
|
|
|
|
fogData->height_fog_density0 = 255.0f*fogTable[Limits::Max_Number_Of_FogStates-1][2];
|
|
fogData->height_fog_density = static_cast<BYTE>(0xff - fogData->height_fog_density0);
|
|
fogData->height_fog_density0 *= fogData->height_one_over;
|
|
|
|
Point3D org(0.0f, 0.0f, 0.0f);
|
|
fogData->orgInShape.Multiply(org, *worldToShape);
|
|
Vector3D up(0.0f, 1.0f, 0.0f);
|
|
fogData->upInShape.Multiply(up, *worldToShape);
|
|
#else
|
|
Vector3D v;
|
|
Point3D orgInShape, org(0.0f, 0.0f, 0.0f);
|
|
Vector3D upInShape, up(0.0f, 1.0f, 0.0f);
|
|
orgInShape.Multiply(org, *worldToShape);
|
|
upInShape.Multiply(up, *worldToShape);
|
|
|
|
int len = coords.GetLength();
|
|
Verify(len<extraChannels[2*FogChannel]->GetLength());
|
|
BYTE *data = extraChannels[2*FogChannel]->GetData();
|
|
Scalar n = fogTable[fogMode][0];
|
|
Scalar f = fogTable[fogMode][1];
|
|
Scalar o = fogTable[fogMode][3];
|
|
|
|
Scalar hn = fogTable[Limits::Max_Number_Of_FogStates-1][0];
|
|
Scalar hf = fogTable[Limits::Max_Number_Of_FogStates-1][1];
|
|
Scalar ho = fogTable[Limits::Max_Number_Of_FogStates-1][3];
|
|
|
|
Scalar hden0 = 255.0f*fogTable[Limits::Max_Number_Of_FogStates-1][2];
|
|
BYTE hden = static_cast<BYTE>(0xff - hden0);
|
|
hden0 *= ho;
|
|
|
|
for(int i=0;i<len;i++)
|
|
{
|
|
if((*visibleIndexedVertices)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
v.Subtract(coords[i], *cameraPos);
|
|
Scalar d = v.GetApproximateLength();
|
|
BYTE df = (BYTE)( (d<n+SMALL) ? 0xff : (d+SMALL>f) ? 0 : Truncate_Float_To_Byte(255.0f*(1.0f - (d-n)*o)) );
|
|
|
|
BYTE hhf;
|
|
if(hden < 0xff)
|
|
{
|
|
v.Subtract(coords[i], orgInShape);
|
|
Scalar h = v*upInShape;
|
|
hhf = (BYTE)( (h<hn+SMALL) ? hden : (h+SMALL>hf) ? 0xff : Truncate_Float_To_Byte(hden + hden0*(h-hn)) );
|
|
data[i] = df < hhf ? df : hhf;
|
|
}
|
|
else
|
|
{
|
|
data[i] = df;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
channelUse |= 1<<FogChannel;
|
|
|
|
Stop_Timer(Fog_Time);
|
|
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MLRIndexedPrimitiveBase::CheckIndicies()
|
|
{
|
|
for(int i=0;i<numGOSIndices;i++)
|
|
{
|
|
if(gos_indices[i] >= numGOSVertices)
|
|
{
|
|
STOP(("Invalid indicies detected !"));
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|