/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "core/geometry.h" #include "log/log.h" using namespace GS; using namespace GS::Core; //------------------------------------------------------------------------------ bool Geometry::ComputePolygonNormal(bool force) { if (!pol.GetCount() || !vtx.GetCount()) return false; if (!force && (pol_normal.GetCount() == pol.GetCount())) return true; if (!pol_normal.Allocate(pol.GetCount())) __ERR__(__LOG_E__ << "Geometry::ComputePolygonNormal() failed to allocate buffer.\n", false) for (uint c = 0; c < pol.GetCount(); ++c) if (pol[c].vtx_count > 2) { Vector4 va = vtx[pol[c].binding[2]] - vtx[pol[c].binding[0]], vb = vtx[pol[c].binding[1]] - vtx[pol[c].binding[0]]; pol_normal[c] = vb.Cross(va).Normalized(); } else pol_normal[c].Set(); return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool Geometry::ComputeVertexNormal(Array &buffer, float msa) { if (!pol.GetCount() || !vtx.GetCount()) return false; if (!ComputePolygonNormal()) return false; Array vtx_to_pol; ComputeVertexToPolygon(vtx_to_pol); // Allocate full blown edge normal array. __LOG__ << "Compute vertex normal for " << name << ".\n"; if (!binding.GetCount()) __ERR__(__LOG_E__ << "The total binding count is wrong. Check that the importer did properly update this flag.\n", false) if (!vtx_normal.Allocate(binding.GetCount())) __ERR__(__LOG_E__ << "Failed to allocate vertex normal buffer.\n", false) for (uint cp = 0, ttp = 0; cp < pol.GetCount(); cp++) for (uint cv = 0; cv < pol[cp].vtx_count; cv++) { uint gv = pol[cp].binding[cv]; Vector4 normal(0, 0, 0); for (uint cg = 0; cg < vtx_to_pol[gv].pol_count; cg++) if (pol_normal[cp].Dot(pol_normal[vtx_to_pol[gv].pol_index[cg]]) > msa) // MSA test. normal += pol_normal[vtx_to_pol[gv].pol_index[cg]]; vtx_normal[ttp++] = normal.Normalized(); } return true; } bool Geometry::ComputeVertexNormal(float msa, bool force) { if (!force && (vtx_normal.GetCount() == binding.GetCount())) return true; return ComputeVertexNormal(vtx_normal, msa); } //------------------------------------------------------------------------------