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

166 lines
4.7 KiB
C++

#include "ElementProxyHeaders.hpp"
#include <Proxies\MakeSingleSided.hpp>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementPolygonMeshProxy::MakeSingleSided(MakeSingleSidedProcess *process)
{
Check_Object(this);
Check_Object(process);
//
//--------------------------
// Make sure we can continue
//--------------------------
//
process->MirrorCallback(this);
if (!process->continueProcess)
return true;
//
//------------------------------------------------------
// Make sure that we only have a single mesh to evaluate
//------------------------------------------------------
//
unsigned unique_combinations = GetPrimitiveCount();
if (!unique_combinations)
{
Destroy();
return false;
}
Verify(unique_combinations == 1);
//
//-----------------------------------------
// If backface rejection is on, we are done
//-----------------------------------------
//
MLR_I_PMesh *primitive = GetPrimitive(0);
Check_Object(primitive);
MLRState state = primitive->GetReferenceState();
// If back face culling is off, no need to duplicate
if (state.GetBackFaceMode() == MLRState::BackFaceOffMode) {
state.SetMatTwoSidedOff();
return true;
}
// If material is single sided, no need to duplicate either
if (state.GetMatTwoSidedMode() == MLRState::MatTwoSidedOffMode &&
state.GetProcessDeltaMask()&MLRState::MatTwoSidedMask != 0) {
state.SetMatTwoSidedOff();
return true;
}
state.SetMatTwoSidedOff();
//----------------------------------------------------------------
// Backface rejection is on, but material is two-sided,
// so we need to duplicate the polygons
//----------------------------------------------------------------
//
state.SetBackFaceOn();
primitive->SetReferenceState(state);
//
//-------------------------------------------
// Create a new polymesh and set its position
//-------------------------------------------
//
GroupProxy *parent = GetParentGroupProxy();
LinearMatrix4D m;
GetLocalToParent(&m);
PolygonMeshProxy *mesh;
if (parent)
{
Check_Object(parent);
mesh = parent->AppendNewPolygonMeshProxy();
}
else
mesh = GetSceneProxy()->AppendNewPolygonMeshProxy();
LinearMatrix4D matrix;
if (mesh->GetLocalToParent(&matrix))
SetLocalToParent(matrix);
//
//---------------------------------------------------------------------
// Get the polygons of the original mesh and copy them into the new one
// after mirroring
//---------------------------------------------------------------------
//
DynamicArrayOf<PolygonProxy*> poly_array;
int polycount = UsePolygonArray(&poly_array);
DynamicArrayOf<PolygonProxy*> newpoly_array(polycount);
for (int i=0;i<polycount;i++)
{
PolygonProxy *polygon = poly_array[i];
Check_Object(polygon);
//
//---------------
// Copy the state
//---------------
//
MultiState multi_state;
polygon->UseMultiState(&multi_state);
PolygonProxy *new_polygon = Proxies::PolygonProxy::MakeProxy();
Check_Object(new_polygon);
new_polygon->SetStatesToMatch(multi_state);
multi_state.DetachReferences();
//
//------------------
// Copy the vertices
//------------------
//
DynamicArrayOf<IndexProxy*> index_array;
int indexcount = polygon->UseIndexArray(&index_array);
DynamicArrayOf<IndexProxy*> newindex_array(indexcount);
DynamicArrayOf<VertexProxy*> newvertex_array(indexcount);
for (int k=0;k<indexcount;k++)
{
Proxies::VertexProxy *old_vertex = index_array[indexcount-1-k]->GetVertexProxy();
Check_Object(old_vertex);
Proxies::VertexProxy *new_vertex = Proxies::VertexProxy::MakeProxy();
Check_Object(new_vertex);
newvertex_array[k] = new_vertex;
Stuff::Point3D pos;
Stuff::RGBAColor color;
Stuff::Normal3D normal;
Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > uvs;
old_vertex->GetPosition(&pos);
new_vertex->SetPosition(pos);
if (old_vertex->GetColor(&color))
new_vertex->SetColor(color);
if (old_vertex->GetNormal(&normal))
{
new_vertex->SetNormal(normal.Negate(normal));
}
if (old_vertex->GetUVs(&uvs))
new_vertex->SetUVs(uvs);
newindex_array[k] = Proxies::IndexProxy::MakeProxy(new_polygon,new_vertex);
}
new_polygon->SetPolygonIndices(newvertex_array);
newpoly_array[i] = new_polygon;
new_polygon->DetachArrayReferences(&newindex_array);
polygon->DetachArrayReferences(&index_array);
}
Proxies::Process a_process;
mesh->AddPolygons(&a_process,newpoly_array);
mesh->DetachReference();
DetachArrayReferences(&newpoly_array);
DetachArrayReferences(&poly_array);
return true;
}