Files
firestorm/Gameleap/code/mw4/Libraries/mlr/MLRIndexedPrimitiveBase.cpp
T
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

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;
}