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.
166 lines
4.7 KiB
C++
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;
|
|
}
|