thug/Code/Gfx/NGPS/NX/instance.cpp

278 lines
5.6 KiB
C++
Raw Permalink Normal View History

2016-02-13 21:39:12 +00:00
#include "instance.h"
#include "scene.h"
#include "dma.h"
#include "mesh.h"
#include <core/math.h>
namespace NxPs2
{
CInstance::CInstance(sScene *pScene, Mth::Matrix transform, bool color_per_material)
{
SetTransform(transform);
mp_bone_transforms = NULL;
m_num_bones = 0;
m_flags = INSTANCEFLAG_ACTIVE;
mp_next = pScene->pInstances;
pScene->pInstances = this;
m_lastFrame = 0;
m_field = 0;
mp_scene = pScene;
mp_light_group = NULL;
if (color_per_material)
{
m_flags |= INSTANCEFLAG_COLORPERMATERIAL;
mp_color_array = new uint32[mp_scene->NumMeshes];
for (int i = 0; i < mp_scene->NumMeshes; i++)
{
mp_color_array[i] = 0x80808080;
}
}
else
{
m_colour = 0x80808080;
}
}
CInstance::CInstance(sScene *pScene, Mth::Matrix transform, bool color_per_material, int numBones, Mth::Matrix *pBoneTransforms)
{
SetTransform(transform);
mp_bone_transforms = pBoneTransforms;
m_num_bones = numBones;
m_flags = INSTANCEFLAG_ACTIVE;
mp_next = pScene->pInstances;
pScene->pInstances = this;
m_lastFrame = 0;
m_field = 0;
mp_scene = pScene;
mp_light_group = NULL;
if (color_per_material)
{
m_flags |= INSTANCEFLAG_COLORPERMATERIAL;
mp_color_array = new uint32[mp_scene->NumMeshes];
for (int i = 0; i < mp_scene->NumMeshes; i++)
{
mp_color_array[i] = 0x80808080;
}
}
else
{
m_colour = 0x80808080;
}
}
CInstance::~CInstance()
{
if (HasColorPerMaterial())
{
delete [] mp_color_array;
}
// remove from list structure...
// head of instance list
if (mp_scene->pInstances == this)
{
mp_scene->pInstances = mp_next;
}
// body of instance list
else
{
CInstance *pInstance;
for (pInstance=mp_scene->pInstances; pInstance; pInstance=pInstance->mp_next)
if (pInstance->mp_next == this)
break;
Dbg_MsgAssert(pInstance, ("couldn't locate CInstance for deletion"));
pInstance->mp_next = mp_next;
}
}
void CInstance::SetActive(bool Active)
{
if (Active)
{
m_flags |= INSTANCEFLAG_ACTIVE;
}
else
{
m_flags &= ~INSTANCEFLAG_ACTIVE;
}
}
void CInstance::EnableShadow(bool Enabled)
{
if (Enabled)
{
m_flags |= INSTANCEFLAG_CASTSSHADOW;
}
else
{
m_flags &= ~INSTANCEFLAG_CASTSSHADOW;
}
}
void CInstance::SetWireframe(bool Wireframe)
{
if (Wireframe)
{
m_flags |= INSTANCEFLAG_WIREFRAME;
}
else
{
m_flags &= ~INSTANCEFLAG_WIREFRAME;
}
}
Mth::Matrix* CInstance::GetBoneTransforms(void)
{
return m_field ? mp_bone_transforms : ( mp_bone_transforms + m_num_bones );
}
void CInstance::SetBoneTransforms(Mth::Matrix* pMat)
{
// GJ: toggle field, but only the first time
// (otherwise, the double-buffer gets messed
// up if SetBoneTransforms() is called more
// than once per frame...)
uint8 thisFrame = ( render::Frame & 0xff );
if ( m_lastFrame != thisFrame )
{
m_field = !m_field;
m_lastFrame = thisFrame;
}
int startIndex = m_field ? 0 : m_num_bones;
Mth::Matrix* pSrc = pMat;
Mth::Matrix* pDst = mp_bone_transforms + startIndex;
// copy the given matrices into the correct half of the matrix double-buffer
for ( int i = 0; i < m_num_bones; i++ )
{
*pDst++ = *pSrc++;
}
}
void CInstance::SetColor(uint32 rgba)
{
Dbg_Assert(!HasColorPerMaterial());
m_colour = rgba;
}
uint32 CInstance::GetColor()
{
Dbg_Assert(!HasColorPerMaterial());
return m_colour;
}
void CInstance::SetMaterialColor(uint32 material_name, int pass, uint32 rgba)
{
Dbg_Assert(HasColorPerMaterial());
int i;
sMesh *pMesh;
// Array is in mesh order
for (pMesh = mp_scene->pMeshes, i = 0; i < mp_scene->NumMeshes; pMesh++, i++)
{
if ((pMesh->MaterialName==material_name) && (pMesh->Pass == pass))
{
mp_color_array[i] = rgba;
}
}
}
void CInstance::SetMaterialColorByIndex(int mesh_idx, uint32 rgba)
{
Dbg_Assert(HasColorPerMaterial());
Dbg_MsgAssert(mesh_idx < mp_scene->NumMeshes, ("Mesh index %d is out of range", mesh_idx));
mp_color_array[mesh_idx] = rgba;
}
uint32 CInstance::GetMaterialColor(uint32 material_name, int pass)
{
Dbg_Assert(HasColorPerMaterial());
int i;
sMesh *pMesh;
// Array is in mesh order
for (pMesh = mp_scene->pMeshes, i = 0; i < mp_scene->NumMeshes; pMesh++, i++)
{
if ((pMesh->MaterialName==material_name) && (pMesh->Pass == pass))
{
return mp_color_array[i];
}
}
return 0x80808080;
}
uint32 CInstance::GetMaterialColorByIndex(int mesh_idx)
{
Dbg_Assert(HasColorPerMaterial());
return mp_color_array[mesh_idx];
}
Mth::Vector CInstance::GetBoundingSphere()
{
if (m_flags & INSTANCEFLAG_EXPLICITSPHERE)
{
return m_bounding_sphere;
}
else
{
Mth::Vector sphere(mp_scene->Sphere);
sphere[3] += 24.0f;
return sphere;
}
}
void CInstance::SetBoundingSphere(float x, float y, float z, float r)
{
//printf( "Stub: SetBoundingSphere %f %f %f %f\n", x, y, z, r );
m_bounding_sphere.Set(x,y,z,r);
m_flags |= INSTANCEFLAG_EXPLICITSPHERE;
}
void CInstance::SqueezeADC()
{
int i, num_meshes = mp_scene->NumMeshes;
sMesh *p_mesh = mp_scene->pMeshes;
for (i=0; i<num_meshes; i++,p_mesh++)
{
dma::SqueezeADC(p_mesh->pSubroutine);
dma::SqueezeNOP(p_mesh->pSubroutine);
}
}
// uv manipulation for skins
void CInstance::SetUVOffset(uint32 material_name, int pass, float u_offset, float v_offset)
{
mp_scene->SetUVOffset(material_name, pass, u_offset, v_offset);
}
void CInstance::SetUVMatrix(uint32 material_name, int pass, const Mth::Matrix &mat)
{
mp_scene->SetUVMatrix(material_name, pass, mat);
}
} // namespace NxPs2