commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
213
include/engine/core/object.cpp
Normal file
213
include/engine/core/object.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "core/object.h"
|
||||
#include "core/camera.h"
|
||||
#include "core/geometry.h"
|
||||
#include "core/resource_factories.h"
|
||||
#include "core/render_resource_factory.h"
|
||||
#include "timing/benchmark.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::Core;
|
||||
|
||||
float Object::lod_bias = 0.f;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Object::RenderSetup(ResourceFactories *f)
|
||||
{
|
||||
render_data = new RenderData;
|
||||
|
||||
if (f && f->render)
|
||||
{
|
||||
render_data->geometry = f->render->LoadGeometry(geometry, !cache_geometry);
|
||||
|
||||
if (render_data->geometry.IsValid())
|
||||
{
|
||||
// Assert skin correctness.
|
||||
uint bone_count = render_data->geometry->bone_bind_matrix.GetCount();
|
||||
|
||||
if (bone_count > 0)
|
||||
{
|
||||
if (skin.IsNull() || (skin->bones_mtx.GetCount() != bone_count))
|
||||
{
|
||||
AllocateSkin(render_data->geometry->bone_bind_matrix.GetCount());
|
||||
|
||||
// Initialize skin to the binding position.
|
||||
for (uint n = 0; n < render_data->geometry->bone_bind_matrix.GetCount(); ++n)
|
||||
skin->previous_bones_mtx[n] = skin->bones_mtx[n] = render_data->geometry->bone_bind_matrix[n];
|
||||
}
|
||||
}
|
||||
else
|
||||
FreeSkin();
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static float GetGeometrySortValue(const Matrix4 &vm, Render::Geometry *g, const Matrix4 &gm)
|
||||
{ return vm.GetRow(2).Dot((g->hotspot * gm) - vm.GetRow(3)); }
|
||||
|
||||
void Object::ComputeRenderableMinMax(MinMax &mm)
|
||||
{
|
||||
ComputeLocalMinMax(mm);
|
||||
OBB obb = OBB::FromMinMax(mm);
|
||||
obb.Transform(GetMatrix());
|
||||
obb.ComputeMinMax(mm);
|
||||
}
|
||||
uint Object::GetRenderablePrimitiveList(const Camera &view, const Camera &default_view, Stack <Render::Primitive *> &list, Renderable::Context context, bool cull)
|
||||
{
|
||||
Render::Geometry *g = render_data.IsValid() ? render_data->geometry.c_ptr() : NULL;
|
||||
if (!g)
|
||||
return 1;
|
||||
|
||||
// Recursive LOD selection.
|
||||
{
|
||||
float d2 = Vector4::Dist2(default_view.GetMatrix().GetRow(3), GetMatrix().GetRow(3)) + lod_bias * lod_bias;
|
||||
|
||||
d2 /= GetScale().Len2(); // [EJ] scale affects lod selection
|
||||
|
||||
for ( ; g; g = g->lod_proxy)
|
||||
{
|
||||
// If closer than lod, stop there.
|
||||
if (d2 < (g->lod_distance * g->lod_distance))
|
||||
break;
|
||||
|
||||
// Null lod.
|
||||
if (g->flag.IsSet(Geometry::FlagNullLodProxy))
|
||||
return 1;
|
||||
|
||||
// No lod to follow, stop there.
|
||||
if (g->lod_proxy.IsNull())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check context proxy on the selected lod.
|
||||
if (context == Renderable::Context_Shadow)
|
||||
{
|
||||
// Null proxy.
|
||||
if (g->flag.IsSet(Geometry::FlagNullShadowProxy))
|
||||
return 1;
|
||||
|
||||
if (g->shadow_proxy.IsValid())
|
||||
g = g->shadow_proxy;
|
||||
}
|
||||
|
||||
// Test geometry hidden flag.
|
||||
if (g->flag.IsSet(Geometry::FlagHidden))
|
||||
return 1;
|
||||
|
||||
// Culling.
|
||||
if (cull)
|
||||
{
|
||||
MinMax minmax;
|
||||
ComputeLocalMinMax(minmax);
|
||||
|
||||
if (view.frustum.ClassifyMinMax(minmax, &GetMatrix()) == Frustum::Outside)
|
||||
return 1;
|
||||
}
|
||||
|
||||
list.Push(new Render::Primitive(g, this, GetGeometrySortValue(view.GetMatrix(), g, GetMatrix())));
|
||||
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Object::GetBindMatrix(uint n, Matrix4 &m) const
|
||||
{
|
||||
if (render_data.IsNull() || render_data->geometry.IsNull())
|
||||
return false;
|
||||
if (n >= render_data->geometry->bone_bind_matrix.GetCount())
|
||||
return false;
|
||||
|
||||
m = render_data->geometry->bone_bind_matrix[n];
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Object::ComputeLocalMinMax(MinMax &minmax) const
|
||||
{
|
||||
if (render_data.IsNull() || render_data->geometry.IsNull())
|
||||
Item::ComputeLocalMinMax(minmax);
|
||||
|
||||
else
|
||||
{
|
||||
if (HasSkin())
|
||||
{
|
||||
// Compute skin minmax.
|
||||
OBB obb;
|
||||
for (uint n = 0; n < GetBoneCount(); ++n)
|
||||
if (skin->ComputeBoneBoundingVolume(n, obb))
|
||||
{
|
||||
MinMax bmm;
|
||||
obb.ComputeMinMax(bmm);
|
||||
if (n)
|
||||
minmax.Grow(bmm);
|
||||
else minmax = bmm;
|
||||
}
|
||||
}
|
||||
else
|
||||
minmax = render_data->geometry->minmax;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Object::UpdateSkin()
|
||||
{
|
||||
if (render_data.IsValid() && render_data->geometry.IsValid())
|
||||
for (uint n = 0; n < GetBoneCount(); ++n)
|
||||
if (Item *bone = GetBone(n))
|
||||
{
|
||||
skin->previous_bones_mtx[n] = GetInverseMatrix() * (bone->GetPreviousMatrix() * render_data->geometry->bone_bind_matrix[n]);
|
||||
skin->bones_mtx[n] = GetInverseMatrix() * (bone->GetMatrix() * render_data->geometry->bone_bind_matrix[n]);
|
||||
}
|
||||
else
|
||||
{
|
||||
skin->previous_bones_mtx[n] = Matrix4::IdentityMatrix();
|
||||
skin->bones_mtx[n] = Matrix4::IdentityMatrix();
|
||||
}
|
||||
}
|
||||
bool Object::BindBone(uint n, Item *bone)
|
||||
{
|
||||
if (skin.IsNull() || (n >= skin->bones.GetCount()))
|
||||
return false;
|
||||
|
||||
skin->bones[n] = bone;
|
||||
if (bone)
|
||||
bone->item_flags.Set(ItemFlagBoneHint);
|
||||
return true;
|
||||
}
|
||||
bool Object::AllocateSkin(uint bone_count)
|
||||
{
|
||||
skin = new Skin;
|
||||
|
||||
if (!skin->bones.Allocate(bone_count) || !skin->bones_mtx.Allocate(bone_count) || !skin->previous_bones_mtx.Allocate(bone_count) || !skin->bones_minmax.Allocate(bone_count))
|
||||
{
|
||||
FreeSkin();
|
||||
__ERR__(__LOG_E__ << "Failed to allocate skinning structure.\n", false);
|
||||
}
|
||||
for (uint n = 0; n < bone_count; ++n)
|
||||
{
|
||||
skin->bones[n] = NULL;
|
||||
skin->bones_mtx[n] = Matrix4::IdentityMatrix();
|
||||
skin->previous_bones_mtx[n] = Matrix4::IdentityMatrix();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void Object::FreeSkin()
|
||||
{
|
||||
skin = NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Object::Object() : cache_geometry(true) {}
|
||||
Reference in New Issue
Block a user