📄 ivp_gridbuild_array.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
#include <ivp_physics.hxx>
#if defined(LINUX)
# include <memory.h>
#endif
#include <ivu_memory.hxx>
#ifndef WIN32
# pragma implementation "ivp_gridbuild_array.hxx"
#endif
#include <ivp_compact_grid.hxx>
#include <ivp_gridbuild_array.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_compact_ledge.hxx>
#include <ivp_compact_ledge_solver.hxx>
IVP_Template_Compact_Grid::IVP_Template_Compact_Grid(){
P_MEM_CLEAR(this);
}
IVP_GridBuilder_Array::IVP_GridBuilder_Array(IVP_U_Memory *mm_, const IVP_Template_Compact_Grid *gp, IVP_FLOAT *height_field_)
{
P_MEM_CLEAR(this);
mm = mm_;
this->height_field = height_field_;
n_rows = gp->row_info.n_points;
n_cols = gp->column_info.n_points;
n_compact_poly_points_used = 0;
height_points = (IVP_Compact_Poly_Point *)mm->get_mem(sizeof(IVP_Compact_Poly_Point) * n_rows * n_cols);
unsigned int buffer_size=sizeof(IVP_Compact_Poly_Point) * n_rows * n_cols * 3;
compact_poly_point_buffer = (IVP_Compact_Poly_Point *)mm->get_mem(buffer_size); // two extra points per square worst case
ledge_reference_field = (IVP_Compact_Grid_Element *)mm->get_memc(sizeof(IVP_Compact_Grid_Element) * n_rows * n_cols); // last row and col not used
grid_point_to_ledge_point_array = (int *) mm->get_mem(sizeof(int) * n_rows * n_cols);
for (int j= n_rows * n_cols -1; j>=0;j--){
grid_point_to_ledge_point_array[j] = -1;
}
IVP_U_Float_Point *dest = &this->height_points[0];
IVP_FLOAT *source = &this->height_field[0];
IVP_DOUBLE x = gp->position_origin_os.k[ gp->row_info.maps_to ];
IVP_DOUBLE dx = (gp->row_info.invert_axis) ? -gp->grid_field_size:gp->grid_field_size;
IVP_DOUBLE dy = (gp->column_info.invert_axis) ? -gp->grid_field_size:gp->grid_field_size;
IVP_DOUBLE dz = (gp->height_invert_axis) ? -1.0f : 1.0f;
for (int r=0; r<n_rows; r++) {
IVP_DOUBLE y = gp->position_origin_os.k[ gp->column_info.maps_to ];
for (int c=0; c<n_cols; c++) {
dest->k[ gp->row_info.maps_to ] = (IVP_FLOAT)x;
dest->k[ gp->column_info.maps_to ] = (IVP_FLOAT)y;
dest->k[ gp->height_maps_to ] = float(source[0] * dz);
source++;
dest++;
IVP_ASSERT( ((int)dest & 15) == 0 );
y += dy;
}
x += dx;
}
templ = gp;
}
int IVP_GridBuilder_Array::install_grid_point(int grid_point_index){
int index = grid_point_to_ledge_point_array[grid_point_index];
if (index >=0) return index;
index = n_compact_poly_points_used++;
grid_point_to_ledge_point_array[grid_point_index] = index;
compact_poly_point_buffer[ index ] = height_points[grid_point_index];
IVP_IF(1) {
IVP_Compact_Poly_Point *cpp=&compact_poly_point_buffer[ index ];
int adress=(int)cpp;
IVP_ASSERT( (adress & 15)==0 );
}
return index;
}
int IVP_GridBuilder_Array::install_point(const IVP_U_Float_Point *point){
int index = n_compact_poly_points_used++;
IVP_IF(1) {
IVP_Compact_Poly_Point *cpp=&compact_poly_point_buffer[ index ];
int adress=(int)cpp;
IVP_ASSERT( (adress & 15)==0 );
}
compact_poly_point_buffer[ index ].set(point);
compact_poly_point_buffer[index].hesse_val = 0.0f;
return index;
}
IVP_GridBuilder_Array::~IVP_GridBuilder_Array(){
//P_FREE(height_points); // memory management system used
//P_FREE(ledge_reference_field);
}
void IVP_GridBuilder_Array::add_triangle(int s_p0_off, int s_p1_off, int s_p2_off,
int opp0, int opp1, int opp2)
{
int p0_off = c_point_to_point_index[s_p0_off];
int p1_off = c_point_to_point_index[s_p1_off];
int p2_off = c_point_to_point_index[s_p2_off];
IVP_Compact_Triangle *tri = &((IVP_Compact_Triangle *)this->c_ledge)[this->triangle_count + 1];
tri->set_tri_index(this->triangle_count++);
tri->c_three_edges[0].set_start_point_index(p0_off);
tri->c_three_edges[1].set_start_point_index(p1_off);
tri->c_three_edges[2].set_start_point_index(p2_off);
tri->c_three_edges[0].set_opposite_index(opp0);
tri->c_three_edges[1].set_opposite_index(opp1);
tri->c_three_edges[2].set_opposite_index(opp2);
IVP_IF(1){
// check for opposite and convexity consistency
int opp[3];
opp[0] = opp0;
opp[1] = opp1;
opp[2] = opp2;
for(int e=0; e<3; e++){
const IVP_Compact_Edge *edge, *oppo;
edge = &tri->c_three_edges[e];
oppo = edge->get_opposite();
if((opp[e] < 0)&&(opp[e] > -1000) && (oppo->get_opposite_index() > -1000)){
IVP_ASSERT(edge==oppo->get_opposite());
// check for convexity
IVP_U_Hesse hesse;
IVP_U_Point p0, p1, p2;
p0.set(edge->get_start_point(c_ledge));
p1.set(edge->get_next()->get_start_point(c_ledge));
p2.set(edge->get_prev()->get_start_point(c_ledge));
hesse.calc_hesse(&p0, &p1, &p2);
IVP_U_Point pp;
pp.set(oppo->get_prev()->get_start_point(c_ledge));
IVP_ASSERT(hesse.get_dist(&pp) >= -0.001f);//- P_RES_EPS);
}
}
}
}
void IVP_GridBuilder_Array::insert_opposite_index( const IVP_Compact_Edge *edge, int index){
((IVP_Compact_Edge *)edge)->set_opposite_index(index);
IVP_IF(1){
const IVP_Compact_Edge *oppo;
oppo = edge->get_opposite();
if (oppo->get_triangle() - c_ledge->get_first_triangle() >= triangle_count) return; // not in list yet
// if((index < 0)&&(index > -1000) && (oppo->get_opposite_index() > -1000)){
IVP_ASSERT(edge==oppo->get_opposite());
// check for convexity
IVP_U_Hesse hesse;
IVP_U_Point p0, p1, p2;
p0.set(edge->get_start_point(c_ledge));
p1.set(edge->get_next()->get_start_point(c_ledge));
p2.set(edge->get_prev()->get_start_point(c_ledge));
hesse.calc_hesse(&p0, &p1, &p2);
IVP_U_Point pp;
pp.set(oppo->get_prev()->get_start_point(c_ledge));
IVP_ASSERT(hesse.get_dist(&pp) >= -1e-12f);
// }
}
}
IVP_Compact_Ledge *IVP_GridBuilder_Array::convert_convex_triangle_to_compact_ledge( int strip_points[] ){
int num_triangles = 2;
//const int n_points = 3;
triangle_count= 0;
// get memory for Ledge Header, Triangles and Points
int mem_size = sizeof(IVP_Compact_Ledge) + num_triangles * sizeof(IVP_Compact_Triangle);
this->c_ledge = (IVP_Compact_Ledge *)mm->get_memc( mem_size);
IVP_ASSERT( (int(this->c_ledge) & 15) == 0); // make sure it is aligned
{ // set point arrays
// search the minimum point index and install points
int min = IVP_GRID_MAX_ROWS * IVP_GRID_MAX_ROWS * 3; // super high number
int max = 0;
for (int i=2;i>=0;i--){
int index = install_grid_point(strip_points[i]);
if (index < min) min = index;
if (index > max) max = index;
c_point_to_point_index[i] = index;
}
// shift start so min gets zero
c_point_to_point_index[0] -= min;
c_point_to_point_index[1] -= min;
c_point_to_point_index[2] -= min;
IVP_ASSERT(max - min + 1 < n_cols * 4 + 2 * n_cols);
this->c_points = &compact_poly_point_buffer[min];
c_ledge->set_offset_ledge_points( (int)((uchar *)c_points - (uchar *)c_ledge) ); // byte offset from 'this' to (ledge) point array
}
c_ledge->set_is_compact( IVP_FALSE);
c_ledge->set_size(mem_size); // <0 indicates a non compact compact ledge
c_ledge->n_triangles = num_triangles;
c_ledge->has_chilren_flag = IVP_FALSE;
// triangles
this->add_triangle(0, 1, 2, 6, 4, 2);
this->add_triangle(0, 2, 1, -2, -4, -6);
// pierce info
IVP_Compact_Triangle *tri = c_ledge->get_first_triangle();
tri->set_pierce_index(1);
tri->get_next_tri()->set_pierce_index(0);
#ifdef DEBUG
IVP_Compact_Ledge_Solver::check_ledge(c_ledge);
#endif
return this->c_ledge;
}
IVP_Compact_Ledge *IVP_GridBuilder_Array::convert_convex_square_to_compact_ledge( int strip_points[], IVP_BOOL is_right_starter){
int num_triangles = 4;
const int n_points = 4;
triangle_count= 0;
// get memory for Ledge Header, Triangles and Points
int mem_size = sizeof(IVP_Compact_Ledge) + num_triangles * sizeof(IVP_Compact_Triangle);
this->c_ledge = (IVP_Compact_Ledge *)mm->get_memc( mem_size);
IVP_ASSERT( (int(this->c_ledge) & 15) == 0); // make sure it is aligned
{ // set point arrays
// search the minimum point index and install points
int min = IVP_GRID_MAX_ROWS * IVP_GRID_MAX_ROWS * 3; // super high number
int max = 0;
for (int i= n_points-1 ;i>=0;i--){
int index = install_grid_point(strip_points[i]);
if (index < min) min = index;
if (index > max) max = index;
c_point_to_point_index[i] = index;
}
// shift start so min gets zero
c_point_to_point_index[0] -= min;
c_point_to_point_index[1] -= min;
c_point_to_point_index[2] -= min;
c_point_to_point_index[3] -= min;
IVP_ASSERT(max - min + 1 < n_cols * 4 + 2 * n_cols);
this->c_points = &compact_poly_point_buffer[min];
c_ledge->set_offset_ledge_points( (int)((uchar *)c_points - (uchar *)c_ledge) ); // byte offset from 'this' to (ledge) point array
}
c_ledge->set_is_compact( IVP_FALSE);
c_ledge->set_size(mem_size);
c_ledge->n_triangles = num_triangles;
c_ledge->has_chilren_flag = IVP_FALSE;
// triangles
int p1 = 1;
int p2 = 2;
if ( is_right_starter ){ // swap points 1 and 2
p1 = 2;
p2 = 1;
}
this->add_triangle(p2, p1, 0, 4, 8, 12);
this->add_triangle(p1, p2, 3, -4, 8, 4);
this->add_triangle( 3, 0, p1, 4, -8, -4);
this->add_triangle( 0, 3, p2, -4, -8, -12);
// pierce info
IVP_Compact_Triangle *tri;
tri = c_ledge->get_first_triangle(); tri->set_pierce_index(2);
tri = tri->get_next_tri(); tri->set_pierce_index(2);
tri = tri->get_next_tri(); tri->set_pierce_index(0);
tri = tri->get_next_tri(); tri->set_pierce_index(0);
#ifdef DEBUG
IVP_Compact_Ledge_Solver::check_ledge(c_ledge);
#endif
return this->c_ledge;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -