📄 ivp_compact_ledge.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
/********************************************************************************
* File: ivp_compact_ledge.cxx
* Description: compacted ledge representation
********************************************************************************/
//#include <string.h>
#include <ivp_physics.hxx>
#include <ivu_hash.hxx>
#ifndef WIN32
# pragma implementation "ivp_compact_ledge.hxx"
#endif
#include <ivp_compact_ledge.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_cache_ledge_point.hxx>
int IVP_Compact_Edge::next_table[] = { 0, 1*int(sizeof(IVP_Compact_Edge)), 1*int(sizeof(IVP_Compact_Edge)), -2*int(sizeof(IVP_Compact_Edge)) };
int IVP_Compact_Edge::prev_table[] = { 0, 2*int(sizeof(IVP_Compact_Edge)), -1*int(sizeof(IVP_Compact_Edge)), -1*int(sizeof(IVP_Compact_Edge)) };
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
IVP_Compact_Edge::IVP_Compact_Edge()
{
start_point_index = 0;
opposite_index = 0;
}
void IVP_Compact_Edge::byte_swap()
{
/*
unsigned int start_point_index:16; // point index
signed int opposite_index:15; // rel to this // maybe extra array, 3 bits more than tri_index/pierce_index
unsigned int is_virtual:1;
*/
// XXX COMPILER SPECIFIC XXX
uint bitfields = *(uint*)(this);
#if defined (__POWERPC__)
#elif defined (WIN32)
uint bitfield0 = (bitfields & 0x0000FFFF) << 16;
uint bitfield1 = (bitfields & 0x7FFF0000) >> 15;
uint bitfield2 = (bitfields & 0x80000000) >> 31;
bitfields = bitfield0 | bitfield1 | bitfield2;
#endif
ivp_byte_swap4( bitfields );
start_point_index = (bitfields & 0x0FFFF);
opposite_index = (bitfields & 0x7FFF0000) >> 16;
is_virtual = (bitfields & 0x80000000) >> 31;
uint sp = start_point_index;
int oi = opposite_index;
uint isv = is_virtual;
}
///////////////////////////////////////////////////////////////////////////////////////
IVP_Compact_Triangle::IVP_Compact_Triangle()
{
P_MEM_CLEAR(this);
}
void IVP_Compact_Triangle::byte_swap()
{
/*
unsigned int tri_index:12; // used for upward navigation
unsigned int pierce_index:12;
unsigned int material_index:7;
unsigned int is_virtual:1;
IVP_Compact_Edge c_three_edges[3];
*/
uint bitfields = *(uint*)(this);
#if defined (__POWERPC__)
#elif defined (WIN32)
uint bitfield0 = (bitfields & 0x00000FFF) << 20;
uint bitfield1 = (bitfields & 0x00FFF000) >> 4;
uint bitfield2 = (bitfields & 0x7F000000) >> 23;
uint bitfield3 = (bitfields & 0x80000000) >> 31;
bitfields = bitfield0 | bitfield1 | bitfield2 | bitfield3;
#endif
ivp_byte_swap4( bitfields );
// XXX VERY POSSIBLY COMPILER SPECIFIC XXX
// Due to different ordering / packing of bitfields
tri_index = bitfields & 0x0FFF;
pierce_index = (bitfields & 0x0FFF000) >> 12 ;
material_index = (bitfields & 0x7F000000) >> 24 ;
is_virtual = (bitfields & 0x80000000) >> 31 ;
uint ti = tri_index;
uint pi = pierce_index;
uint mi = material_index;
uint iv = is_virtual;
c_three_edges[0].byte_swap();
c_three_edges[1].byte_swap();
c_three_edges[2].byte_swap();
}
///////////////////////////////////////////////////////////////////////////////////////
void IVP_Compact_Ledge::c_ledge_init()
{
P_MEM_CLEAR(this);
}
void IVP_Compact_Ledge::byte_swap()
{
/*
int c_point_offset; // byte offset from 'this' to (ledge) point array
union {
int ledgetree_node_offset;
int client_data; // if indicates a non terminal ledge
};
unsigned int has_chilren_flag:2;
IVP_BOOL is_compact_flag:2; // if false than compact ledge uses points outside this piece of memory
unsigned int dummy:4;
unsigned int size_div_16:24;
short n_triangles;
short for_future_use;
*/
ivp_byte_swap4( (uint&) c_point_offset );
ivp_byte_swap4( (uint&) ledgetree_node_offset );
uint bitfields = *(uint*)( &ledgetree_node_offset + 1 ); // as can't get addr of bitfield member..
#if defined (__POWERPC__)
#elif defined (WIN32)
uint bitfield0 = bitfields << 24;
uint bitfield00 = bitfield0 & 0x03000000;
uint bitfield01 = bitfield0 & 0x0c000000;
uint bitfield02 = bitfield0 & 0xf0000000;
bitfield0 = (bitfield00 << 6) | (bitfield01 << 2) | (bitfield02 >> 4);
uint bitfield1 = bitfields >> 8;
bitfields = bitfield0 | bitfield1;
#endif
ivp_byte_swap4( bitfields );
// XXX VERY POSSIBLY COMPILER SPECIFIC XXX
// Due to different ordering / packing of bitfields
has_chilren_flag = (uchar)(bitfields & 0x03);
is_compact_flag = (IVP_BOOL)( (bitfields & 0x0C) >> 2 );
dummy = (uchar)(bitfields & 0x0F0) >> 4;
size_div_16 = (bitfields & 0xFFFFFF00) >> 8;
uchar hasc = has_chilren_flag;
uchar ic = is_compact_flag;
uchar d = dummy;
uint sd = size_div_16;
ivp_byte_swap2( (ushort&) n_triangles );
ivp_byte_swap2( (ushort&) for_future_use );
}
static void ProcessPoint( IVP_Compact_Poly_Point& point, IVP_U_BigVector<IVP_Compact_Poly_Point>* pre_swapped_points)
{
if (pre_swapped_points)
{
int j;
for (j = 0; j < pre_swapped_points->len(); ++j)
{
if ( pre_swapped_points->element_at(j) == &point )
break;
}
if (j == pre_swapped_points->len())
{
pre_swapped_points->add(&point);
point.byte_swap(); // SWAP
// printf("point [ %.4f %.4f %.4f ]\n", point.k[0], point.k[1], point.k[2] );
}
}
else
{
point.byte_swap(); // SWAP
// printf("point [ %.4f %.4f %.4f ]\n", point.k[0], point.k[1], point.k[2] );
}
}
void IVP_Compact_Ledge::byte_swap_all(IVP_U_BigVector<IVP_Compact_Poly_Point>* pre_swapped_points)
{
#if defined (__POWERPC__)
byte_swap();
#endif
// progress into the data:
IVP_Compact_Poly_Point* points = get_point_array();
IVP_Compact_Triangle* triangles = get_first_triangle();
for ( int j = 0; j < n_triangles; ++j)
{
#if defined (__POWERPC__)
triangles[j].byte_swap();
#endif
const int i0 = triangles[j].get_edge(0)->get_start_point_index();
const int i1 = triangles[j].get_edge(1)->get_start_point_index();
const int i2 = triangles[j].get_edge(2)->get_start_point_index();
ProcessPoint( points[i0], pre_swapped_points);
ProcessPoint( points[i1], pre_swapped_points);
ProcessPoint( points[i2], pre_swapped_points);
#if defined (WIN32)
triangles[j].byte_swap();
#endif
}
#if defined (WIN32)
byte_swap();
#endif
}
///////////////////////////////////////////////////////////////////////////////////////
void IVP_Compact_Ledgetree_Node::byte_swap()
{
/*
int offset_right_node; // (if != 0 than children
int offset_compact_ledge; //(if != 0, pointer to hull that contains all subelements
IVP_U_Float_Point3 center; // in object_coords
IVP_FLOAT radius; // size of sphere
uchar box_sizes[IVP_CLT_N_DIRECTIONS];
uchar free_0;
*/
ivp_byte_swap4( (uint&) offset_right_node );
ivp_byte_swap4( (uint&) offset_compact_ledge );
center.byte_swap();
ivp_byte_swap4( (uint&) radius );
// uchars don't need to be byte swapped themselves
}
void IVP_Compact_Ledgetree_Node::byte_swap_all(IVP_U_BigVector<IVP_Compact_Poly_Point>* pre_swapped_points)
{
#if defined (__POWERPC__)
//
// swaps offsets and data, so we can recurse and not crash!!
//
byte_swap();
#endif
// recurse
if (!is_terminal())
{
// left:
const IVP_Compact_Ledgetree_Node* l = left_son(); //returns const only?!
IVP_ASSERT(l);
const_cast<IVP_Compact_Ledgetree_Node*>(l)->byte_swap_all(pre_swapped_points);
// right:
const IVP_Compact_Ledgetree_Node* r = right_son(); //returns const only?!
IVP_ASSERT(r);
const_cast<IVP_Compact_Ledgetree_Node*>(r)->byte_swap_all(pre_swapped_points);
}
#if defined WIN32
//
// just swaps data
//
byte_swap();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -