mirror of
https://github.com/thug1src/thug.git
synced 2025-01-22 05:43:47 +00:00
1471 lines
42 KiB
C++
1471 lines
42 KiB
C++
|
#include <sys/file/filesys.h>
|
||
|
#include <sys/timer.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "import.h"
|
||
|
#include "scene.h"
|
||
|
#include "mesh.h"
|
||
|
#include "nx_init.h"
|
||
|
#include "sys/ngc/p_aram.h"
|
||
|
#include "sys/ngc/p_dma.h"
|
||
|
#include <sk/modules/skate/skate.h>
|
||
|
|
||
|
#include <dolphin.h>
|
||
|
|
||
|
extern bool gCorrectColor;
|
||
|
|
||
|
namespace NxNgc
|
||
|
{
|
||
|
|
||
|
extern sint32 *pVertex;
|
||
|
int TotalNumVertices;
|
||
|
|
||
|
uint NumMeshes;
|
||
|
|
||
|
|
||
|
// Globals used for cutscene head scaling.
|
||
|
bool s_meshScalingEnabled = false;
|
||
|
char* s_pWeightIndices = NULL;
|
||
|
float* s_pWeights = NULL;
|
||
|
Mth::Vector* s_pBonePositions = NULL;
|
||
|
Mth::Vector* s_pBoneScales = NULL;
|
||
|
int s_currentVertIndex = 0;
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void SetMeshScalingParameters( Nx::SMeshScalingParameters* pParams )
|
||
|
{
|
||
|
Dbg_Assert( pParams );
|
||
|
|
||
|
s_meshScalingEnabled = true;
|
||
|
s_pWeights = pParams->pWeights;
|
||
|
s_pWeightIndices = pParams->pWeightIndices;
|
||
|
s_pBoneScales = pParams->pBoneScales;
|
||
|
s_pBonePositions = pParams->pBonePositions;
|
||
|
s_currentVertIndex = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void DisableMeshScaling( void )
|
||
|
{
|
||
|
s_meshScalingEnabled = false;
|
||
|
s_pWeights = NULL;
|
||
|
s_pWeightIndices = NULL;
|
||
|
s_pBoneScales = NULL;
|
||
|
s_pBonePositions = NULL;
|
||
|
s_currentVertIndex = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
static inline Mth::Vector get_bone_scale( int bone_index )
|
||
|
{
|
||
|
Mth::Vector returnVec( 1.0f, 1.0f, 1.0f, 1.0f );
|
||
|
|
||
|
if( bone_index >= 29 && bone_index <= 33 )
|
||
|
{
|
||
|
// this only works with the thps5 skeleton, whose
|
||
|
// head bones are between 29 and 33...
|
||
|
// (eventually, we can remove the subtract 29
|
||
|
// once the exporter is massaging the data correctly)
|
||
|
returnVec = s_pBoneScales[ bone_index - 29 ];
|
||
|
|
||
|
// Y & Z are reversed... odd!
|
||
|
Mth::Vector tempVec = returnVec;
|
||
|
returnVec[Y] = tempVec[Z];
|
||
|
returnVec[Z] = tempVec[Y];
|
||
|
}
|
||
|
else if( bone_index == -1 )
|
||
|
{
|
||
|
// implies that it's not weighted to a bone
|
||
|
return returnVec;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// implies that it's weighted to the wrong bone
|
||
|
return returnVec;
|
||
|
}
|
||
|
return returnVec;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
static inline Mth::Vector get_bone_pos( int bone_index )
|
||
|
{
|
||
|
Mth::Vector returnVec( 0.0f, 0.0f, 0.0f, 1.0f );
|
||
|
|
||
|
if( bone_index >= 29 && bone_index <= 33 )
|
||
|
{
|
||
|
// this only works with the thps5 skeleton, whose
|
||
|
// head bones are between 29 and 33...
|
||
|
// (eventually, we can remove the subtract 29
|
||
|
// once the exporter is massaging the data correctly)
|
||
|
returnVec = s_pBonePositions[ bone_index - 29 ];
|
||
|
}
|
||
|
else if( bone_index == -1 )
|
||
|
{
|
||
|
// implies that it's not weighted to a bone
|
||
|
return returnVec;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// implies that it's weighted to the wrong bone
|
||
|
return returnVec;
|
||
|
}
|
||
|
returnVec[W] = 1.0f;
|
||
|
|
||
|
return returnVec;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void ApplyMeshScaling( NxNgc::sObjectHeader * p_object )
|
||
|
{
|
||
|
if( s_meshScalingEnabled )
|
||
|
{
|
||
|
float orig_pool[3*1500];
|
||
|
int pool_size = 0;
|
||
|
|
||
|
// First, build an array from the skin data.
|
||
|
|
||
|
// Singles.
|
||
|
uint32* p32 = (uint32 *)p_object->m_skin.p_data;
|
||
|
for ( uint32 lp = 0; lp < p_object->m_num_single_lists; lp++ ) {
|
||
|
uint32 pairs = *p32++;
|
||
|
/*uint32 mtx = **/p32++;
|
||
|
s16* p_pn = (s16 *)p32;
|
||
|
|
||
|
for ( uint32 lp2 = 0; lp2 < pairs; lp2++ )
|
||
|
{
|
||
|
orig_pool[(pool_size*3)+0] = (float)p_pn[(lp2*6)+0] / (float)(1 << 6);
|
||
|
orig_pool[(pool_size*3)+1] = (float)p_pn[(lp2*6)+1] / (float)(1 << 6);
|
||
|
orig_pool[(pool_size*3)+2] = (float)p_pn[(lp2*6)+2] / (float)(1 << 6);
|
||
|
pool_size++;
|
||
|
}
|
||
|
|
||
|
p32 = (uint32 *)&p_pn[pairs*6];
|
||
|
}
|
||
|
|
||
|
// Doubles.
|
||
|
for ( uint32 lp = 0; lp < p_object->m_num_double_lists; lp++ ) {
|
||
|
uint32 pairs = *p32++;
|
||
|
/*uint32 mtx = **/p32++;
|
||
|
s16* p_pn = (s16 *)p32;
|
||
|
s16* p_weight = (s16 *)&p_pn[(6*pairs)];
|
||
|
|
||
|
for ( uint32 lp2 = 0; lp2 < pairs; lp2++ )
|
||
|
{
|
||
|
orig_pool[(pool_size*3)+0] = (float)p_pn[(lp2*6)+0] / (float)(1 << 6);
|
||
|
orig_pool[(pool_size*3)+1] = (float)p_pn[(lp2*6)+1] / (float)(1 << 6);
|
||
|
orig_pool[(pool_size*3)+2] = (float)p_pn[(lp2*6)+2] / (float)(1 << 6);
|
||
|
pool_size++;
|
||
|
}
|
||
|
|
||
|
p32 = (uint32 *)&p_weight[pairs*2];
|
||
|
}
|
||
|
|
||
|
// Now scale the verts.
|
||
|
float * p_vertices = orig_pool;
|
||
|
for( int v = 0; v < pool_size; ++v, p_vertices += 3 )
|
||
|
{
|
||
|
float x = p_vertices[0];
|
||
|
float y = p_vertices[1];
|
||
|
float z = p_vertices[2];
|
||
|
|
||
|
Mth::Vector origPos( x, y, z, 1.0f );
|
||
|
|
||
|
Mth::Vector bonePos0 = get_bone_pos( s_pWeightIndices[v * 3] );
|
||
|
Mth::Vector bonePos1 = get_bone_pos( s_pWeightIndices[v * 3 + 1] );
|
||
|
Mth::Vector bonePos2 = get_bone_pos( s_pWeightIndices[v * 3 + 2] );
|
||
|
|
||
|
// Need to scale each vert relative to its parent bone.
|
||
|
Mth::Vector localPos0 = origPos - bonePos0;
|
||
|
Mth::Vector localPos1 = origPos - bonePos1;
|
||
|
Mth::Vector localPos2 = origPos - bonePos2;
|
||
|
|
||
|
localPos0.Scale( get_bone_scale( s_pWeightIndices[v * 3] ) );
|
||
|
localPos1.Scale( get_bone_scale( s_pWeightIndices[v * 3 + 1] ) );
|
||
|
localPos2.Scale( get_bone_scale( s_pWeightIndices[v * 3 + 2] ) );
|
||
|
|
||
|
localPos0 += bonePos0;
|
||
|
localPos1 += bonePos1;
|
||
|
localPos2 += bonePos2;
|
||
|
|
||
|
Mth::Vector scaledPos = ( localPos0 * s_pWeights[v * 3] ) +
|
||
|
( localPos1 * s_pWeights[v * 3 + 1] ) +
|
||
|
( localPos2 * s_pWeights[v * 3 + 2] );
|
||
|
|
||
|
p_vertices[0] = scaledPos[X];
|
||
|
p_vertices[1] = scaledPos[Y];
|
||
|
p_vertices[2] = scaledPos[Z];
|
||
|
}
|
||
|
|
||
|
// Now copy back.
|
||
|
pool_size = 0;
|
||
|
|
||
|
// Singles.
|
||
|
p32 = (uint32 *)p_object->m_skin.p_data;
|
||
|
for ( uint32 lp = 0; lp < p_object->m_num_single_lists; lp++ ) {
|
||
|
uint32 pairs = *p32++;
|
||
|
/*uint32 mtx = **/p32++;
|
||
|
s16* p_pn = (s16 *)p32;
|
||
|
|
||
|
for ( uint32 lp2 = 0; lp2 < pairs; lp2++ )
|
||
|
{
|
||
|
p_pn[(lp2*6)+0] = (s16)(orig_pool[(pool_size*3)+0] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+1] = (s16)(orig_pool[(pool_size*3)+1] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+2] = (s16)(orig_pool[(pool_size*3)+2] * (float)(1 << 6 ));
|
||
|
pool_size++;
|
||
|
}
|
||
|
|
||
|
p32 = (uint32 *)&p_pn[pairs*6];
|
||
|
}
|
||
|
|
||
|
// Doubles.
|
||
|
for ( uint32 lp = 0; lp < p_object->m_num_double_lists; lp++ ) {
|
||
|
uint32 pairs = *p32++;
|
||
|
/*uint32 mtx = **/p32++;
|
||
|
s16* p_pn = (s16 *)p32;
|
||
|
s16* p_weight = (s16 *)&p_pn[(6*pairs)];
|
||
|
|
||
|
for ( uint32 lp2 = 0; lp2 < pairs; lp2++ )
|
||
|
{
|
||
|
p_pn[(lp2*6)+0] = (s16)(orig_pool[(pool_size*3)+0] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+1] = (s16)(orig_pool[(pool_size*3)+1] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+2] = (s16)(orig_pool[(pool_size*3)+2] * (float)(1 << 6 ));
|
||
|
pool_size++;
|
||
|
}
|
||
|
|
||
|
p32 = (uint32 *)&p_weight[pairs*2];
|
||
|
}
|
||
|
|
||
|
// Accumulation.
|
||
|
for ( uint32 lp = 0; lp < p_object->m_num_add_lists; lp++ ) {
|
||
|
uint32 singles = *p32++;
|
||
|
/*uint32 mtx = **/p32++;
|
||
|
s16* p_pn = (s16 *)p32;
|
||
|
s16* p_weight = (s16 *)&p_pn[(6*singles)];
|
||
|
uint16* p_index = (uint16 *)&p_weight[singles];
|
||
|
|
||
|
for ( uint32 lp2 = 0; lp2 < singles; lp2++ )
|
||
|
{
|
||
|
int index = p_index[lp2];
|
||
|
p_pn[(lp2*6)+0] = (s16)(orig_pool[(index*3)+0] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+1] = (s16)(orig_pool[(index*3)+1] * (float)(1 << 6 ));
|
||
|
p_pn[(lp2*6)+2] = (s16)(orig_pool[(index*3)+2] * (float)(1 << 6 ));
|
||
|
}
|
||
|
|
||
|
p32 = (uint32 *)&p_index[singles];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
sMesh::sMesh( void )
|
||
|
{
|
||
|
m_flags = 0;
|
||
|
SetActive( true );
|
||
|
// mp_vc_wibble_data = NULL;
|
||
|
//
|
||
|
// m_offset_x = 0.0f;
|
||
|
// m_offset_y = 0.0f;
|
||
|
// m_offset_z = 0.0f;
|
||
|
|
||
|
m_visibility_mask = 0xff;
|
||
|
|
||
|
mp_dl = NULL;
|
||
|
|
||
|
// It's the end of teh project - time for a hack!!!
|
||
|
Mdl::Skate * p_skate_mod = Mdl::Skate::Instance();
|
||
|
if (p_skate_mod->m_requested_level == CRCD(0x9f2bafb7,"load_skateshop"))
|
||
|
{
|
||
|
m_base_color.r = 64;
|
||
|
m_base_color.g = 64;
|
||
|
m_base_color.b = 64;
|
||
|
m_base_color.a = 128;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_base_color.r = 128;
|
||
|
m_base_color.g = 128;
|
||
|
m_base_color.b = 128;
|
||
|
m_base_color.a = 128;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
sMesh::~sMesh( void )
|
||
|
{
|
||
|
if( !( m_flags & MESH_FLAG_IS_INSTANCE ))
|
||
|
{
|
||
|
if( m_flags & MESH_FLAG_IS_CLONED )
|
||
|
{
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// if( mp_posBuffer )
|
||
|
// {
|
||
|
// delete [] mp_posBuffer;
|
||
|
// mp_posBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_normBuffer )
|
||
|
// {
|
||
|
// delete [] mp_normBuffer;
|
||
|
// mp_normBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_colBuffer )
|
||
|
// {
|
||
|
// delete [] mp_colBuffer;
|
||
|
// mp_colBuffer = NULL;
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// if ( mp_dl->mp_texture_dl )
|
||
|
// {
|
||
|
// delete [] mp_dl->mp_texture_dl;
|
||
|
// }
|
||
|
|
||
|
// if( mp_display_list )
|
||
|
// {
|
||
|
// delete mp_display_list;
|
||
|
// mp_display_list = NULL;
|
||
|
// }
|
||
|
|
||
|
// if ( mp_dl && mp_dl->dl_owner )
|
||
|
// {
|
||
|
// if ( mp_dl->mp_material_dl )
|
||
|
// delete [] mp_dl->mp_material_dl;
|
||
|
// }
|
||
|
|
||
|
// // If we're the 0th mesh, we can delete the shared pools.
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// if( mp_posBuffer )
|
||
|
// {
|
||
|
// delete [] mp_posBuffer;
|
||
|
// mp_posBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_normBuffer )
|
||
|
// {
|
||
|
// delete [] mp_normBuffer;
|
||
|
// mp_normBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_uvBuffer )
|
||
|
// {
|
||
|
// delete [] mp_uvBuffer;
|
||
|
// mp_uvBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_envBuffer )
|
||
|
// {
|
||
|
// delete [] mp_envBuffer;
|
||
|
// mp_envBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_colBuffer )
|
||
|
// {
|
||
|
// delete [] mp_colBuffer;
|
||
|
// mp_colBuffer = NULL;
|
||
|
// }
|
||
|
// if( mp_doubleWeight )
|
||
|
// {
|
||
|
// delete [] mp_doubleWeight;
|
||
|
// mp_doubleWeight = NULL;
|
||
|
// }
|
||
|
// if( mp_vc_wibble_data )
|
||
|
// {
|
||
|
// delete mp_vc_wibble_data;
|
||
|
// mp_vc_wibble_data = NULL;
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::wibble_normals( void )
|
||
|
{
|
||
|
// // Angle in the range [-PI/16, PI/16], period is 1 second.
|
||
|
// float time = (float)Tmr::GetTime() * 0.0005f;
|
||
|
//
|
||
|
// if( m_flags & MESH_FLAG_WATER_HACK )
|
||
|
// {
|
||
|
// BYTE *p_byte;
|
||
|
// float *p_normal;
|
||
|
// float *p_pos;
|
||
|
// mp_vertex_buffer2->Lock( 0, 0, &p_byte, 0 );
|
||
|
// p_pos = (float*)( p_byte + 0 );
|
||
|
// p_normal = (float*)( p_byte + m_normal_offset );
|
||
|
//
|
||
|
// for( uint32 i = 0; i < m_num_vertices; ++i )
|
||
|
// {
|
||
|
// float x = p_pos[0] - m_sphere[0];
|
||
|
// float z = p_pos[2] - m_sphere[2];
|
||
|
//
|
||
|
// float time_offset_x = time + (( x / m_sphere_radius ) * 0.5f );
|
||
|
// float time_offset_z = time + (( z / m_sphere_radius ) * 0.5f );
|
||
|
//
|
||
|
// float angle_x = ( Mth::PI * ( 1.0f / 64.0f ) * (float)fabs( sinf( time_offset_x * Mth::PI ))) - ( Mth::PI * ( 1.0f / 128.0f ));
|
||
|
// float angle_z = ( Mth::PI * ( 1.0f / 64.0f ) * (float)fabs( sinf( time_offset_z * Mth::PI ))) - ( Mth::PI * ( 1.0f / 129.0f ));
|
||
|
//
|
||
|
// Mth::Vector n( sinf( angle_x ), cosf(( angle_x + angle_z ) * 0.5f ), sinf( angle_z ));
|
||
|
// n.Normalize();
|
||
|
//
|
||
|
// p_normal[0] = n[X];
|
||
|
// p_normal[1] = n[Y];
|
||
|
// p_normal[2] = n[Z];
|
||
|
//
|
||
|
// p_pos = (float*)((BYTE*)p_pos + m_vertex_stride );
|
||
|
// p_normal = (float*)((BYTE*)p_normal + m_vertex_stride );
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::wibble_vc( void )
|
||
|
{
|
||
|
// if( mp_vc_wibble_data )
|
||
|
// {
|
||
|
// // Grab byte pointer to current 'write' vertex buffer.
|
||
|
//// GXColor *p_byte = (char *)mp_colBuffer;
|
||
|
// uint32 *p_color = mp_colBuffer;
|
||
|
//// p_color = (GXColor*)( p_byte + m_diffuse_offset );
|
||
|
//
|
||
|
// // Scan through each vertex, setting the new color.
|
||
|
// for( uint32 i = 0; i < m_num_vertex; ++i )
|
||
|
// {
|
||
|
// // An index of zero means no update for this vert.
|
||
|
// uint32 index = mp_vc_wibble_data[i];
|
||
|
// if( ( index > 0 ) && ( m_flags & MESH_FLAG_VERTEX_COLOR_WIBBLE ) && mp_material->mp_wibble_vc_colors )
|
||
|
// {
|
||
|
// *p_color = mp_material->mp_wibble_vc_colors[index - 1];
|
||
|
// }
|
||
|
// p_color++;
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::Submit( void )
|
||
|
{
|
||
|
// wibble_vc();
|
||
|
//// wibble_normals();
|
||
|
//
|
||
|
// if ( mp_display_list )
|
||
|
// {
|
||
|
// GXCallDisplayList ( mp_display_list, m_display_list_size );
|
||
|
// }
|
||
|
//// // Horribly inefficient, but will have to do for now until we get bucket rendering going.
|
||
|
//// if( mp_material )
|
||
|
//// {
|
||
|
//// mp_material->Submit();
|
||
|
//// }
|
||
|
////
|
||
|
//// // Set pixel and vertex shader.
|
||
|
//// D3DDevice_SetPixelShader( m_pixel_shader );
|
||
|
//// D3DDevice_SetVertexShader( m_fvf_flags );
|
||
|
////
|
||
|
//// // Set the stream source.
|
||
|
//// D3DDevice_SetStreamSource( 0, mp_vertex_buffer, m_vertex_stride );
|
||
|
////
|
||
|
//// // Submit.
|
||
|
//// D3DDevice_DrawIndexedVertices( m_primitive_type, m_num_indices, mp_index_buffer );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
sMesh *sMesh::Clone( bool instance )
|
||
|
{
|
||
|
sMesh *p_clone = new sMesh();
|
||
|
|
||
|
// Copy over basic details.
|
||
|
memcpy( p_clone, this, sizeof( sMesh ));
|
||
|
p_clone->m_flags &= ~(MESH_FLAG_CLONED_POS|MESH_FLAG_CLONED_COL);
|
||
|
|
||
|
if( instance )
|
||
|
{
|
||
|
p_clone->m_flags |= MESH_FLAG_IS_INSTANCE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p_clone->m_flags |= MESH_FLAG_IS_CLONED;
|
||
|
|
||
|
// Clone the display list.
|
||
|
Mem::Manager::sHandle().BottomUpHeap()->PushAlign( 32 );
|
||
|
p_clone->mp_dl = (NxNgc::sDLHeader*)new char[sizeof(NxNgc::sDLHeader)+mp_dl->m_size];
|
||
|
Mem::Manager::sHandle().BottomUpHeap()->PopAlign();
|
||
|
memcpy( p_clone->mp_dl, mp_dl, sizeof(NxNgc::sDLHeader)+mp_dl->m_size );
|
||
|
p_clone->m_flags |= NxNgc::sMesh::MESH_FLAG_CLONED_DL;
|
||
|
|
||
|
|
||
|
|
||
|
// p_clone->m_flags |= MESH_FLAG_IS_INSTANCE;
|
||
|
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// if ( mp_posBuffer )
|
||
|
// {
|
||
|
//#ifdef SHORT_VERT
|
||
|
// p_clone->mp_posBuffer = new s16[3*m_num_vertex];
|
||
|
// memcpy( p_clone->mp_posBuffer, mp_posBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
// DCFlushRange( p_clone->mp_posBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
//#else
|
||
|
// p_clone->mp_posBuffer = new float[3*m_num_vertex];
|
||
|
// memcpy( p_clone->mp_posBuffer, mp_posBuffer, 3 * m_num_vertex * sizeof( float ) );
|
||
|
// DCFlushRange( p_clone->mp_posBuffer, 3 * m_num_vertex * sizeof( float ) );
|
||
|
//#endif // SHORT_VERT
|
||
|
// }
|
||
|
// if ( mp_normBuffer )
|
||
|
// {
|
||
|
// p_clone->mp_normBuffer = new s16[3*m_num_vertex];
|
||
|
// memcpy( p_clone->mp_normBuffer, mp_normBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
// DCFlushRange( p_clone->mp_normBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
// }
|
||
|
//
|
||
|
// if ( mp_colBuffer )
|
||
|
// {
|
||
|
// p_clone->mp_colBuffer = new uint32[m_num_vertex];
|
||
|
// memcpy( p_clone->mp_colBuffer, mp_colBuffer, m_num_vertex * sizeof( uint32 ) );
|
||
|
// DCFlushRange( p_clone->mp_colBuffer, m_num_vertex * sizeof( uint32 ) );
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
return p_clone;
|
||
|
|
||
|
// Dbg_MsgAssert( false, ( "Not yet implmented!!!!!!!!" ) );
|
||
|
// return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///******************************************************************/
|
||
|
///* */
|
||
|
///* */
|
||
|
///******************************************************************/
|
||
|
//void sMesh::Initialize( int num_vertices,
|
||
|
// float* p_positions,
|
||
|
//#ifdef SHORT_VERT
|
||
|
// s16* p_positions16,
|
||
|
// int shift,
|
||
|
// float off_x,
|
||
|
// float off_y,
|
||
|
// float off_z,
|
||
|
//#endif // SHORT_VERT
|
||
|
// s16* p_normals,
|
||
|
// float* p_tex_coords,
|
||
|
// float* p_env_buffer,
|
||
|
// int num_tc_sets,
|
||
|
// uint32* p_colors,
|
||
|
// int num_indices,
|
||
|
// uint16* p_pos_indices,
|
||
|
// uint16* p_col_indices,
|
||
|
// uint16* p_uv_indices,
|
||
|
// unsigned long material_checksum,
|
||
|
// void *p_scene,
|
||
|
// int num_double,
|
||
|
// uint32 * p_double,
|
||
|
// int num_single,
|
||
|
// int localMeshIndex,
|
||
|
// GXPrimitive primitive_type,
|
||
|
// int bone_idx,
|
||
|
// char *p_vc_wibble_anims )
|
||
|
//
|
||
|
//{
|
||
|
// m_num_indices = 0;
|
||
|
// m_vertex_stride = 0;
|
||
|
// m_num_vertex = num_vertices;
|
||
|
//
|
||
|
// m_bone_idx = bone_idx;
|
||
|
//
|
||
|
//// m_primitive_type = D3DPT_TRIANGLESTRIP;
|
||
|
//// m_fvf_flags = 0;
|
||
|
//// m_pixel_shader = 0;
|
||
|
//
|
||
|
//// mp_posBuffer = NULL; //p_positions;
|
||
|
//// mp_normBuffer = p_normals;
|
||
|
//// mp_uvBuffer = NULL; //p_tex_coords;
|
||
|
//// mp_colBuffer = NULL; //p_colors;
|
||
|
//// mp_index_buffer = NULL; //p_indices;
|
||
|
//
|
||
|
// mp_normBuffer = p_normals;
|
||
|
// mp_uvBuffer = p_tex_coords;
|
||
|
// mp_colBuffer = p_colors;
|
||
|
// m_num_uv_sets = num_tc_sets;
|
||
|
//
|
||
|
// m_numDouble = num_double;
|
||
|
// m_numSingle = num_single;
|
||
|
// mp_doubleWeight = p_double;
|
||
|
//
|
||
|
// m_localMeshIndex = localMeshIndex;
|
||
|
//
|
||
|
// // First thing to do is grab the material pointer for this mesh.
|
||
|
// mp_material = ((sScene*)p_scene )->GetMaterial( material_checksum );
|
||
|
//// if( mp_material == NULL )
|
||
|
//// {
|
||
|
//// exit( 0 );
|
||
|
////
|
||
|
//// // Try with the dummy material for now.
|
||
|
//// // mp_material = GetMaterial( 0 );
|
||
|
//// }
|
||
|
//
|
||
|
//// if( num_indices == 0 )
|
||
|
//// {
|
||
|
//// return;
|
||
|
//// }
|
||
|
////
|
||
|
//// // Figure the min and max indices for this mesh.
|
||
|
//// uint16 min_index = p_indices[0];
|
||
|
//// uint16 max_index = p_indices[0];
|
||
|
//// for( int i = 1; i < num_indices; ++i )
|
||
|
//// {
|
||
|
//// if( p_indices[i] > max_index )
|
||
|
//// {
|
||
|
//// max_index = p_indices[i];
|
||
|
//// }
|
||
|
//// else if( p_indices[i] < min_index )
|
||
|
//// {
|
||
|
//// min_index = p_indices[i];
|
||
|
//// }
|
||
|
//// }
|
||
|
//
|
||
|
// // See if any vertex color alpha valus are less than any of the texture's cutoff values.
|
||
|
// // If so, make sure that the texture is specified as having holes.
|
||
|
// for ( int lp = 0; lp < num_vertices; lp++ )
|
||
|
// {
|
||
|
// if ( ( p_colors[lp] & 255 ) < mp_material->AlphaCutoff )
|
||
|
// {
|
||
|
// for ( int pass = 0; pass < mp_material->Passes; pass++ )
|
||
|
// {
|
||
|
//// if ( mp_material->pTex[pass] ) mp_material->pTex[pass]->HasHoles = 1;
|
||
|
// if ( mp_material->pTex[pass] )
|
||
|
// {
|
||
|
// if ( !mp_material->pTex[pass]->HasHoles )
|
||
|
// {
|
||
|
// mp_material->pTex[pass]->HasHoles = 1;
|
||
|
// OSReport( "Material found that was incorrectly flagged.\n" );
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// break;
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// // See if any of the material layers require environment mapping.
|
||
|
// mp_envBuffer = NULL;
|
||
|
// for ( int pass = 0; pass < mp_material->Passes; pass++ )
|
||
|
// {
|
||
|
// if ( mp_material->Flags[pass] & MATFLAG_ENVIRONMENT )
|
||
|
// {
|
||
|
// if ( p_env_buffer )
|
||
|
// {
|
||
|
// // Already allocated one, so just assign it.
|
||
|
// mp_envBuffer = p_env_buffer;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // Has environment mapping, so allocate an environment map uv buffer.
|
||
|
// mp_envBuffer = new float[2*num_vertices];
|
||
|
// }
|
||
|
// // Break so that we only allocate once.
|
||
|
// break;
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// // Set the bounding box.
|
||
|
// if ( p_positions )
|
||
|
// {
|
||
|
// // Non-skinned.
|
||
|
// for( int v = 0; v < num_vertices; ++v )
|
||
|
// {
|
||
|
// // Do bounding box setting.
|
||
|
// Mth::Vector p( p_positions[(v*3)+0], p_positions[(v*3)+1], p_positions[(v*3)+2] );
|
||
|
// m_bbox.AddPoint( p );
|
||
|
// }
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // Skinned.
|
||
|
// uint32* p32 = p_double;
|
||
|
// for ( int lp = 0; lp < num_double; lp++ ) {
|
||
|
// uint32 pairs = *p32++;
|
||
|
// /*uint32 mtx = **/p32++;
|
||
|
// float* p_pn = (float *)p32;
|
||
|
// float* p_weight = (float *)&p_pn[(6*pairs)];
|
||
|
//
|
||
|
// for( uint v = 0; v < pairs; ++v )
|
||
|
// {
|
||
|
// // Do bounding box setting.
|
||
|
// Mth::Vector p( p_pn[(v*6)+0], p_pn[(v*6)+1], p_pn[(v*6)+2] );
|
||
|
// m_bbox.AddPoint( p );
|
||
|
// }
|
||
|
//
|
||
|
// p32 = (uint32 *)&p_weight[pairs*2];
|
||
|
// }
|
||
|
// }
|
||
|
// float x = ( m_bbox.GetMax().GetX() + m_bbox.GetMin().GetX() ) / 2;
|
||
|
// float y = ( m_bbox.GetMax().GetY() + m_bbox.GetMin().GetY() ) / 2;
|
||
|
// float z = ( m_bbox.GetMax().GetZ() + m_bbox.GetMin().GetZ() ) / 2;
|
||
|
// float r = ( m_bbox.GetMax().GetX() - m_bbox.GetMin().GetX() ) * ( m_bbox.GetMax().GetX() - m_bbox.GetMin().GetX() );
|
||
|
// r += ( m_bbox.GetMax().GetY() - m_bbox.GetMin().GetY() ) * ( m_bbox.GetMax().GetY() - m_bbox.GetMin().GetY() );
|
||
|
// r += ( m_bbox.GetMax().GetZ() - m_bbox.GetMin().GetZ() ) * ( m_bbox.GetMax().GetZ() - m_bbox.GetMin().GetZ() );
|
||
|
// r = sqrtf( r );
|
||
|
// r = r / 2.0f;
|
||
|
// m_sphere[0] = x;
|
||
|
// m_sphere[1] = y;
|
||
|
// m_sphere[2] = z;
|
||
|
// m_sphere[3] = r;
|
||
|
//
|
||
|
// // Set the position buffer & offset.
|
||
|
//#ifdef SHORT_VERT
|
||
|
// mp_posBuffer = p_positions16;
|
||
|
//#else
|
||
|
// mp_posBuffer = p_positions;
|
||
|
//#endif // SHORT_VERT
|
||
|
//
|
||
|
// if ( p_positions )
|
||
|
// {
|
||
|
//#ifdef SHORT_VERT
|
||
|
// // Non-skinned.
|
||
|
// switch ( shift )
|
||
|
// {
|
||
|
// case 1:
|
||
|
// m_vertex_format = GX_VTXFMT2;
|
||
|
// break;
|
||
|
// case 2:
|
||
|
// m_vertex_format = GX_VTXFMT3;
|
||
|
// break;
|
||
|
// case 3:
|
||
|
// m_vertex_format = GX_VTXFMT4;
|
||
|
// break;
|
||
|
// case 4:
|
||
|
// m_vertex_format = GX_VTXFMT5;
|
||
|
// break;
|
||
|
// case 5:
|
||
|
// m_vertex_format = GX_VTXFMT6;
|
||
|
// break;
|
||
|
// case 6:
|
||
|
// m_vertex_format = GX_VTXFMT7;
|
||
|
// break;
|
||
|
// case 0:
|
||
|
// default:
|
||
|
// m_vertex_format = GX_VTXFMT1;
|
||
|
// break;
|
||
|
// }
|
||
|
//#else
|
||
|
// m_vertex_format = GX_VTXFMT6;
|
||
|
//#endif // SHORT_VERT
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // Skinned.
|
||
|
// m_vertex_format = GX_VTXFMT7;
|
||
|
// }
|
||
|
//
|
||
|
//#ifdef SHORT_VERT
|
||
|
// m_offset_x = off_x;
|
||
|
// m_offset_y = off_y;
|
||
|
// m_offset_z = off_z;
|
||
|
//#endif // SHORT_VERT
|
||
|
//
|
||
|
//// if( max_index >= num_vertices )
|
||
|
//// {
|
||
|
//// // Error!
|
||
|
//// exit( 0 );
|
||
|
//// }
|
||
|
//
|
||
|
// // Now figure the total number of vertices required for this mesh, to span the min->max indices.
|
||
|
//// uint16 vertices_for_this_mesh = max_index - min_index + 1;
|
||
|
//
|
||
|
// // Create the index buffer (should be 16byte aligned for best performance).
|
||
|
//// mp_index_buffer = new uint16[num_indices];
|
||
|
//
|
||
|
// // Set our count of the number of indices.
|
||
|
// m_num_indices = num_indices - 2; // Only used for skinned - subtract count & trailing 0.
|
||
|
//
|
||
|
// // Copy in index data, normaling the indices for this vertex buffer (i.e. so the lowest index will reference
|
||
|
// // vertex 0 in the buffer built specifically for this mesh).
|
||
|
//// for( int i = 0; i < num_indices; ++i )
|
||
|
//// {
|
||
|
//// mp_index_buffer[i] = p_indices[i]; // - min_index;
|
||
|
//// }
|
||
|
//
|
||
|
// // Use the material flags to figure the vertex format.
|
||
|
// int vertex_size = 3 * sizeof( float );
|
||
|
//
|
||
|
// // Include weights (for weighted animation) if present.
|
||
|
//// if( p_weights )
|
||
|
//// {
|
||
|
//// Dbg_Assert( p_matrix_indices );
|
||
|
//// vertex_size += sizeof( float ) * 4;
|
||
|
//// }
|
||
|
//
|
||
|
// // Include indices (for weighted animation) if present.
|
||
|
//// if( p_matrix_indices )
|
||
|
//// {
|
||
|
//// Dbg_Assert( p_weights );
|
||
|
//// vertex_size += sizeof( uint16 ) * 4;
|
||
|
//// }
|
||
|
//
|
||
|
// // Texture coordinates.
|
||
|
// uint32 tex_coord_pass = 0;
|
||
|
//// bool env_mapped = false;
|
||
|
// if( p_tex_coords )
|
||
|
// {
|
||
|
// for( uint32 pass = 0; pass < mp_material->Passes; ++pass )
|
||
|
// {
|
||
|
//// if( mp_material->Flags[pass] & MATFLAG_ENVIRONMENT )
|
||
|
//// {
|
||
|
//// env_mapped = true;
|
||
|
//// }
|
||
|
//
|
||
|
// // Only need UV's for this stage if it is *not* environment mapped.
|
||
|
// if(( mp_material->pTex[pass] ) /*&& ( !( mp_material->Flags[pass] & MATFLAG_ENVIRONMENT ))*/)
|
||
|
// {
|
||
|
// // Will need uv for this pass and all before it.
|
||
|
// tex_coord_pass = pass + 1;
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// for( uint32 pass = 0; pass < mp_material->Passes; ++pass )
|
||
|
// {
|
||
|
//// if( mp_material->Flags[pass] & MATFLAG_ENVIRONMENT )
|
||
|
//// {
|
||
|
//// env_mapped = true;
|
||
|
//// }
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// if( tex_coord_pass > 0 )
|
||
|
// {
|
||
|
// vertex_size += 2 * sizeof( float ) * tex_coord_pass;
|
||
|
// }
|
||
|
//
|
||
|
// // Assume no normals for now.
|
||
|
// if( 0 )
|
||
|
// {
|
||
|
// // We want vertex colors in this mesh,
|
||
|
// if( 0 )
|
||
|
// {
|
||
|
// // The raw vertex data does not contain vertex colors.
|
||
|
// exit( 0 );
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // The raw vertex data does contain vertex colors.
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// bool use_colors = false;
|
||
|
// if( p_colors )
|
||
|
// {
|
||
|
// // We want vertex colors in this mesh,
|
||
|
// if( 0 )
|
||
|
// {
|
||
|
// // The raw vertex data does not contain vertex colors.
|
||
|
// exit( 0 );
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // The raw vertex data does contain vertex colors.
|
||
|
// vertex_size += sizeof( uint32 );
|
||
|
// use_colors = true;
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// // Create the vertex color wibble array if data is present.
|
||
|
// if( p_vc_wibble_anims )
|
||
|
// {
|
||
|
// mp_vc_wibble_data = p_vc_wibble_anims;
|
||
|
// }
|
||
|
//
|
||
|
//// if ( p_double )
|
||
|
//// {
|
||
|
//// mp_doubleWeight = 1;
|
||
|
//// }
|
||
|
//// else
|
||
|
//// {
|
||
|
//// mp_doubleWeight = 0;
|
||
|
//// }
|
||
|
//
|
||
|
// m_primitive_type = primitive_type;
|
||
|
//
|
||
|
// Build( num_indices, p_pos_indices, p_col_indices, p_uv_indices );
|
||
|
//
|
||
|
// // Find the index list in the display list data.
|
||
|
// mp_index_buffer = NULL;
|
||
|
// {
|
||
|
// unsigned char * p8;
|
||
|
// unsigned char search[3];
|
||
|
//
|
||
|
// p8 = (unsigned char *)mp_display_list;
|
||
|
//
|
||
|
// search[0] = *p8++;
|
||
|
// search[1] = *p8++;
|
||
|
// for ( int ss = 2; ss < m_display_list_size; ss++ ) {
|
||
|
// search[2] = *p8++;
|
||
|
//
|
||
|
// if ( ( ( search[0] & 0xf8 ) == m_primitive_type ) &&
|
||
|
// ( ( ( search[1] << 8 ) | search[2] ) == (int)*p_pos_indices ) ) {
|
||
|
// // Found it!!!
|
||
|
// if ( num_double )
|
||
|
// {
|
||
|
// // Skinned mesh.
|
||
|
// mp_index_buffer = (unsigned short *)p8;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // Non-skinned mesh.
|
||
|
// mp_index_buffer = (unsigned short *)&p8[-2];
|
||
|
// }
|
||
|
// break;
|
||
|
// }
|
||
|
// search[0] = search[1];
|
||
|
// search[1] = search[2];
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
//// if ( p_double )
|
||
|
//// {
|
||
|
//// double_bytes = dbytes;
|
||
|
//// single_bytes = sbytes;
|
||
|
////
|
||
|
//// if ( m_localMeshIndex == 0 )
|
||
|
//// {
|
||
|
//// NsARAM::HEAPTYPE heap = NsARAM::BOTTOMUP;
|
||
|
////
|
||
|
//// if ( Mem::Manager::sHandle().GetContextAllocator() == Mem::Manager::sHandle().SkaterGeomHeap(0) )
|
||
|
//// {
|
||
|
//// heap = NsARAM::SKATER0;
|
||
|
//// }
|
||
|
//// if ( Mem::Manager::sHandle().GetContextAllocator() == Mem::Manager::sHandle().SkaterGeomHeap(1) )
|
||
|
//// {
|
||
|
//// heap = NsARAM::SKATER1;
|
||
|
//// }
|
||
|
////
|
||
|
//// //OSReport( "Allocating %d ARAM bytes %s\n", dbytes + sbytes, Mem::Manager::sHandle().GetContextName() );
|
||
|
//// mp_doubleWeight = NsARAM::alloc( (dbytes + sbytes) * 4, heap );
|
||
|
//// NsDMA::toARAM( mp_doubleWeight, p_double, ( dbytes + sbytes ) * 4 );
|
||
|
//// }
|
||
|
//// }
|
||
|
//// else
|
||
|
//// {
|
||
|
//// mp_doubleWeight = 0;
|
||
|
//// double_bytes = dbytes;
|
||
|
//// single_bytes = sbytes;
|
||
|
//// }
|
||
|
//
|
||
|
// delete p_pos_indices;
|
||
|
//}
|
||
|
|
||
|
//void sMesh::Build( int num_indices, uint16* p_pos_indices, uint16* p_col_indices, uint16* p_uv_indices, bool rebuild )
|
||
|
//{
|
||
|
// Mem::Manager::sHandle().BottomUpHeap()->PushAlign( 32 );
|
||
|
// EngineGlobals.gpuBusy = true;
|
||
|
// // Turn the index list into a display list.
|
||
|
// mp_display_list = NULL;
|
||
|
//#define DL_BUILD_SIZE (32*1024)
|
||
|
// uint8 * p_build_dl = new (Mem::Manager::sHandle().TopDownHeap()) uint8[DL_BUILD_SIZE];
|
||
|
// DCFlushRange ( p_build_dl, DL_BUILD_SIZE );
|
||
|
//
|
||
|
// GXBeginDisplayList ( p_build_dl, DL_BUILD_SIZE );
|
||
|
// GXResetWriteGatherPipe();
|
||
|
//
|
||
|
// GXClearVtxDesc();
|
||
|
// GXSetVtxDesc( GX_VA_POS, GX_INDEX16 );
|
||
|
// m_vertex_stride = 1;
|
||
|
// if ( mp_normBuffer || mp_doubleWeight )
|
||
|
// {
|
||
|
// GXSetVtxDesc( GX_VA_NRM, GX_INDEX16 );
|
||
|
// m_vertex_stride++;
|
||
|
// }
|
||
|
// if ( mp_colBuffer )
|
||
|
// {
|
||
|
// GXSetVtxDesc( GX_VA_CLR0, GX_INDEX16 );
|
||
|
// m_vertex_stride++;
|
||
|
// if ( !mp_doubleWeight && gCorrectColor )
|
||
|
// {
|
||
|
// // Before we go wading in and allow a 2nd color index list, see if it's necessary.
|
||
|
// // Check every poly in the mesh and see if the color difference is greater than a threshold.
|
||
|
// bool needs_fixing = false;
|
||
|
// uint32 color0;
|
||
|
// uint32 color1 = mp_colBuffer[p_col_indices[p_pos_indices[0]]];
|
||
|
// uint32 color2 = mp_colBuffer[p_col_indices[p_pos_indices[1]]];
|
||
|
// for ( int lp = 2; lp < num_indices; lp++ )
|
||
|
// {
|
||
|
// // Grab new color to form triangle.
|
||
|
// color0 = color1;
|
||
|
// color1 = color2;
|
||
|
// color2 = mp_colBuffer[p_col_indices[p_pos_indices[lp]]];
|
||
|
//
|
||
|
// int diff0_a = abs( ( ( color1 >> 24 ) & 255 ) - ( ( color0 >> 24 ) & 255 ) );
|
||
|
// int diff1_a = abs( ( ( color2 >> 24 ) & 255 ) - ( ( color1 >> 24 ) & 255 ) );
|
||
|
// int diff2_a = abs( ( ( color0 >> 24 ) & 255 ) - ( ( color2 >> 24 ) & 255 ) );
|
||
|
// int diff0_r = abs( ( ( color1 >> 16 ) & 255 ) - ( ( color0 >> 16 ) & 255 ) );
|
||
|
// int diff1_r = abs( ( ( color2 >> 16 ) & 255 ) - ( ( color1 >> 16 ) & 255 ) );
|
||
|
// int diff2_r = abs( ( ( color0 >> 16 ) & 255 ) - ( ( color2 >> 16 ) & 255 ) );
|
||
|
// int diff0_g = abs( ( ( color1 >> 8 ) & 255 ) - ( ( color0 >> 8 ) & 255 ) );
|
||
|
// int diff1_g = abs( ( ( color2 >> 8 ) & 255 ) - ( ( color1 >> 8 ) & 255 ) );
|
||
|
// int diff2_g = abs( ( ( color0 >> 8 ) & 255 ) - ( ( color2 >> 8 ) & 255 ) );
|
||
|
// int diff0_b = abs( ( ( color1 >> 0 ) & 255 ) - ( ( color0 >> 0 ) & 255 ) );
|
||
|
// int diff1_b = abs( ( ( color2 >> 0 ) & 255 ) - ( ( color1 >> 0 ) & 255 ) );
|
||
|
// int diff2_b = abs( ( ( color0 >> 0 ) & 255 ) - ( ( color2 >> 0 ) & 255 ) );
|
||
|
//
|
||
|
// int wdiff = diff0_a;
|
||
|
// if ( diff1_a > wdiff ) wdiff = diff1_a;
|
||
|
// if ( diff2_a > wdiff ) wdiff = diff2_a;
|
||
|
// if ( diff0_r > wdiff ) wdiff = diff0_r;
|
||
|
// if ( diff1_r > wdiff ) wdiff = diff1_r;
|
||
|
// if ( diff2_r > wdiff ) wdiff = diff2_r;
|
||
|
// if ( diff0_g > wdiff ) wdiff = diff0_g;
|
||
|
// if ( diff1_g > wdiff ) wdiff = diff1_g;
|
||
|
// if ( diff2_g > wdiff ) wdiff = diff2_g;
|
||
|
// if ( diff0_b > wdiff ) wdiff = diff0_b;
|
||
|
// if ( diff1_b > wdiff ) wdiff = diff1_b;
|
||
|
// if ( diff2_b > wdiff ) wdiff = diff2_b;
|
||
|
//
|
||
|
// if ( wdiff > 8 ) needs_fixing = true;
|
||
|
// }
|
||
|
//
|
||
|
// if ( needs_fixing )
|
||
|
// {
|
||
|
// m_flags |= MESH_FLAG_DOUBLE_COLOR_IDX;
|
||
|
// GXSetVtxDesc( GX_VA_CLR1, GX_INDEX16 );
|
||
|
// m_vertex_stride++;
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// int coord = 0;
|
||
|
// for ( uint layer = 0; layer < mp_material->Passes; layer++ )
|
||
|
// {
|
||
|
// GXSetVtxDesc( (GXAttr)(((int)GX_VA_TEX0)+coord), GX_INDEX16 );
|
||
|
// m_vertex_stride++;
|
||
|
// coord++;
|
||
|
// }
|
||
|
//
|
||
|
// if ( rebuild )
|
||
|
// {
|
||
|
// // Send coordinates.
|
||
|
// GXBegin( (GXPrimitive)m_primitive_type, (GXVtxFmt)m_vertex_format, num_indices );
|
||
|
// for ( int lp = 0; lp < num_indices; lp++ )
|
||
|
// {
|
||
|
// // Send coordinates.
|
||
|
// int pindex = p_pos_indices[lp];
|
||
|
// int cindex = p_col_indices[pindex];
|
||
|
// GXPosition1x16(pindex);
|
||
|
// if ( mp_normBuffer || mp_doubleWeight ) GXNormal1x16(pindex);
|
||
|
// if ( mp_colBuffer ) GXColor1x16(cindex);
|
||
|
// if ( m_flags & MESH_FLAG_DOUBLE_COLOR_IDX ) GXColor1x16(cindex);
|
||
|
// for ( uint layer = 0; layer < mp_material->Passes; layer++ )
|
||
|
// {
|
||
|
// int uindex = pindex;
|
||
|
// if ( p_uv_indices ) uindex = p_uv_indices[pindex+(layer*m_num_vertex)];
|
||
|
// GXTexCoord1x16(uindex);
|
||
|
// }
|
||
|
// }
|
||
|
// GXEnd();
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// // Parse index list & turn into gxbegin/end pairs.
|
||
|
// int v = 0;
|
||
|
// while ( p_pos_indices[v] )
|
||
|
// {
|
||
|
// uint16 num = p_pos_indices[v];
|
||
|
// v++;
|
||
|
//
|
||
|
// GXBegin( (GXPrimitive)m_primitive_type, (GXVtxFmt)m_vertex_format, num );
|
||
|
//
|
||
|
// for ( int vv = 0; vv < num; vv++ )
|
||
|
// {
|
||
|
// // Send coordinates.
|
||
|
// int pindex = p_pos_indices[v+vv];
|
||
|
// int cindex = p_col_indices[pindex];
|
||
|
// GXPosition1x16(pindex);
|
||
|
// if ( mp_normBuffer || mp_doubleWeight ) GXNormal1x16(pindex);
|
||
|
// if ( mp_colBuffer ) GXColor1x16(cindex);
|
||
|
// if ( m_flags & MESH_FLAG_DOUBLE_COLOR_IDX ) GXColor1x16(cindex);
|
||
|
// for ( uint layer = 0; layer < mp_material->Passes; layer++ )
|
||
|
// {
|
||
|
// int uindex = pindex;
|
||
|
// if ( p_uv_indices ) uindex = p_uv_indices[pindex+(layer*m_num_vertex)];
|
||
|
// GXTexCoord1x16(uindex);
|
||
|
// }
|
||
|
// }
|
||
|
// v += num;
|
||
|
// GXEnd();
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// int size = GXEndDisplayList();
|
||
|
//
|
||
|
// mp_index_buffer = NULL;
|
||
|
//
|
||
|
// uint8 * p_dl = new uint8[size];
|
||
|
// memcpy ( p_dl, p_build_dl, size );
|
||
|
// DCFlushRange ( p_dl, size );
|
||
|
//
|
||
|
// delete p_build_dl;
|
||
|
//
|
||
|
// mp_display_list = p_dl;
|
||
|
// m_display_list_size = size;
|
||
|
// EngineGlobals.gpuBusy = false;
|
||
|
//
|
||
|
// Mem::Manager::sHandle().BottomUpHeap()->PopAlign();
|
||
|
//}
|
||
|
//
|
||
|
//void sMesh::Rebuild( int num_indices, uint16* p_indices )
|
||
|
//{
|
||
|
// uint16 * p_temp_col_remap = NULL;
|
||
|
// uint16 * p_temp_uv_remap = NULL;
|
||
|
// p_temp_uv_remap = m_num_uv_sets ? new (Mem::Manager::sHandle().TopDownHeap()) uint16[m_num_vertex*m_num_uv_sets] : NULL;
|
||
|
// p_temp_col_remap = mp_colBuffer ? new (Mem::Manager::sHandle().TopDownHeap()) uint16[m_num_vertex] : NULL;
|
||
|
//
|
||
|
// for ( int c = 0; c < m_num_vertex; c++ )
|
||
|
// {
|
||
|
// for ( int u = 0; u < m_num_uv_sets; u++ )
|
||
|
// {
|
||
|
// p_temp_uv_remap[(u*m_num_vertex)+c] = (u*m_num_vertex)+c;
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// for ( int c = 0; c < m_num_vertex; c++ )
|
||
|
// {
|
||
|
// p_temp_col_remap[c] = c;
|
||
|
// }
|
||
|
//
|
||
|
// delete [] mp_display_list;
|
||
|
//
|
||
|
//// Build( num_indices, p_indices, p_indices, p_indices, true );
|
||
|
// Build( num_indices, p_indices, p_temp_col_remap, p_temp_uv_remap, true );
|
||
|
// // Update to new number of indices.
|
||
|
// m_num_indices = num_indices;
|
||
|
//
|
||
|
// delete [] p_temp_col_remap;
|
||
|
// delete [] p_temp_uv_remap;
|
||
|
//}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::SetPosition( Mth::Vector &pos )
|
||
|
{
|
||
|
|
||
|
|
||
|
// // Figure what we need to add to each vertex, based on current position.
|
||
|
// Mth::Vector offset( pos[X] - m_offset_x,
|
||
|
// pos[Y] - m_offset_y,
|
||
|
// pos[Z] - m_offset_z );
|
||
|
// m_offset_x = pos[X];
|
||
|
// m_offset_y = pos[Y];
|
||
|
// m_offset_z = pos[Z];
|
||
|
//
|
||
|
// // We also need to adjust the bounding box and sphere information for this mesh.
|
||
|
// m_sphere[0] += offset[X];
|
||
|
// m_sphere[1] += offset[Y];
|
||
|
// m_sphere[2] += offset[Z];
|
||
|
//
|
||
|
// m_bbox.SetMin( m_bbox.GetMin() + offset );
|
||
|
// m_bbox.SetMax( m_bbox.GetMax() + offset );
|
||
|
//
|
||
|
//#ifndef SHORT_VERT
|
||
|
// if ( m_localMeshIndex != 0 ) return;
|
||
|
//
|
||
|
// for( uint32 bv = 0; bv < m_num_vertex; ++bv )
|
||
|
// {
|
||
|
// mp_posBuffer[(bv*3)+0] += offset[X];
|
||
|
// mp_posBuffer[(bv*3)+1] += offset[Y];
|
||
|
// mp_posBuffer[(bv*3)+2] += offset[Z];
|
||
|
// }
|
||
|
// DCFlushRange( mp_posBuffer, 3 * sizeof( float ) * m_num_vertex );
|
||
|
//#endif // SHORT_VERT
|
||
|
//
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::GetPosition( Mth::Vector *p_pos )
|
||
|
{
|
||
|
// p_pos->Set( m_offset_x, m_offset_y, m_offset_z );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
void sMesh::SetYRotation( Mth::ERot90 rot )
|
||
|
{
|
||
|
// if( ( rot > Mth::ROT_0 ) && ( m_localMeshIndex == 0 ) )
|
||
|
// {
|
||
|
// s16 nx, nz;
|
||
|
//#ifdef SHORT_VERT
|
||
|
// s16 xo = 0;
|
||
|
// s16 zo = 0;
|
||
|
// s16 x, z;
|
||
|
//#else
|
||
|
// float x, z;
|
||
|
// float xo = m_offset_x;
|
||
|
// float zo = m_offset_z;
|
||
|
//#endif // SHORT_VERT
|
||
|
// switch( rot )
|
||
|
// {
|
||
|
// case Mth::ROT_90:
|
||
|
// {
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// for( uint32 v = 0; v < m_num_vertex; ++v )
|
||
|
// {
|
||
|
// x = mp_posBuffer[(v*3)+0] - xo;
|
||
|
// z = mp_posBuffer[(v*3)+2] - zo;
|
||
|
// mp_posBuffer[(v*3)+0] = z + xo;
|
||
|
// mp_posBuffer[(v*3)+2] = -x + zo;
|
||
|
// if ( mp_normBuffer )
|
||
|
// {
|
||
|
// nx = mp_normBuffer[(v*3)+0];
|
||
|
// nz = mp_normBuffer[(v*3)+2];
|
||
|
// mp_normBuffer[(v*3)+0] = nz;
|
||
|
// mp_normBuffer[(v*3)+2] = -nx;
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// // Adjust the bounding sphere information for this mesh.
|
||
|
// m_sphere[0] -= m_offset_x;
|
||
|
// m_sphere[2] -= m_offset_z;
|
||
|
// float t = m_sphere[0];
|
||
|
// m_sphere[0] = m_sphere[2] + m_offset_x;
|
||
|
// m_sphere[2] = -t + m_offset_z;
|
||
|
//
|
||
|
// // Adjust the bounding box information for this mesh.
|
||
|
// Mth::Vector m[4];
|
||
|
//
|
||
|
// m[0].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[1].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
// m[2].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[3].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
//
|
||
|
// for( int i = 0; i < 4; ++i )
|
||
|
// {
|
||
|
// m[i][X] -= m_offset_x;
|
||
|
// m[i][Z] -= m_offset_z;
|
||
|
// float t = m[i][X];
|
||
|
// m[i][X] = m[i][Z];
|
||
|
// m[i][Z] = -t;
|
||
|
// m[i][X] += m_offset_x;
|
||
|
// m[i][Z] += m_offset_z;
|
||
|
// }
|
||
|
//
|
||
|
// Mth::Vector mmin( m[0][X], m_bbox.GetMin()[Y], m[0][Z] );
|
||
|
// Mth::Vector mmax( m[0][X], m_bbox.GetMax()[Y], m[0][Z] );
|
||
|
// for( int i = 1; i < 4; ++i )
|
||
|
// {
|
||
|
// if( m[i][X] < mmin[X] )
|
||
|
// mmin[X] = m[i][X];
|
||
|
// if( m[i][X] > mmax[X] )
|
||
|
// mmax[X] = m[i][X];
|
||
|
//
|
||
|
// if( m[i][Z] < mmin[Z] )
|
||
|
// mmin[Z] = m[i][Z];
|
||
|
// if( m[i][Z] > mmax[Z] )
|
||
|
// mmax[Z] = m[i][Z];
|
||
|
// }
|
||
|
//
|
||
|
// m_bbox.SetMin( mmin );
|
||
|
// m_bbox.SetMax( mmax );
|
||
|
// break;
|
||
|
// }
|
||
|
// case Mth::ROT_180:
|
||
|
// {
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// for( uint32 v = 0; v < m_num_vertex; ++v )
|
||
|
// {
|
||
|
// x = mp_posBuffer[(v*3)+0] - xo;
|
||
|
// z = mp_posBuffer[(v*3)+2] - zo;
|
||
|
// mp_posBuffer[(v*3)+0] = -x + xo;
|
||
|
// mp_posBuffer[(v*3)+2] = -z + zo;
|
||
|
// if ( mp_normBuffer )
|
||
|
// {
|
||
|
// nx = mp_normBuffer[(v*3)+0];
|
||
|
// nz = mp_normBuffer[(v*3)+2];
|
||
|
// mp_normBuffer[(v*3)+0] = -nx;
|
||
|
// mp_normBuffer[(v*3)+2] = -nz;
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// // Adjust the bounding sphere information for this mesh.
|
||
|
// m_sphere[0] -= m_offset_x;
|
||
|
// m_sphere[2] -= m_offset_z;
|
||
|
// m_sphere[0] = -m_sphere[0] + m_offset_x;
|
||
|
// m_sphere[2] = -m_sphere[2] + m_offset_z;
|
||
|
//
|
||
|
// // Adjust the bounding box information for this mesh.
|
||
|
// Mth::Vector m[4];
|
||
|
//
|
||
|
// m[0].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[1].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
// m[2].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[3].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
//
|
||
|
// for( int i = 0; i < 4; ++i )
|
||
|
// {
|
||
|
// m[i][X] -= m_offset_x;
|
||
|
// m[i][Z] -= m_offset_z;
|
||
|
// m[i][X] = -m[i][X];
|
||
|
// m[i][Z] = -m[i][Z];
|
||
|
// m[i][X] += m_offset_x;
|
||
|
// m[i][Z] += m_offset_z;
|
||
|
// }
|
||
|
//
|
||
|
// Mth::Vector mmin( m[0][X], m_bbox.GetMin()[Y], m[0][Z] );
|
||
|
// Mth::Vector mmax( m[0][X], m_bbox.GetMax()[Y], m[0][Z] );
|
||
|
// for( int i = 1; i < 4; ++i )
|
||
|
// {
|
||
|
// if( m[i][X] < mmin[X] )
|
||
|
// mmin[X] = m[i][X];
|
||
|
// if( m[i][X] > mmax[X] )
|
||
|
// mmax[X] = m[i][X];
|
||
|
//
|
||
|
// if( m[i][Z] < mmin[Z] )
|
||
|
// mmin[Z] = m[i][Z];
|
||
|
// if( m[i][Z] > mmax[Z] )
|
||
|
// mmax[Z] = m[i][Z];
|
||
|
// }
|
||
|
//
|
||
|
// m_bbox.SetMin( mmin );
|
||
|
// m_bbox.SetMax( mmax );
|
||
|
// break;
|
||
|
// }
|
||
|
// case Mth::ROT_270:
|
||
|
// {
|
||
|
// if ( m_localMeshIndex == 0 )
|
||
|
// {
|
||
|
// for( uint32 v = 0; v < m_num_vertex; ++v )
|
||
|
// {
|
||
|
// x = mp_posBuffer[(v*3)+0] - xo;
|
||
|
// z = mp_posBuffer[(v*3)+2] - zo;
|
||
|
// mp_posBuffer[(v*3)+0] = -z + xo;
|
||
|
// mp_posBuffer[(v*3)+2] = x + zo;
|
||
|
// if ( mp_normBuffer )
|
||
|
// {
|
||
|
// nx = mp_normBuffer[(v*3)+0];
|
||
|
// nz = mp_normBuffer[(v*3)+2];
|
||
|
// mp_normBuffer[(v*3)+0] = -nz;
|
||
|
// mp_normBuffer[(v*3)+2] = nx;
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// // Adjust the bounding sphere information for this mesh.
|
||
|
// m_sphere[0] -= m_offset_x;
|
||
|
// m_sphere[2] -= m_offset_z;
|
||
|
// float t = m_sphere[0];
|
||
|
// m_sphere[0] = -m_sphere[2] + m_offset_x;
|
||
|
// m_sphere[2] = t + m_offset_z;
|
||
|
//
|
||
|
// // Adjust the bounding box information for this mesh.
|
||
|
// Mth::Vector m[4];
|
||
|
//
|
||
|
// m[0].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[1].Set( m_bbox.GetMin()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
// m[2].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMin()[Z] );
|
||
|
// m[3].Set( m_bbox.GetMax()[X], 0.0f, m_bbox.GetMax()[Z] );
|
||
|
//
|
||
|
// for( int i = 0; i < 4; ++i )
|
||
|
// {
|
||
|
// m[i][X] -= m_offset_x;
|
||
|
// m[i][Z] -= m_offset_z;
|
||
|
// float t = m[i][X];
|
||
|
// m[i][X] = -m[i][Z];
|
||
|
// m[i][Z] = t;
|
||
|
// m[i][X] += m_offset_x;
|
||
|
// m[i][Z] += m_offset_z;
|
||
|
// }
|
||
|
//
|
||
|
// Mth::Vector mmin( m[0][X], m_bbox.GetMin()[Y], m[0][Z] );
|
||
|
// Mth::Vector mmax( m[0][X], m_bbox.GetMax()[Y], m[0][Z] );
|
||
|
// for( int i = 1; i < 4; ++i )
|
||
|
// {
|
||
|
// if( m[i][X] < mmin[X] )
|
||
|
// mmin[X] = m[i][X];
|
||
|
// if( m[i][X] > mmax[X] )
|
||
|
// mmax[X] = m[i][X];
|
||
|
//
|
||
|
// if( m[i][Z] < mmin[Z] )
|
||
|
// mmin[Z] = m[i][Z];
|
||
|
// if( m[i][Z] > mmax[Z] )
|
||
|
// mmax[Z] = m[i][Z];
|
||
|
// }
|
||
|
//
|
||
|
// m_bbox.SetMin( mmin );
|
||
|
// m_bbox.SetMax( mmax );
|
||
|
// break;
|
||
|
// }
|
||
|
// default:
|
||
|
// // Do nothing.
|
||
|
// break;
|
||
|
// }
|
||
|
//#ifdef SHORT_VERT
|
||
|
// DCFlushRange( mp_posBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
//#else
|
||
|
// DCFlushRange( mp_posBuffer, 3 * m_num_vertex * sizeof( float ) );
|
||
|
//#endif // SHORT_VERT
|
||
|
// if ( mp_normBuffer ) DCFlushRange( mp_normBuffer, 3 * m_num_vertex * sizeof( s16 ) );
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
} // namespace NxNgc
|
||
|
|
||
|
|
||
|
|
||
|
|