commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

View File

@ -0,0 +1,449 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "core/geometry.h"
#include "math/matrix4.h"
#include "log/log.h"
using namespace GS;
using namespace GS::Core;
static const float HomogeneousDistance = Units::Mm(0.01f);
//------------------------------------------------------------------------------
bool Core::ComputeVertexArrayMinMax(const Array <Vector4> &vtx, MinMax &mm, const Matrix4 *mtx)
{
if (!vtx.GetCount())
return false;
Vector4 tvt = mtx ? vtx[0] * mtx[0] : vtx[0], mn = tvt, mx = tvt;
if (mtx)
for (uint n = 0; n < vtx.GetCount(); ++n)
{
tvt = vtx[n] * mtx[0];
if (tvt.x > mx.x) mx.x = tvt.x;
if (tvt.y > mx.y) mx.y = tvt.y;
if (tvt.z > mx.z) mx.z = tvt.z;
if (tvt.x < mn.x) mn.x = tvt.x;
if (tvt.y < mn.y) mn.y = tvt.y;
if (tvt.z < mn.z) mn.z = tvt.z;
}
else
for (uint n = 0; n < vtx.GetCount(); ++n)
{
tvt = vtx[n];
if (tvt.x > mx.x) mx.x = tvt.x;
if (tvt.y > mx.y) mx.y = tvt.y;
if (tvt.z > mx.z) mx.z = tvt.z;
if (tvt.x < mn.x) mn.x = tvt.x;
if (tvt.y < mn.y) mn.y = tvt.y;
if (tvt.z < mn.z) mn.z = tvt.z;
}
mm.mn = mn;
mm.mx = mx;
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
uint Geometry::GetUVCount() const
{
uint c = 0;
for (uint n = 0; n < __UV_PER_GEOMETRY__; ++n)
if (uv[n])
++c;
return c;
}
uint Geometry::GetBoneCount() const
{ return bone_name.GetCount(); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Geometry::ComputeBoneBoundingVolumes(Array <MinMax> &bone_mm) const
{
uint bone_count = bone_bind_matrix.GetCount();
if (skin.IsNull() || !bone_count)
return false;
if (!bone_mm.Allocate(bone_count))
__ERR__(__LOG_E__ << "Failed to allocate bon minmax array.\n", false)
Array <bool> bone_mm_init(bone_count);
for (uint n = 0; n < bone_count; ++n)
bone_mm_init[n] = false;
for (uint v = 0; v < vtx.GetCount(); ++v)
for (int b = 0; b < __PV_BONE_LIMIT__; ++b)
if (skin[v].w[b] > 0.f)
{
int idx = skin[v].bone_index[b];
if (!bone_mm_init[idx])
{
bone_mm[idx].Set(vtx[v], vtx[v]);
bone_mm_init[idx] = true;
}
else
bone_mm[idx].Grow(vtx[v]);
}
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
uint Geometry::ComputePolygonBindingCount() const
{
uint c = 0;
for (uint n = 0; n < pol.GetCount(); ++n)
c += pol[n].vtx_count;
return c;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
MinMax Geometry::ComputeMinMax(const Matrix4 *mtx) const
{
MinMax mm;
ComputeVertexArrayMinMax(vtx, mm, mtx);
return mm;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Geometry::AllocateVertex(uint count)
{ return vtx.Allocate(count); }
bool Geometry::AllocatePolygon(uint count)
{
binding.Free();
return pol.Allocate(count);
}
bool Geometry::AllocatePolygonBinding()
{
uint count = ComputePolygonBindingCount();
if (!binding.Allocate(count))
return false;
count = 0;
for (uint n = 0; n < pol.GetCount(); ++n)
{
pol[n].binding = &binding[count];
count += pol[n].vtx_count;
}
return true;
}
bool Geometry::AllocateBone(uint count)
{ return bone_name.Allocate(count) && bone_bind_matrix.Allocate(count); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Geometry::ComputePolygonIndex(Array <uint> &i) const
{
if (i.Allocate(pol.GetCount()))
for (uint pc = 0, ci = 0; pc < pol.GetCount(); ++pc)
{
i[pc] = ci;
ci += pol[pc].vtx_count;
}
}
void Geometry::ComputeVertexToPolygon(Array <VertexToPolygon> &vtx_to_pol) const
{
if (!pol || !vtx)
return;
Array <uint> pol_per_vtx(vtx.GetCount());
if (!pol_per_vtx)
return;
Memory::Set(&pol_per_vtx[0], 0, pol_per_vtx.GetSize());
uint p, v;
for (p = 0; p < pol.GetCount(); ++p)
for (v = 0; v < pol[p].vtx_count; ++v)
pol_per_vtx[pol[p].binding[v]]++;
vtx_to_pol.Allocate(vtx.GetCount());
for (v = 0; v < vtx.GetCount(); ++v)
{
vtx_to_pol[v].pol_count = 0;
vtx_to_pol[v].pol_index.Allocate(pol_per_vtx[v]);
}
for (p = 0; p < pol.GetCount(); ++p)
for (v = 0; v < pol[p].vtx_count; ++v)
vtx_to_pol[pol[p].binding[v]].pol_index[vtx_to_pol[pol[p].binding[v]].pol_count++] = p;
}
void Geometry::ComputeVertexToVertex(Array <VertexToVertex> &vtx_to_vtx, const Array <VertexToPolygon> *vtx_to_pol) const
{
if (!pol || !vtx)
return;
// Allocate vertex to vertex buffer.
if (!vtx_to_vtx.Allocate(vtx.GetCount()))
__ERRRAW__(__LOG_E__ << "Could not allocate memory.\n")
// Allocate work area.
#define __VertexToVertexTempListSize 1024
PolygonVertex tmp_vtx_to_vtx[__VertexToVertexTempListSize];
// Compute vertex to polygon if not provided.
Array <VertexToPolygon> _vtx_to_pol;
if (!vtx_to_pol)
{
vtx_to_pol = &_vtx_to_pol;
ComputeVertexToPolygon(_vtx_to_pol);
}
for (int pass = 0; pass < 2; ++pass)
for (uint v = 0; v < vtx.GetCount(); ++v)
{
vtx_to_vtx[v].vtx_count = 0;
uint vtx_vtx_count = 0;
for (uint p = 0; p < (*vtx_to_pol)[v].pol_count; ++p)
{
uint pol_index = (*vtx_to_pol)[v].pol_index[p];
Polygon *poly = &pol[pol_index];
int ci;
for (ci = 0; ci < poly->vtx_count; ++ci)
if (poly->binding[ci] == v)
break;
for (int _c = (ci - 1); _c <= (ci + 1); _c += 2)
{
int vtx_index = _c;
if (vtx_index < 0)
vtx_index += poly->vtx_count;
if (vtx_index >= poly->vtx_count)
vtx_index -= poly->vtx_count;
// Invalidate already registered candidate.
bool insert = true;
for (uint nl = 0; nl < vtx_vtx_count; ++nl)
if ((tmp_vtx_to_vtx[nl].pol_index == pol_index) && (tmp_vtx_to_vtx[nl].vtx_index == (uint)vtx_index))
{
insert = false;
break;
}
if (insert)
{
tmp_vtx_to_vtx[vtx_vtx_count].pol_index = pol_index;
tmp_vtx_to_vtx[vtx_vtx_count].vtx_index = vtx_index;
if (vtx_vtx_count == __VertexToVertexTempListSize)
{
__LOG_E__ << "Temporary list exceeded, vertex to vertex LUT corrupted.\n";
vtx_vtx_count = __VertexToVertexTempListSize - 1;
}
if (pass == 1)
{
vtx_to_vtx[v].vtx[vtx_vtx_count].pol_index = pol_index;
vtx_to_vtx[v].vtx[vtx_vtx_count].vtx_index = vtx_index;
}
++vtx_vtx_count;
}
}
}
// Allocate vertex container for this vertex.
if (pass == 0)
vtx_to_vtx[v].vtx.Allocate(vtx_vtx_count);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Geometry::FlagHomogeneousVertex(Array <bool> &flag, const Array <uint> &pol_index, const Array <VertexToPolygon> &vtx_to_pol, int mat) const
{
if (!flag.Allocate(vtx.GetCount()))
__ERRRAW__(__LOG_E__ << "Could not allocate homogeneous vertex table.\n")
for (uint n = 0; n < vtx.GetCount(); ++n)
flag[n] = true;
#if 0
// Test for early exit in case no polygon uses this material.
for (uint n = 0; n < pol.GetCount(); n++)
if (pol[n].material == n)
break;
if (n == pol.GetCount())
return;
#endif
for (uint m = 0; m < vtx.GetCount(); ++m)
{
uint ngeo = vtx_to_pol[m].pol_count;
for (uint ac = 0; ac < ngeo; ++ac)
for (uint bc = 0; bc < ngeo; ++bc)
{
uint i_ac = vtx_to_pol[m].pol_index[ac],
i_bc = vtx_to_pol[m].pol_index[bc];
Polygon *apoly = &pol[i_ac], *bpoly = &pol[i_bc];
if (apoly == bpoly)
continue;
if (apoly->material == bpoly->material)
{
if ((mat == -1) || (apoly->material == (uint)mat))
{
uint _u, _v;
for (_u = 0; _u < apoly->vtx_count; ++_u)
if ( apoly->binding[_u] == m )
break;
for (_v = 0; _v < bpoly->vtx_count; ++_v)
if ( bpoly->binding[_v] == m )
break;
if (vtx_normal)
if (Vector4::Dist2(vtx_normal[pol_index[i_ac] + _u], vtx_normal[pol_index[i_bc] + _v]) > HomogeneousDistance)
flag[m] = false;
/*
if (vtx_tangent)
if (
(nVector::Dist2(vtx_tangent[pol_index[i_ac] + _u].B, vtx_tangent[pol_index[i_bc] + _v].B) > HomogeneousDistance) ||
(nVector::Dist2(vtx_tangent[pol_index[i_ac] + _u].T, vtx_tangent[pol_index[i_bc] + _v].T) > HomogeneousDistance)
)
vtx_homogeneous[m] = false;
*/
if (rgb)
if (Vector4::Dist2(rgb[pol_index[i_ac] + _u], rgb[pol_index[i_bc] + _v]) > HomogeneousDistance)
flag[m] = false;
for (uint cuv = 0; cuv < __UV_PER_GEOMETRY__; ++cuv)
if (uv[cuv])
if (Vector2::Dist2(uv[cuv][pol_index[i_ac] + _u], uv[cuv][pol_index[i_bc] + _v]) > HomogeneousDistance)
flag[m] = false;
}
}
else
flag[m] = false;
if (!flag[m])
goto nxth;
}
nxth:;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
uint Geometry::MergeDuplicateMaterials()
{
if (material_table.GetCount() < 2)
return 0;
__LOG_H__ << "Merging materials in geometry '" << name << "'...\n";
// Build the drop table.
uint old_slot_count = material_table.GetCount();
Array <bool> drop(material_table.GetCount());
for (uint n = 0; n < material_table.GetCount(); ++n)
drop[n] = false;
Array <uint> material_remap(material_table.GetCount());
for (uint n = 0; n < material_table.GetCount(); ++n)
material_remap[n] = n;
// Flag materials to drop.
for (uint n = 0; n < material_table.GetCount(); ++n)
{
if (drop[n]) // Already dropped.
continue;
for (uint m = n + 1; m < material_table.GetCount(); ++m)
{
// Check by material name.
if (material_table[n].name != material_table[m].name)
goto skip_material_drop;
// Drop material.
drop[m] = true;
material_remap[m] = n;
skip_material_drop:;
}
}
// Create the new material array.
uint new_material_slot_count = 0;
for (uint n = 0; n < material_table.GetCount(); ++n)
if (!drop[n])
new_material_slot_count++;
Array <Geometry::MaterialSlot> new_material_slot(new_material_slot_count);
new_material_slot_count = 0;
for (uint n = 0; n < material_table.GetCount(); ++n)
if (!drop[n])
{
for (uint m = 0; m < material_table.GetCount(); ++m)
if (material_remap[m] == n)
material_remap[m] = new_material_slot_count;
new_material_slot[new_material_slot_count].name = material_table[n].name;
new_material_slot[new_material_slot_count].use_cache = material_table[n].use_cache;
++new_material_slot_count;
}
material_table.Transfer(new_material_slot);
// Remap polygon references.
for (uint n = 0; n < pol.GetCount(); ++n)
pol[n].material = (ushort)material_remap[pol[n].material];
uint merge_count = old_slot_count - material_table.GetCount();
__LOG__ << "Done, merged " << merge_count << " material slot(s).\n";
return merge_count;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Geometry::Free()
{
bone_name.Free();
skin.Free();
bone_bind_matrix.Free();
vtx.Free();
vtx_normal.Free();
vtx_tangent.Free();
pol_normal.Free();
pol_tangent.Free();
pol.Free();
binding.Free();
for (uint n = 0; n < __UV_PER_GEOMETRY__; n++)
uv[n].Free();
rgb.Free();
material_table.Free();
lod_proxy = NULL;
lod_distance = Units::Mtr(100.f);
shadow_proxy = NULL;
flag.Raise(FlagNullShadowProxy | FlagNullLodProxy, false);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Geometry::Geometry()
{
lod_distance = Units::Mtr(100.f);
}
Geometry::~Geometry()
{
Free();
}
//------------------------------------------------------------------------------