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

445 lines
11 KiB
C++

#include "ProxyHeaders.hpp"
struct AbstractVertex
{
Point3D position;
Normal3D normal;
Vector2DOf<Scalar> uv;
RGBAColor color;
};
//
//############################################################################
//######################### PolygonMeshProxy ###########################
//############################################################################
//
PolygonMeshProxy::ClassData*
PolygonMeshProxy::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
PolygonMeshProxyClassID,
"PolygonMeshProxy",
ChildProxy::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PolygonMeshProxy::PolygonMeshProxy(
ClassData *class_data,
SceneProxy *scene,
GroupProxy *parent
):
ChildProxy(class_data, scene, parent),
activePolygonProxies(NULL),
activeVertexProxies(NULL)
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PolygonMeshProxy::~PolygonMeshProxy()
{
Check_Object(this);
Verify(activePolygonProxies.IsEmpty());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::GetCentroid(Point3D *centroid)
{
Check_Object(this);
Check_Object(centroid);
//
//-------------------------------------------------------------------
// If we have no polygons, just return our local to world translation
//-------------------------------------------------------------------
//
DynamicArrayOf<PolygonProxy*> polygons;
unsigned polygon_count = UsePolygonArray(&polygons);
Verify(polygon_count == polygons.GetLength());
if (!polygon_count)
{
*centroid = Point3D::Identity;
return;
}
//
//---------------------------------------------
// Sum up all the polygon centroids and weights
//---------------------------------------------
//
*centroid = Point3D::Identity;
for (unsigned i=0; i<polygon_count; ++i)
{
PolygonProxy *polygon = polygons[i];
Check_Object(polygon);
Point3D center;
Scalar area = polygon->GetSurfaceAreaAndCentroid(&center);
if (area > SMALL)
center /= area;
*centroid += center;
}
*centroid /= static_cast<Scalar>(polygon_count);
DetachArrayReferences(&polygons);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::Recenter()
{
Check_Object(this);
//
//-------------------------------------------------------------------------
// Now, get our centroid in our mesh space, and recenter the mesh around it
// in model space
//-------------------------------------------------------------------------
//
Point3D centroid;
GetCentroid(&centroid);
if (centroid != Point3D::Identity)
{
LinearMatrix4D matrix;
GetLocalToParent(&matrix);
LinearMatrix4D shift(true);
shift.BuildTranslation(centroid);
LinearMatrix4D new_origin;
new_origin.Multiply(shift, matrix);
SetLocalToParent(new_origin);
//
//-----------------------------------------------------------
// Now we have to subtract the centroid from all our vertices
//-----------------------------------------------------------
//
DynamicArrayOf<VertexProxy*> vertices;
unsigned vertex_count = UseVertexArray(&vertices);
for (unsigned i=0; i<vertex_count; ++i)
{
VertexProxy *vertex = vertices[i];
Check_Object(vertex);
Point3D position;
vertex->GetPosition(&position);
position -= centroid;
vertex->SetPosition(position);
}
DetachArrayReferences(&vertices);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
unsigned
PolygonMeshProxy::UseMultiStateArray(
DynamicArrayOf<MultiState*> *states,
DynamicArrayOf<unsigned> *index,
DynamicArrayOf<unsigned> *count,
DynamicArrayOf<PolygonProxy*> &polygons
)
{
Check_Object(this);
Check_Object(index);
Check_Object(count);
Check_Object(states);
//
//----------------------------------------------------------------------
// We have to evaluate each polygon within the mesh to see how many have
// unique states, so set up arrays to hold proxies and matching indices
//----------------------------------------------------------------------
//
unsigned polygon_count = polygons.GetLength();
//
//-------------------------------------------------------
// Spin through the polygons, check for max. nr of states
//-------------------------------------------------------
//
unsigned poly;
states->SetLength(polygon_count);
index->SetLength(polygon_count);
count->SetLength(polygon_count);
unsigned i, j;
for (i=0; i<polygon_count; ++i)
(*count)[i] = 0;
unsigned unique_combinations = 0;
//
//------------------------------------------------------
// Spin through the polygons, looking for unique entries
//------------------------------------------------------
//
for (poly=0; poly < polygon_count; ++poly)
{
PolygonProxy *polygon = polygons[poly];
Check_Object(polygon);
MultiState poly_states;
polygon->UseMultiState(&poly_states);
//
//-------------------------------------------------------------------
// Get the state proxies, and see if they index one of
// the prior entries
//-------------------------------------------------------------------
//
for (i=0; i<unique_combinations;++i)
{
//
//--------------------------------------------------------------
// Make sure that the state combo has the same length
//--------------------------------------------------------------
//
unsigned state_count = (*states)[i]->GetLength();
if( poly_states.GetLength() != state_count)
{
continue;
}
//
//--------------------------------------------------------------
// Make sure that the state and texture exists in either both
// proxies or neither proxy
//--------------------------------------------------------------
//
for(j=0;j<state_count;++j)
{
if ((!poly_states[j] && (*(*states)[i])[j]) ||
(poly_states[j] && !(*(*states)[i])[j]))
{
break;
}
}
if(j<state_count)
{
continue;
}
//
//-----------------------------------------------
// Make sure that the state and textures index
//-----------------------------------------------
//
if(poly_states.IsEqualTo(*(*states)[i]))
{
break;
}
}
//
//-------------------------------------------------------------------
// If this is a new entry, bump the combo count and store the proxies
//-------------------------------------------------------------------
//
if (i == unique_combinations)
{
++unique_combinations;
(*states)[i] = new MultiState (poly_states);
// Verify((*states)[i]->GetLength() > 0);
}
//
//-------------------------
// Move to the next polygon
//-------------------------
//
(*index)[poly] = i;
++(*count)[i];
poly_states.DetachReferences();
}
//
//-------------------------------------
// Release the texture/state proxies
//-------------------------------------
//
states->SetLength(unique_combinations);
count->SetLength(unique_combinations);
return unique_combinations;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
PolygonMeshProxy::GetBoundingSphere(Sphere *sphere)
{
Check_Object(this);
Check_Pointer(sphere);
//
//---------------------------------------------------------------------
// Put the center of the sphere at the centroid, then set the radius to
// just contain the mesh
//---------------------------------------------------------------------
//
DynamicArrayOf<VertexProxy*> vertices;
unsigned vertex_count = UseVertexArray(&vertices);
Verify(vertex_count == vertices.GetLength());
#if 1
DynamicArrayOf<Point3D> points;
points.SetLength(vertex_count);
for (unsigned i=0; i<vertex_count; ++i)
{
VertexProxy *vertex = vertices[i];
Check_Object(vertex);
vertex->GetPosition(&points[i]);
}
DetachArrayReferences(&vertices);
sphere->ComputeBounds(points);
//
//-------------------------------------
// Make sure the radius is properly set
//-------------------------------------
//
if (sphere->radius == -1.0f)
{
sphere->radius = 0.0f;
return false;
}
return true;
#else
GetCentroid(&sphere->center);
sphere->radius = -1.0f;
for (unsigned i=0; i<vertex_count; ++i)
{
VertexProxy *vertex = vertices[i];
Check_Object(vertex);
Point3D position;
vertex->GetPosition(&position);
position -= sphere->center;
Scalar range = position.GetLengthSquared();
if (range > sphere->radius)
sphere->radius = range;
}
DetachArrayReferences(&vertices);
//
//-------------------------------------
// Make sure the radius is properly set
//-------------------------------------
//
if (sphere->radius == -1.0f)
{
sphere->radius = 0.0f;
return false;
}
sphere->radius = Sqrt(sphere->radius) + SMALL;
return true;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::DetachPolygonProxy(PolygonProxy* proxy)
{
Check_Object(this);
activePolygonProxies.RemovePlug(proxy);
Verify(referenceCount > 1);
DetachReference();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::DetachArrayReferences(
DynamicArrayOf<MultiState*> *states
)
{
Check_Object(states);
//
//------------------------------
// Add all the vertices together
//------------------------------
//
unsigned i, state_count = states->GetLength();
for (i=0; i<state_count; ++i)
{
Check_Object((*states)[i]);
(*states)[i]->DetachReferences();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::DetachArrayReferences(
DynamicArrayOf<PolygonProxy*> *polygons
)
{
Check_Object(polygons);
//
//------------------------------
// Add all the vertices together
//------------------------------
//
unsigned polygon_count = polygons->GetLength();
for (unsigned i=0; i<polygon_count; ++i)
{
Check_Object((*polygons)[i]);
(*polygons)[i]->DetachReference();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
PolygonMeshProxy::DetachArrayReferences(
DynamicArrayOf<VertexProxy*> *vertices
)
{
Check_Object(vertices);
//
//------------------------------
// Add all the vertices together
//------------------------------
//
unsigned vertex_count = vertices->GetLength();
for (unsigned i=0; i<vertex_count; ++i)
{
Check_Object((*vertices)[i]);
(*vertices)[i]->DetachReference();
}
}