mirror of
https://github.com/KranX/Vangers.git
synced 2025-11-30 23:15:27 +07:00
3515 lines
89 KiB
C++
3515 lines
89 KiB
C++
#include "../src/global.h"
|
|
|
|
#include "sqint.h"
|
|
|
|
#include "../src/common.h"
|
|
#include "sqexp.h"
|
|
#include "tools.h"
|
|
#include "track.h"
|
|
|
|
#include "impass.h"
|
|
#include "../src/terra/vmap.h"
|
|
#include "../src/terra/world.h"
|
|
#include "../src/terra/render.h"
|
|
|
|
#include "port.h"
|
|
#define itoa port_itoa
|
|
#include "missed.h"
|
|
|
|
//XStream fout( "out.txt", XS_OUT );
|
|
|
|
extern int NodeHeight, NodeSlope;
|
|
extern iGameMap* curGMap;
|
|
extern vrtMap *vMap;
|
|
extern int TrackBuild, TerrainMode;
|
|
extern int ColorBase;
|
|
extern int RenderMode;
|
|
extern int MaterSection;
|
|
extern int WideSection;
|
|
extern int Redraw;
|
|
extern sqFont sysfont;
|
|
|
|
int ColorTable[7] = {COL1,63,127,139,152,175,180};
|
|
int WATERLINE = 16;
|
|
int ROAD_MATERIAL;
|
|
int ROAD_FORCING;
|
|
|
|
int sqTrackBuild;
|
|
int Track_show_all;
|
|
|
|
static int delta = 20;
|
|
|
|
int NoiseLevel,NoiseAmp,ShapeNumber,ShapeAmp;
|
|
|
|
int DeltamH = 0;
|
|
int DeltalH = 0;
|
|
int cPoint = 0;
|
|
int cwBranch = 0;
|
|
int cwPoint = 0;
|
|
int cBranch = 0;
|
|
int cNode = 0;
|
|
|
|
//int UcutLeft,UcutRight,VcutUp,VcutDown;
|
|
|
|
double f0( double t, double );
|
|
double f1( double t, double );
|
|
double f2( double t, double );
|
|
double f3( double t, double );
|
|
double f4( double t, double );
|
|
double f5( double t, double );
|
|
|
|
PF profils[] = {f0, f1, f2, f3, f4, f5};
|
|
eBranch* delBranch = 0;
|
|
eNode* delNode = 0;
|
|
void drawpoly(int* x, int* y, int n, int, int, double, int, int, int, int, int, int, double, int, int);
|
|
void calc_normal_vector( eSection* data, int pos, int& xv, int& yv );
|
|
void set_one_section(int,eBranch*&,int,int ,int,int,int,int,int,int);
|
|
|
|
unsigned realRND(unsigned m);
|
|
|
|
double f0( double t, double d ){
|
|
return 0.0;
|
|
}
|
|
|
|
double f1( double t, double d ){
|
|
if ( t < 1.0/6) return 0.0;
|
|
else if ( t < 1.0/3 ) return -d/2;
|
|
else if ( t < 2.0/3 ) return -d;
|
|
else if ( t < 5.0/6 ) return -d/2;
|
|
else return 0.0;
|
|
}
|
|
|
|
double f2( double t, double d ){
|
|
if ( t < 0.1 ) return 4.0;
|
|
else if ( t < 0.5 ) return d*2.5*( 0.1 - t );
|
|
else if ( t < 0.9 ) return d*2.5*( t - 0.9 );
|
|
else return 0.0;
|
|
}
|
|
|
|
double f3( double t, double d ){
|
|
double z;
|
|
|
|
if ( t < 1.0/3) z = sqrt( 0.17*0.17 - (t-0.17)*(t-0.17) );
|
|
else if ( t < 2.0/3 ) z =-sqrt( 0.17*0.17 - (t-0.5)*(t-0.5) );
|
|
else z = sqrt( 0.17*0.17 - (t-0.83)*(t-0.83) );
|
|
return z*6*d;
|
|
}
|
|
|
|
double f4( double t, double d ){
|
|
double z;
|
|
|
|
if ( t < 0.1 ) z = 0.0;
|
|
else if ( t < 0.9 ) z =-sqrt( 0.4*0.4 - (t-0.5)*(t-0.5) );
|
|
else z = 0.0;
|
|
return z*2.5*d;
|
|
}
|
|
|
|
double f5( double t, double d ){
|
|
if ( t < 0.05 ) return t*20*d;
|
|
if ( t < 0.15 ) return d + (0.05-t)*20*d;
|
|
if ( t < 0.25 ) return d + (t-0.25)*20*d;
|
|
if ( t < 0.35 ) return d + (0.25-t)*20*d;
|
|
if ( t < 0.45 ) return d + (t-0.45)*20*d;
|
|
if ( t < 0.55 ) return d + (0.45-t)*20*d;
|
|
if ( t < 0.65 ) return d + (t-0.65)*20*d;
|
|
if ( t < 0.75 ) return d + (0.65-t)*20*d;
|
|
if ( t < 0.85 ) return d + (t-0.85)*20*d;
|
|
if ( t < 0.95 ) return (1.0-t)*20*d;
|
|
return 0.0;
|
|
}
|
|
|
|
void render_line( int xr, int yr, int xl, int yl, int hh, int what );
|
|
void lline(int x,int y,int len,int color);
|
|
void line( int, int, int, int, int );
|
|
void m_line( int, int, int, int, int );
|
|
|
|
void find_point_on_line( gLine, gLine, int&, int& );
|
|
void spline( eSection*& data_base, rSection* data_all, int i, int n_section, int& n_point );
|
|
|
|
void do_left_buttion_off( int mX, int mY){
|
|
if( Track.check_mouse_work() ) return;
|
|
|
|
switch( TrackBuild ){
|
|
case MOVING_NODE:
|
|
Track.set_node( cNode, 0, mX, mY );
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case MOVING_SECTION:
|
|
Track.set_point_in_branch( cBranch, cPoint, mX, mY, -1 );
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case BUILDING:
|
|
if ( Track.find_node( cNode, mX, mY ) ){
|
|
cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
Track.set_point_in_branch( cBranch, 0, mX, mY, -1 );
|
|
Track.add_branch_to_node( cNode, cBranch );
|
|
Track.build_all_node();
|
|
cNode = 0;
|
|
TrackBuild = WAIT;
|
|
} else if ( Track.find_branch( cBranch, cwBranch, cwPoint, mX, mY ) ) {
|
|
// if ( cBranch != cwBranch ){
|
|
if ( Track.decompose_branch( cwBranch, cwPoint, cNode ) ) {
|
|
cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
Track.set_point_in_branch( cBranch, 0, mX, mY, -1 );
|
|
Track.add_branch_to_node( cNode, cBranch );
|
|
Track.set_node( cNode, 1, mX, mY );
|
|
Track.build_all_node();
|
|
} else {
|
|
cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
Track.set_point_in_branch( cBranch, 0, mX, mY, -1 );
|
|
Track.concate_branch( cwBranch, cBranch );
|
|
}
|
|
TrackBuild = WAIT;
|
|
// } else {
|
|
// cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
// }
|
|
} else {
|
|
cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
}
|
|
break;
|
|
case WAIT :
|
|
if ( Track.find_node( cNode, mX, mY ) ){
|
|
TrackBuild = MOVING_NODE;
|
|
} else if ( Track.find_branch( -1, cBranch, cPoint, mX, mY ) ){
|
|
TrackBuild = MOVING_SECTION;
|
|
} else if ( Track.find_bound_point( cBranch, cPoint, mX, mY ) ){
|
|
TrackBuild = SET_WIDE;
|
|
} else if ( !Track.insert_point_in_branch( mX, mY ) ){
|
|
cBranch = Track.add_branch( mX, mY, cPoint, MIN_WIDE);
|
|
cPoint = 2;
|
|
TrackBuild = BUILDING;
|
|
}
|
|
break;
|
|
case SET_WIDE :
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case SET_HEIGHT :
|
|
Track.get_section_parametr( cBranch, cPoint, NoiseLevel, ShapeNumber, NoiseAmp, ShapeAmp, NodeHeight, NodeSlope, TerrainMode, ColorBase, RenderMode, WideSection, MaterSection);
|
|
cNode = 0;
|
|
sqE -> put(E_TRACKFORM,E_COMMON,XGR_MAXX/2,XGR_MAXY/2);
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case SET_HEIGHT_NODE :
|
|
ShapeNumber = 0;
|
|
ShapeAmp = 0;
|
|
NodeSlope = 0;
|
|
WideSection = 0;
|
|
RenderMode = 0;
|
|
Track.get_node_parametr( cNode, NoiseLevel, NoiseAmp, NodeHeight, ColorBase, MaterSection, TerrainMode);
|
|
cBranch = 0;
|
|
sqE -> put(E_TRACKFORM,E_COMMON,XGR_MAXX/2,XGR_MAXY/2);
|
|
TrackBuild = WAIT;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
void do_right_buttion_off( int mX, int mY){
|
|
if( Track.check_mouse_work() ) return;
|
|
|
|
switch( TrackBuild ){
|
|
case BUILDING:
|
|
Track.set_point_in_branch( cBranch, 0, mX, mY, -1 );
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case MOVING_SECTION:
|
|
if ( Track.decompose_branch( cBranch, cPoint, cNode ) ) {
|
|
cBranch = Track.add_branch( mX, mY, cPoint, MIN_WIDE );
|
|
cPoint = 2;
|
|
Track.add_branch_to_node( cNode, cBranch );
|
|
Track.set_node( cNode, 1, mX, mY );
|
|
Track.build_all_node();
|
|
TrackBuild = BUILDING;
|
|
} else {
|
|
Track.prepare_branch_to_add_point( cBranch, cPoint );
|
|
cPoint = Track.add_point_to_branch( cBranch, mX, mY, MIN_WIDE );
|
|
TrackBuild = BUILDING;
|
|
}
|
|
break;
|
|
case MOVING_NODE:
|
|
cBranch = Track.add_branch( mX, mY, cPoint, MIN_WIDE );
|
|
Track.add_branch_to_node( cNode, cBranch );
|
|
cNode = 0;
|
|
cPoint = 2;
|
|
TrackBuild = BUILDING;
|
|
break;
|
|
case WAIT :
|
|
if ( Track.find_node( cNode, mX, mY ) ){
|
|
if(!Track.delete_node( cNode ) ){
|
|
ShapeNumber = 0;
|
|
ShapeAmp = 0;
|
|
NodeSlope = 0;
|
|
WideSection = 0;
|
|
RenderMode = 0;
|
|
Track.get_node_parametr( cNode, NoiseLevel, NoiseAmp, NodeHeight, ColorBase, MaterSection, TerrainMode );
|
|
Track.show_node_height( cNode );
|
|
cBranch = 0;
|
|
sqTrackBuild = SET_HEIGHT_NODE;
|
|
sqE -> put(E_TRACKFORM,E_COMMON,XGR_MAXX/2,XGR_MAXY/2);
|
|
}
|
|
} else if ( Track.find_branch( -1, cBranch, cPoint, mX, mY ) ){
|
|
Track.delete_point_from_branch( cBranch, cPoint );
|
|
Track.build_all_node();
|
|
} else if ( Track.find_bound_point( cBranch, cPoint, mX, mY ) ){
|
|
Track.get_section_parametr( cBranch, cPoint, NoiseLevel, ShapeNumber, NoiseAmp, ShapeAmp, NodeHeight, NodeSlope, TerrainMode, ColorBase, RenderMode, WideSection, MaterSection);
|
|
cNode = 0;
|
|
Track.show_branch_height( cBranch, cPoint);
|
|
|
|
sqTrackBuild = SET_HEIGHT;
|
|
sqE -> put(E_TRACKFORM,E_COMMON,XGR_MAXX/2,XGR_MAXY/2);
|
|
} else {
|
|
cBranch = Track.insert_point_in_branch( mX, mY );
|
|
if ( cBranch )
|
|
Track.delete_branch( cBranch );
|
|
else
|
|
Track.build_all_node();
|
|
// Track.build_all_spline();
|
|
curGMap -> shift(mX - curGMap -> CX,mY - curGMap -> CY);
|
|
}
|
|
break;
|
|
case SET_WIDE :
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case SET_HEIGHT :
|
|
TrackBuild = WAIT;
|
|
break;
|
|
case SET_HEIGHT_NODE :
|
|
TrackBuild = WAIT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void line( int x1, int y1, int x2, int y2, int color){
|
|
int CX = curGMap -> CX;
|
|
int CY = curGMap -> CY;
|
|
int xc = curGMap -> xc;
|
|
int yc = curGMap -> yc;
|
|
|
|
int xx1, yy1, yy2, xx2;
|
|
|
|
xx1 = ((x1&clip_mask_x) - CX);
|
|
|
|
yy1 = y1 - CY;
|
|
xx2 = ((x2&clip_mask_x) - CX);
|
|
|
|
yy2 = y2 - CY;
|
|
|
|
//int old_x1 = xx1;
|
|
//int old_x2 = xx2;
|
|
|
|
if( xx1 > ((int)clip_mask_x/2) ) xx1 = xx1 - clip_mask_x-1;
|
|
if( xx1 < (-(int)clip_mask_x/2) ) xx1 = xx1 + clip_mask_x+1;
|
|
|
|
if ( xx2 > ((int)clip_mask_x/2) ) xx2 = xx2 - clip_mask_x-1;
|
|
if ( xx2 < (-(int)clip_mask_x/2) ) xx2 = xx2 + clip_mask_x+1;
|
|
|
|
if ( abs( xx1 - xx2 ) < XGR_MAXX )
|
|
m_line( xx1 + xc, yy1 + yc, xx2 + xc, yy2 + yc, color);
|
|
}
|
|
|
|
sTrack::sTrack(void){
|
|
n_node = 0;
|
|
n_branch = 0;
|
|
|
|
node = 0;
|
|
branch = 0;
|
|
|
|
linkingLog = 0;
|
|
nTails = new eNode*[PART_MAX];
|
|
bTails = new eBranch*[PART_MAX];
|
|
}
|
|
|
|
eBranch::eBranch(void){
|
|
index = 0;
|
|
n_section = 0;
|
|
n_point = 0;
|
|
beg_node = 0;
|
|
end_node = 0;
|
|
all_on = 0;
|
|
color = 0;
|
|
material = 2;
|
|
is_render = 1;
|
|
|
|
xpb = new int[3];
|
|
ypb = new int[3];
|
|
xpe = new int[3];
|
|
ype = new int[3];
|
|
|
|
data_base = new eSection[MAX_BASE];
|
|
// data_all = new rSection[MAX_ALL];
|
|
data_all = NULL;
|
|
|
|
l = 0;
|
|
r = 0;
|
|
}
|
|
|
|
eBranch::~eBranch(void){
|
|
delete[] data_base;
|
|
delete[] xpb;
|
|
delete[] ypb;
|
|
delete[] xpe;
|
|
delete[] ype;
|
|
if ( data_all != NULL ) delete[] data_all;
|
|
}
|
|
|
|
|
|
void eBranch::show(int all){
|
|
int i = n_section;
|
|
|
|
if ( beg_node != 0 ){
|
|
line(xpb[1], ypb[1], xpb[0], ypb[0], ColorTable[ color ]);
|
|
line(xpb[1], ypb[1], xpb[2], ypb[2], ColorTable[ color ]);
|
|
line(xpb[2], ypb[2], xpb[0], ypb[0], ColorTable[ color ]);
|
|
}
|
|
|
|
if ( end_node != 0 ){
|
|
i = n_section-1;
|
|
line(xpe[1], ype[1], xpe[0], ype[0], ColorTable[ color ]);
|
|
line(xpe[1], ype[1], xpe[2], ype[2], ColorTable[ color ]);
|
|
line(xpe[2], ype[2], xpe[0], ype[0], ColorTable[ color ]);
|
|
}
|
|
|
|
if (all_on) {
|
|
for( i = 0; i < n_point-1; i++ ){
|
|
line(data_all[i].xl, data_all[i].yl, data_all[i+1].xl, data_all[i+1].yl, ColorTable[ color ]);
|
|
line(data_all[i].xr, data_all[i].yr, data_all[i+1].xr, data_all[i+1].yr, ColorTable[ color ]);
|
|
}
|
|
|
|
// for( i = 0; i < n_point; i++ ){
|
|
// line(data_all[i].x-1, data_all[i].y-1, data_all[i].x+1, data_all[i].y-1, COLOR_TRACK);
|
|
// line(data_all[i].x-1, data_all[i].y, data_all[i].x+1, data_all[i].y, COLOR_TRACK);
|
|
// line(data_all[i].x-1, data_all[i].y+1, data_all[i].x+1, data_all[i].y+1, COLOR_TRACK);
|
|
// }
|
|
} else {
|
|
for( i = 0; i < n_section-1; i++ ){
|
|
line(data_base[i].x, data_base[i].y, data_base[i+1].x, data_base[i+1].y, ColorTable[ color ]);
|
|
if ( (data_base[i].x != data_base[i+1].x) || (data_base[i].y != data_base[i+1].y) ){
|
|
line(data_base[i].xl, data_base[i].yl, data_base[i+1].xl, data_base[i+1].yl, ColorTable[ color ]);
|
|
line(data_base[i].xr, data_base[i].yr, data_base[i+1].xr, data_base[i+1].yr, ColorTable[ color ]);
|
|
|
|
line(data_base[i].xr, data_base[i].yr, data_base[i].xl, data_base[i].yl, ColorTable[ color ]);
|
|
line(data_base[i+1].xr, data_base[i+1].yr, data_base[i+1].xl, data_base[i+1].yl, ColorTable[ color ]);
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
line(data_base[i].x-1, data_base[i].y-1, data_base[i].x+1, data_base[i].y-1, ColorTable[ color ]);
|
|
line(data_base[i].x-1, data_base[i].y, data_base[i].x+1, data_base[i].y, ColorTable[ color ]);
|
|
line(data_base[i].x-1, data_base[i].y+1, data_base[i].x+1, data_base[i].y+1, ColorTable[ color ]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void eNode::show(void){
|
|
line(x-2, y-2, x+2, y-2, ColorTable[ color ]);
|
|
line(x-2, y-1, x+2, y-1, ColorTable[ color ]);
|
|
line(x-2, y, x+2, y, ColorTable[ color ]);
|
|
line(x-2, y+1, x+2, y+1, ColorTable[ color ]);
|
|
line(x-2, y+2, x+2, y+2, ColorTable[ color ]);
|
|
}
|
|
|
|
void sTrack::show(void ){
|
|
int i;
|
|
eBranch* l_branch = branch;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> show(0);
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
eNode* l_node = node;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> show();
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
if ( Track_show_all) show_all_track();
|
|
/*
|
|
if ( TrackBuild == SET_HEIGHT ){
|
|
show_branch_hight( cBranch, cPoint);
|
|
}
|
|
if ( TrackBuild == SET_HEIGHT_NODE ){
|
|
show_node_hight( cNode );
|
|
}
|
|
*/
|
|
}
|
|
|
|
int sTrack::add_branch( int X, int Y, int &pos, int WIDE){
|
|
eBranch* l_branch;
|
|
|
|
if ( n_branch > 0 ){
|
|
n_branch++;
|
|
if ( delBranch != 0 ){
|
|
l_branch = delBranch;
|
|
delBranch = delBranch -> r;
|
|
|
|
l_branch -> end_node = 0;
|
|
l_branch -> beg_node = 0;
|
|
l_branch -> n_section = 0;
|
|
l_branch -> n_point = 0;
|
|
l_branch -> color = 0;
|
|
l_branch -> material = 2;
|
|
l_branch -> is_render = 1;
|
|
} else {
|
|
l_branch = new eBranch;
|
|
l_branch -> index = n_branch;
|
|
}
|
|
|
|
l_branch -> l = branch -> l;
|
|
l_branch -> r = branch;
|
|
l_branch -> l -> r = l_branch;
|
|
branch -> l = l_branch;
|
|
pos = l_branch -> add_section( X, Y, WIDE);
|
|
} else {
|
|
n_branch++;
|
|
if ( delBranch != 0 ){
|
|
branch = delBranch;
|
|
delBranch = delBranch -> r;
|
|
|
|
branch -> end_node = 0;
|
|
branch -> beg_node = 0;
|
|
branch -> n_section = 0;
|
|
branch -> n_point = 0;
|
|
branch -> color = 0;
|
|
branch -> material = 2;
|
|
branch -> is_render = 1;
|
|
} else {
|
|
branch = new eBranch;
|
|
branch -> index = n_branch;
|
|
}
|
|
branch -> l = branch;
|
|
branch -> r = branch;
|
|
l_branch = branch;
|
|
pos = branch -> add_section( X, Y, WIDE);
|
|
}
|
|
return l_branch -> index;
|
|
}
|
|
|
|
int sTrack::add_node( int X, int Y, int H){
|
|
eNode* l_node;
|
|
|
|
if ( n_node > 0 ){
|
|
if ( delNode != 0 ){
|
|
l_node = delNode;
|
|
delNode = delNode -> r;
|
|
l_node -> n_branch = 0;
|
|
l_node -> color = 0;
|
|
l_node -> material = 2;
|
|
l_node -> mode = 0;
|
|
|
|
l_node -> x = X;
|
|
l_node -> y = Y;
|
|
l_node -> h = H;
|
|
|
|
l_node -> polygon_on = 0;
|
|
l_node -> noise = 0;
|
|
l_node -> dnoise = 0;
|
|
n_node++;
|
|
} else {
|
|
n_node++;
|
|
l_node = new eNode( X, Y, H );
|
|
l_node -> index = n_node;
|
|
}
|
|
|
|
l_node -> l = node -> l;
|
|
l_node -> r = node;
|
|
l_node -> l -> r = l_node;
|
|
node -> l = l_node;
|
|
} else {
|
|
n_node++;
|
|
if ( delNode != 0 ){
|
|
node = delNode;
|
|
delNode = delNode -> r;
|
|
node -> n_branch = 0;
|
|
node -> color = 0;
|
|
node -> material = 2;
|
|
node -> mode = 0;
|
|
node -> polygon_on = 0;
|
|
node -> noise = 0;
|
|
node -> dnoise = 0;
|
|
|
|
node -> x = X;
|
|
node -> y = Y;
|
|
node -> h = H;
|
|
} else {
|
|
node = new eNode( X, Y, H );
|
|
node -> index = n_node;
|
|
}
|
|
node -> l = node;
|
|
node -> r = node;
|
|
l_node = node;
|
|
}
|
|
return l_node -> index;
|
|
}
|
|
|
|
void sTrack::add_branch_to_node( int cNode, int cBranch ){
|
|
eBranch* l_branch = branch;
|
|
eNode* l_node = node;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find Branch in add_branch_to_node" );
|
|
i = 0;
|
|
while( l_node -> index != cNode && i < n_node ) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
if( i == n_node ) ErrH.Abort( "Dont Find Node in add_branch_to_node" );
|
|
|
|
if ( abs(l_branch -> data_base[0].x-l_node -> x) < delta && abs(l_branch -> data_base[0].y-l_node -> y) < delta ){
|
|
l_branch -> beg_node = cNode;
|
|
l_node -> add_branch( cBranch );
|
|
} else {
|
|
l_branch -> end_node = cNode;
|
|
l_node -> add_branch( cBranch );
|
|
}
|
|
}
|
|
|
|
int sTrack::add_point_to_branch(int pos, int X, int Y, int WIDE){
|
|
eBranch* l_branch = branch;
|
|
int pos_p;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != pos && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find Branch in add_point_to_" );
|
|
|
|
pos_p = l_branch -> add_section( X, Y, WIDE );
|
|
return pos_p;
|
|
}
|
|
|
|
void sTrack::set_point_in_branch( int pos1, int pos2, int X, int Y, int hh ){
|
|
eBranch* l_branch = branch;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != pos1 && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find Branch in set_point_in" );
|
|
|
|
if ( l_branch -> n_section == 2 && pos2 < 1 )
|
|
delete_branch( pos1 );
|
|
else
|
|
l_branch -> set_section( pos2, X, Y, hh );
|
|
build_all_node();
|
|
}
|
|
|
|
void sTrack::set_node( int cNode, int Mode, int X, int Y){
|
|
int i;
|
|
eNode* l_node = node;
|
|
|
|
i = 0;
|
|
while( l_node -> index != cNode && i < n_node ) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
if( i == n_node ) ErrH.Abort( "Dont Find Node in set_node" );
|
|
|
|
l_node -> polygon_on = 0;
|
|
|
|
if ( Mode )
|
|
for( i = 0; i < l_node -> n_branch; i++ ){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != l_node -> branches[i] ) l_branch = l_branch -> r;
|
|
|
|
if ( l_branch -> beg_node == cNode ) l_branch -> set_section( 1, X, Y, l_node -> h );
|
|
|
|
register int pos = l_branch -> n_section;
|
|
|
|
if ( l_branch -> end_node == cNode ) l_branch -> set_section( pos, X, Y, l_node -> h );
|
|
}
|
|
else
|
|
for( i = 0; i < l_node -> n_branch; i++ ){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != l_node -> branches[i] ) l_branch = l_branch -> r;
|
|
|
|
if ( l_branch -> beg_node == cNode ) l_branch -> set_section( 1, X, Y, -1 );
|
|
|
|
register int pos = l_branch -> n_section;
|
|
|
|
if ( l_branch -> end_node == cNode ) l_branch -> set_section( pos, X, Y, -1 );
|
|
}
|
|
|
|
|
|
l_node -> x = X;
|
|
l_node -> y = Y;
|
|
build_all_node();
|
|
}
|
|
|
|
void sTrack::curr_build(void){
|
|
int mX;
|
|
int mY;
|
|
|
|
int xm = XGR_MouseObj.PosX;
|
|
int ym = XGR_MouseObj.PosY;
|
|
mX = (xm - curGMap -> xc + curGMap -> CX) & clip_mask_x;
|
|
mY = (ym - curGMap -> yc + curGMap -> CY) & clip_mask_y;
|
|
|
|
// Redraw = 1;
|
|
|
|
switch( TrackBuild ){
|
|
case MOVING_NODE:
|
|
set_node( cNode, 0, mX, mY );
|
|
break;
|
|
case MOVING_SECTION :
|
|
case BUILDING:
|
|
set_point_in_branch( cBranch, cPoint, mX, mY, -1 );
|
|
break;
|
|
case WAIT :
|
|
break;
|
|
case SET_HEIGHT:
|
|
break;
|
|
case SET_WIDE:
|
|
set_wide_in_branch( cBranch, cPoint, mX, mY );
|
|
break;
|
|
}
|
|
}
|
|
|
|
int sTrack::find_branch( int cBranch, int& cwBranch, int& cPoint, int& X, int& Y ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
for( i = 0; i < n_branch; i++){
|
|
if ( l_branch -> index != cBranch ){
|
|
if ( l_branch -> find_point( cPoint, X, Y ) ){
|
|
cwBranch = l_branch -> index;
|
|
return 1;
|
|
}
|
|
}
|
|
l_branch = l_branch -> r;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int sTrack::find_node( int& cNode, int& X, int& Y ){
|
|
eNode* l_node = node;
|
|
int i;
|
|
|
|
if ( n_node == 0 ) return 0;
|
|
|
|
for( i = 0; i < n_node; i++){
|
|
if ( l_node -> find_point( X, Y ) ){
|
|
cNode = l_node -> index;
|
|
return 1;
|
|
}
|
|
l_node = l_node -> r;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void sTrack::delete_point_from_branch( int cBranch, int cPoint ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
for( i = 0; i < n_branch; i++){
|
|
if ( l_branch -> index == cBranch ){
|
|
if ( !l_branch -> delete_point( cPoint ) )
|
|
delete_branch( cBranch );
|
|
return;
|
|
}
|
|
l_branch = l_branch -> r;
|
|
}
|
|
build_all_node();
|
|
}
|
|
|
|
int eBranch::add_section( int X, int Y, int WIDE){
|
|
|
|
if (!n_section){
|
|
data_base[n_section].x = X;
|
|
data_base[n_section].y = Y;
|
|
data_base[n_section].h = H_MAIN;
|
|
data_base[n_section].hl = H_MAIN;
|
|
data_base[n_section].hr = H_MAIN;
|
|
data_base[n_section].wide = WIDE;
|
|
data_base[n_section].noise = 0;
|
|
data_base[n_section].dnoise = 0;
|
|
data_base[n_section].profil = 0;
|
|
data_base[n_section].dprofil = 0;
|
|
data_base[n_section].mode = 0;
|
|
data_base[n_section].point = 0;
|
|
n_section+=1;
|
|
}
|
|
|
|
data_base[n_section].x = X;
|
|
data_base[n_section].y = Y;
|
|
data_base[n_section].h = H_MAIN;
|
|
data_base[n_section].hl = H_MAIN;
|
|
data_base[n_section].hr = H_MAIN;
|
|
data_base[n_section].wide = WIDE;
|
|
data_base[n_section].dnoise = 0;
|
|
data_base[n_section].noise = 0;
|
|
data_base[n_section].profil = 0;
|
|
data_base[n_section].dprofil = 0;
|
|
data_base[n_section].mode = 0;
|
|
data_base[n_section].point = 0;
|
|
|
|
n_section+=1;
|
|
if ( n_section == MAX_BASE ) n_section--;
|
|
return n_section;
|
|
}
|
|
|
|
void eBranch::set_section( int pos, int X, int Y, int hh){
|
|
if ( pos == 0 ) {
|
|
n_section--;
|
|
set_wide( n_section );
|
|
} else {
|
|
pos--;
|
|
data_base[pos].x = X;
|
|
data_base[pos].y = Y;
|
|
|
|
if ( hh > 0 ) {
|
|
data_base[pos].hl += hh - data_base[pos].hl;
|
|
data_base[pos].hr += hh - data_base[pos].hr;
|
|
data_base[pos].h = hh;
|
|
}
|
|
|
|
set_wide( pos );
|
|
set_wide( pos+1 );
|
|
set_wide( pos+2 );
|
|
}
|
|
}
|
|
|
|
int eBranch::find_point( int& cPoint, int& X, int& Y){
|
|
int i;
|
|
int _x = X;
|
|
int _y = Y;
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
int dop = 0;
|
|
|
|
if ((data_base[i].x - X) > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
else if ((data_base[i].x - X) < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
_x += dop;
|
|
|
|
dop = 0;
|
|
if ((data_base[i].y - Y) > (int)clip_mask_y) dop = clip_mask_y+1;
|
|
else if ((data_base[i].y - Y) < -(int)clip_mask_y) dop = -((int)clip_mask_y+1);
|
|
|
|
_y += dop;
|
|
|
|
if ( abs(data_base[i].x-_x) < delta && abs(data_base[i].y-_y) < delta ){
|
|
X = data_base[i].x;
|
|
Y = data_base[i].y;
|
|
cPoint = i+1;
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int eBranch::delete_point( int pos){
|
|
int i;
|
|
|
|
if ( n_section < 3 ) return 0;
|
|
|
|
for( i = pos-1; i < n_section-1; i++){
|
|
data_base[i].x = data_base[i+1].x;
|
|
data_base[i].y = data_base[i+1].y;
|
|
data_base[i].h = data_base[i+1].h;
|
|
data_base[i].hl = data_base[i+1].hl;
|
|
data_base[i].hr = data_base[i+1].hr;
|
|
data_base[i].wide = data_base[i+1].wide;
|
|
data_base[i].noise = data_base[i+1].noise;
|
|
data_base[i].dnoise = data_base[i+1].dnoise;
|
|
data_base[i].profil = data_base[i+1].profil;
|
|
data_base[i].dprofil = data_base[i+1].dprofil;
|
|
data_base[i].mode = data_base[i+1].mode;
|
|
}
|
|
n_section--;
|
|
rebuild_wide();
|
|
|
|
return 1;
|
|
}
|
|
|
|
eNode::eNode(int X, int Y, int H){
|
|
index = 0;
|
|
n_branch = 0;
|
|
color = 0;
|
|
material = 2;
|
|
mode = 0;
|
|
|
|
x = X;
|
|
y = Y;
|
|
h = H;
|
|
|
|
xp = new int[MAX_BRANCH];
|
|
yp = new int[MAX_BRANCH];
|
|
branches = new int[MAX_BRANCH];
|
|
|
|
polygon_on = 0;
|
|
noise = 0;
|
|
dnoise = 0;
|
|
l = 0;
|
|
r = 0;
|
|
}
|
|
|
|
eNode::~eNode(void){
|
|
delete[] xp;
|
|
delete[] yp;
|
|
delete[] branches;
|
|
}
|
|
|
|
int eNode::find_point( int& X, int& Y){
|
|
if ( (abs(x-X) < delta) && (abs(y-Y) < delta) ){
|
|
X = x;
|
|
Y = y;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void eNode::add_branch( int cBranch ){
|
|
branches[n_branch] = cBranch;
|
|
n_branch++;
|
|
}
|
|
|
|
void sTrack::concate_branch( int cwBranch, int cBranch ){
|
|
eBranch* lw_branch = branch;
|
|
eBranch* ls_branch = branch;
|
|
int i;
|
|
|
|
if ( cwBranch == cBranch ) return;
|
|
|
|
i = 0;
|
|
while( lw_branch -> index != cwBranch && i < n_branch ) {
|
|
lw_branch = lw_branch -> r;
|
|
i++;
|
|
}
|
|
if ( i == n_branch ) ErrH.Abort( "Dont Find cwBranch .." );
|
|
|
|
i = 0;
|
|
while( ls_branch -> index != cBranch && i < n_branch) {
|
|
ls_branch = ls_branch -> r;
|
|
i++;
|
|
}
|
|
if ( i == n_branch ) ErrH.Abort( "Dont Find cBranch .." );
|
|
|
|
int pos = lw_branch -> n_section-1;
|
|
int pos2 = ls_branch -> n_section-1;
|
|
|
|
if ( abs(lw_branch -> data_base[0].x-ls_branch -> data_base[pos2].x) < 2*delta && abs(lw_branch -> data_base[0].y-ls_branch -> data_base[pos2].y) < 2*delta){
|
|
for( i = 1; i < lw_branch -> n_section; i++ ){
|
|
ls_branch -> data_base[i+pos2].x = lw_branch -> data_base[i].x;
|
|
ls_branch -> data_base[i+pos2].y = lw_branch -> data_base[i].y;
|
|
ls_branch -> data_base[i+pos2].h = lw_branch -> data_base[i].h;
|
|
ls_branch -> data_base[i+pos2].hl = lw_branch -> data_base[i].hl;
|
|
ls_branch -> data_base[i+pos2].hr = lw_branch -> data_base[i].hr;
|
|
ls_branch -> data_base[i+pos2].wide = lw_branch -> data_base[i].wide;
|
|
ls_branch -> data_base[i+pos2].noise = lw_branch -> data_base[i].noise;
|
|
ls_branch -> data_base[i+pos2].dnoise = lw_branch -> data_base[i].dnoise;
|
|
ls_branch -> data_base[i+pos2].profil = lw_branch -> data_base[i].profil;
|
|
ls_branch -> data_base[i+pos2].dprofil = lw_branch -> data_base[i].dprofil;
|
|
ls_branch -> data_base[i+pos2].mode = lw_branch -> data_base[i].mode;
|
|
}
|
|
ls_branch -> n_section += pos;
|
|
|
|
if ( lw_branch -> end_node > 0 ) {
|
|
delete_branch_from_node(lw_branch -> end_node, cwBranch);
|
|
add_branch_to_node( lw_branch -> end_node, cBranch);
|
|
}
|
|
ls_branch -> end_node = lw_branch -> end_node;
|
|
lw_branch -> end_node = 0;
|
|
|
|
delete_branch( cwBranch );
|
|
} else {
|
|
for( i = 1; i <= pos; i++ ){
|
|
ls_branch -> data_base[i+pos2].x = lw_branch -> data_base[pos-i].x;
|
|
ls_branch -> data_base[i+pos2].y = lw_branch -> data_base[pos-i].y;
|
|
ls_branch -> data_base[i+pos2].h = lw_branch -> data_base[pos-i].h;
|
|
ls_branch -> data_base[i+pos2].hl = lw_branch -> data_base[pos-i].hl;
|
|
ls_branch -> data_base[i+pos2].hr = lw_branch -> data_base[pos-i].hr;
|
|
ls_branch -> data_base[i+pos2].wide = lw_branch -> data_base[pos-i].wide;
|
|
ls_branch -> data_base[i+pos2].noise = lw_branch -> data_base[pos-i].noise;
|
|
ls_branch -> data_base[i+pos2].dnoise = lw_branch -> data_base[pos-i].dnoise;
|
|
ls_branch -> data_base[i+pos2].profil = lw_branch -> data_base[pos-i].profil;
|
|
ls_branch -> data_base[i+pos2].dprofil = lw_branch -> data_base[pos-i].dprofil;
|
|
ls_branch -> data_base[i+pos2].mode = lw_branch -> data_base[pos-i].mode;
|
|
}
|
|
ls_branch -> n_section += pos;
|
|
|
|
if ( lw_branch -> beg_node > 0 ) {
|
|
delete_branch_from_node(lw_branch -> beg_node, cwBranch);
|
|
add_branch_to_node( lw_branch -> beg_node, cBranch);
|
|
}
|
|
ls_branch -> end_node = lw_branch -> beg_node;
|
|
lw_branch -> beg_node = 0;
|
|
|
|
delete_branch( cwBranch );
|
|
}
|
|
ls_branch -> rebuild_wide();
|
|
}
|
|
|
|
int sTrack::decompose_branch( int cwBranch, int cwPoint, int& cNode ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
int pos, loc;
|
|
|
|
i = 0;
|
|
while( l_branch -> index != cwBranch && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if ( i == n_branch ) ErrH.Abort( "Dont find branch in decompose_branch" );
|
|
|
|
if ( (cwPoint == 1) || (cwPoint == l_branch -> n_section) ) return 0;
|
|
|
|
loc = add_branch( l_branch -> data_base[cwPoint-1].x, l_branch -> data_base[cwPoint-1].y, pos, l_branch -> data_base[cwPoint-1].wide );
|
|
|
|
eBranch* lw_branch = branch;
|
|
i = 0;
|
|
while( lw_branch -> index != loc && i < n_branch ) {
|
|
lw_branch = lw_branch -> r;
|
|
i++;
|
|
}
|
|
if ( i == n_branch ) ErrH.Abort( "Dont find newbranch in decompose_branch" );
|
|
lw_branch -> color = l_branch -> color;
|
|
|
|
pos = 0;
|
|
for( i = cwPoint-1; i < l_branch -> n_section; i++, pos++ ){
|
|
lw_branch -> data_base[pos].x = l_branch -> data_base[i].x;
|
|
lw_branch -> data_base[pos].y = l_branch -> data_base[i].y;
|
|
lw_branch -> data_base[pos].h = l_branch -> data_base[i].h;
|
|
lw_branch -> data_base[pos].xr = l_branch -> data_base[i].xr;
|
|
lw_branch -> data_base[pos].yr = l_branch -> data_base[i].yr;
|
|
lw_branch -> data_base[pos].hr = l_branch -> data_base[i].hr;
|
|
lw_branch -> data_base[pos].xl = l_branch -> data_base[i].xl;
|
|
lw_branch -> data_base[pos].yl = l_branch -> data_base[i].yl;
|
|
lw_branch -> data_base[pos].hl = l_branch -> data_base[i].hl;
|
|
lw_branch -> data_base[pos].wide = l_branch -> data_base[i].wide;
|
|
lw_branch -> data_base[pos].profil = l_branch -> data_base[i].profil;
|
|
lw_branch -> data_base[pos].dprofil = l_branch -> data_base[i].dprofil;
|
|
lw_branch -> data_base[pos].noise = l_branch -> data_base[i].noise;
|
|
lw_branch -> data_base[pos].dnoise = l_branch -> data_base[i].dnoise;
|
|
lw_branch -> data_base[pos].mode = l_branch -> data_base[i].mode;
|
|
}
|
|
|
|
lw_branch -> n_section = pos;
|
|
l_branch -> n_section = cwPoint;
|
|
|
|
cNode = add_node( l_branch -> data_base[cwPoint-1].x, l_branch -> data_base[cwPoint-1].y, l_branch -> data_base[cwPoint-1].h );
|
|
|
|
if (l_branch -> end_node > 0){
|
|
delete_branch_from_node(l_branch -> end_node, cwBranch);
|
|
add_branch_to_node( l_branch -> end_node, loc);
|
|
l_branch -> end_node = 0;
|
|
}
|
|
|
|
add_branch_to_node( cNode, loc );
|
|
add_branch_to_node( cNode, cwBranch );
|
|
|
|
return 1;
|
|
}
|
|
|
|
void sTrack::delete_branch_from_node( int cNode, int cBranch ){
|
|
eNode* l_node = node;
|
|
int i;
|
|
|
|
if ( n_node == 0 ) return;
|
|
|
|
if ( cNode <= 0 ) return;
|
|
|
|
i = 0;
|
|
while( l_node -> index != cNode && i < n_node) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
if( i == n_node ) ErrH.Abort( "Dont Find Node in delete branch.." );
|
|
|
|
for( i = 0; l_node -> branches[i] != cBranch && i < l_node -> n_branch; i++ );
|
|
|
|
if( i == l_node -> n_branch ) ErrH.Abort( "Dont Find Branch in Node" );
|
|
|
|
l_node -> n_branch--;
|
|
for(; i < l_node -> n_branch; i++ )
|
|
l_node -> branches[i] = l_node -> branches[i+1];
|
|
build_all_node();
|
|
}
|
|
|
|
void sTrack::delete_branch( int cwBranch ){
|
|
eBranch* l_branch = branch;
|
|
|
|
if ( cwBranch < 1 ) ErrH.Abort( "Error in struct Track" );
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cwBranch && i < n_branch) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find deleted Branch" );
|
|
|
|
delete_branch_from_node( l_branch -> beg_node, cwBranch );
|
|
l_branch -> beg_node = 0;
|
|
delete_branch_from_node( l_branch -> end_node, cwBranch );
|
|
l_branch -> end_node = 0;
|
|
|
|
l_branch -> r -> l = l_branch -> l;
|
|
l_branch -> l -> r = l_branch -> r;
|
|
|
|
if (delBranch != 0){
|
|
l_branch -> r = delBranch;
|
|
delBranch = l_branch;
|
|
} else {
|
|
delBranch = l_branch;
|
|
delBranch -> r = 0;
|
|
}
|
|
branch = l_branch -> l;
|
|
n_branch--;
|
|
if(n_branch == 0) branch = 0;
|
|
build_all_node();
|
|
}
|
|
|
|
int sTrack::delete_node( int cNode ){
|
|
eNode* l_node = node;
|
|
eBranch* l_branch = branch;
|
|
|
|
if ( cNode < 1 ) ErrH.Abort("Error in struct Node" );
|
|
|
|
int i = 0;
|
|
while( l_node -> index != cNode && i < n_node ) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_node ) ErrH.Abort( " Dont Find Node" );
|
|
|
|
if ( l_node -> n_branch > 2 )
|
|
return 0;
|
|
else if ( l_node -> n_branch == 2 ) {
|
|
prepare_branch_concate( l_node -> branches[0], cNode );
|
|
concate_branch( l_node -> branches[1], l_node -> branches[0] );
|
|
} else if ( l_node -> n_branch == 1 ){
|
|
|
|
i = 0;
|
|
while( l_branch -> index != l_node -> branches[0] && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_branch ) ErrH.Abort( " Dont Find branch for Node.." );
|
|
|
|
if ( l_branch -> beg_node == cNode ) l_branch -> beg_node = 0;
|
|
if ( l_branch -> end_node == cNode ) l_branch -> end_node = 0;
|
|
}
|
|
|
|
l_node -> r -> l = l_node -> l;
|
|
l_node -> l -> r = l_node -> r;
|
|
|
|
node = l_node -> l;
|
|
|
|
if (delNode != 0){
|
|
l_node -> r = delNode;
|
|
delNode = l_node;
|
|
} else {
|
|
delNode = l_node;
|
|
delNode -> r = 0;
|
|
}
|
|
|
|
n_node--;
|
|
if ( n_node == 0 ) node = 0;
|
|
build_all_node();
|
|
return 1;
|
|
}
|
|
|
|
void sTrack::prepare_branch_to_add_point( int cBranch, int cPoint ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
if ( cPoint != 1 ) return;
|
|
|
|
while( l_branch -> index != cBranch ) l_branch = l_branch -> r;
|
|
|
|
int pos = l_branch -> n_section-1;
|
|
for( i = 0; i < l_branch -> n_section/2; i++ ){
|
|
register int tmp = l_branch -> data_base[i].x;
|
|
l_branch -> data_base[i].x = l_branch -> data_base[pos-i].x;
|
|
l_branch -> data_base[pos-i].x = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].y;
|
|
l_branch -> data_base[i].y = l_branch -> data_base[pos-i].y;
|
|
l_branch -> data_base[pos-i].y = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].h;
|
|
l_branch -> data_base[i].h = l_branch -> data_base[pos-i].h;
|
|
l_branch -> data_base[pos-i].h = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].hl;
|
|
l_branch -> data_base[i].hl = l_branch -> data_base[pos-i].hr;
|
|
l_branch -> data_base[pos-i].hr = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].hr;
|
|
l_branch -> data_base[i].hr = l_branch -> data_base[pos-i].hl;
|
|
l_branch -> data_base[pos-i].hl = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].wide;
|
|
l_branch -> data_base[i].wide = l_branch -> data_base[pos-i].wide;
|
|
l_branch -> data_base[pos-i].wide = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].noise;
|
|
l_branch -> data_base[i].noise = l_branch -> data_base[pos-i].noise;
|
|
l_branch -> data_base[pos-i].noise = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].dnoise;
|
|
l_branch -> data_base[i].dnoise = l_branch -> data_base[pos-i].dnoise;
|
|
l_branch -> data_base[pos-i].dnoise = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].profil;
|
|
l_branch -> data_base[i].profil = l_branch -> data_base[pos-i].profil;
|
|
l_branch -> data_base[pos-i].profil = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].dprofil;
|
|
l_branch -> data_base[i].dprofil = l_branch -> data_base[pos-i].dprofil;
|
|
l_branch -> data_base[pos-i].dprofil = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].mode;
|
|
l_branch -> data_base[i].mode = l_branch -> data_base[pos-i].mode;
|
|
l_branch -> data_base[pos-i].mode = tmp;
|
|
}
|
|
register int tmp = l_branch -> end_node;
|
|
l_branch -> end_node = l_branch -> beg_node;
|
|
l_branch -> beg_node = tmp;
|
|
|
|
l_branch -> rebuild_wide();
|
|
}
|
|
|
|
void sTrack::prepare_branch_concate( int cBranch, int cNode ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
if ( cNode < 1 ) ErrH.Abort( "This Node dont exist" );
|
|
|
|
i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch ) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_branch ) ErrH.Abort( "Dont Find Branch" );
|
|
|
|
if ( cNode == l_branch -> end_node ) return;
|
|
if ( cNode != l_branch -> beg_node ) ErrH.Abort( "Error in Struct" );
|
|
|
|
int pos = l_branch -> n_section-1;
|
|
for( i = 0; i < l_branch -> n_section/2; i++ ){
|
|
int tmp = l_branch -> data_base[i].x;
|
|
l_branch -> data_base[i].x = l_branch -> data_base[pos-i].x;
|
|
l_branch -> data_base[pos-i].x = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].y;
|
|
l_branch -> data_base[i].y = l_branch -> data_base[pos-i].y;
|
|
l_branch -> data_base[pos-i].y = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].h;
|
|
l_branch -> data_base[i].h = l_branch -> data_base[pos-i].h;
|
|
l_branch -> data_base[pos-i].h = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].hl;
|
|
l_branch -> data_base[i].hl = l_branch -> data_base[pos-i].hl;
|
|
l_branch -> data_base[pos-i].hl = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].hr;
|
|
l_branch -> data_base[i].hr = l_branch -> data_base[pos-i].hr;
|
|
l_branch -> data_base[pos-i].hr = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].wide;
|
|
l_branch -> data_base[i].wide = l_branch -> data_base[pos-i].wide;
|
|
l_branch -> data_base[pos-i].wide = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].noise;
|
|
l_branch -> data_base[i].noise = l_branch -> data_base[pos-i].noise;
|
|
l_branch -> data_base[pos-i].noise = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].dnoise;
|
|
l_branch -> data_base[i].dnoise = l_branch -> data_base[pos-i].dnoise;
|
|
l_branch -> data_base[pos-i].dnoise = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].profil;
|
|
l_branch -> data_base[i].profil = l_branch -> data_base[pos-i].profil;
|
|
l_branch -> data_base[pos-i].profil = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].dprofil;
|
|
l_branch -> data_base[i].dprofil = l_branch -> data_base[pos-i].dprofil;
|
|
l_branch -> data_base[pos-i].dprofil = tmp;
|
|
|
|
tmp = l_branch -> data_base[i].mode;
|
|
l_branch -> data_base[i].mode = l_branch -> data_base[pos-i].mode;
|
|
l_branch -> data_base[pos-i].mode = tmp;
|
|
}
|
|
int itmp = l_branch -> end_node;
|
|
l_branch -> end_node = l_branch -> beg_node;
|
|
l_branch -> beg_node = itmp;
|
|
|
|
l_branch -> rebuild_wide();
|
|
}
|
|
|
|
int sTrack::insert_point_in_branch( int X, int Y ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
for( i = 0; i < n_branch; i++){
|
|
if ( l_branch -> insert_point( X, Y ) ){
|
|
l_branch -> rebuild_wide();
|
|
return l_branch -> index;
|
|
}
|
|
l_branch = l_branch -> r;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int eBranch::insert_point( int X, int Y ){
|
|
int i;
|
|
|
|
for( i = 0; i < n_section-1; i++ ){
|
|
int minx;
|
|
int miny;
|
|
int maxx;
|
|
int maxy;
|
|
|
|
int x1 = data_base[i].x;
|
|
int x2 = data_base[i+1].x;
|
|
|
|
int y1 = data_base[i].y;
|
|
int y2 = data_base[i+1].y;
|
|
|
|
int dop = 0;
|
|
|
|
if (x1 - x2 > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
else if (x1 - x2 < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
x2 += dop;
|
|
dop = 0;
|
|
|
|
if (x1 - X > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
else if (x1 - X < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
X += dop;
|
|
|
|
if ( x1 > x2 ){
|
|
maxx = x1;
|
|
minx = x2;
|
|
} else {
|
|
maxx = x2;
|
|
minx = x1;
|
|
}
|
|
|
|
if ( y1 > y2 ){
|
|
maxy = y1;
|
|
miny = y2;
|
|
} else {
|
|
maxy = y2;
|
|
miny = y1;
|
|
}
|
|
|
|
if ( (minx-delta) <= X && (maxx+delta) >= X && (miny-delta) <= Y && (maxy+delta) >= Y ){
|
|
int yy = 0;
|
|
|
|
if ( abs(x2-x1) > delta )
|
|
yy = (int)(y1 + double((X - x1)*( y2 - y1))/( x2 - x1));
|
|
else
|
|
yy = Y;
|
|
|
|
if ( abs(yy - Y) < delta ) {
|
|
int j;
|
|
for( j = n_section; j > i+1; j-- ){
|
|
data_base[j].x = data_base[j-1].x;
|
|
data_base[j].y = data_base[j-1].y;
|
|
data_base[j].h = data_base[j-1].h;
|
|
data_base[j].hl = data_base[j-1].hl;
|
|
data_base[j].hr = data_base[j-1].hr;
|
|
data_base[j].wide = data_base[j-1].wide;
|
|
data_base[j].noise = data_base[j-1].noise;
|
|
data_base[j].dnoise = data_base[j-1].dnoise;
|
|
data_base[j].profil = data_base[j-1].profil;
|
|
data_base[j].dprofil = data_base[j-1].dprofil;
|
|
data_base[j].mode = data_base[j-1].mode;
|
|
}
|
|
data_base[i+1].x = X&clip_mask_x;
|
|
data_base[i+1].y = Y;
|
|
data_base[i+1].h = H_MAIN;
|
|
data_base[i+1].hl = H_MAIN;
|
|
data_base[i+1].hr = H_MAIN;
|
|
data_base[i+1].wide = MIN_WIDE;
|
|
data_base[i+1].noise = 0;
|
|
data_base[i+1].dnoise = 0;
|
|
data_base[i+1].profil = 0;
|
|
data_base[i+1].dprofil = 0;
|
|
data_base[i+1].mode = 0;
|
|
n_section++;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
} // end for
|
|
return 0;
|
|
}
|
|
|
|
void calc_normal_vector( eSection* data, int pos, int& xv, int& yv ){
|
|
int dop = 0;
|
|
|
|
if (data[pos-1].x - data[pos].x + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (data[pos-1].x - data[pos].x - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
xv = data[pos].y - data[pos-1].y;
|
|
yv = data[pos-1].x - data[pos].x - dop;
|
|
}
|
|
|
|
void eBranch::set_wide( int pos ){
|
|
int xv, yv;
|
|
double len;
|
|
|
|
if ( pos < 1 || pos > n_section ) return;
|
|
|
|
if ( pos == n_section ) {
|
|
pos--;
|
|
calc_normal_vector( data_base, pos, xv, yv);
|
|
|
|
len = sqrt((double)yv*yv + xv*xv);
|
|
if ( len == 0 ) return;
|
|
|
|
xv = (int)(double(xv*data_base[pos].wide)/len);
|
|
yv = (int)(double(yv*data_base[pos].wide)/len);
|
|
|
|
data_base[pos].xr = data_base[pos].x + xv;
|
|
data_base[pos].yr = data_base[pos].y + yv;
|
|
|
|
data_base[pos].xl = data_base[pos].x - xv;
|
|
data_base[pos].yl = data_base[pos].y - yv;
|
|
} else if ( pos == 1 ) {
|
|
pos--;
|
|
calc_normal_vector( data_base, pos+1, xv, yv);
|
|
|
|
len = sqrt((double)yv*yv + xv*xv);
|
|
if ( len == 0 ) return;
|
|
|
|
xv = (int)(double(xv*data_base[pos].wide)/len);
|
|
yv = (int)(double(yv*data_base[pos].wide)/len);
|
|
|
|
data_base[pos].xr = data_base[pos].x + xv;
|
|
data_base[pos].yr = data_base[pos].y + yv;
|
|
|
|
data_base[pos].xl = data_base[pos].x - xv;
|
|
data_base[pos].yl = data_base[pos].y - yv;
|
|
} else {
|
|
int xx, yy;
|
|
pos--;
|
|
calc_normal_vector( data_base, pos, xv, yv);
|
|
|
|
calc_normal_vector( data_base, pos+1, xx, yy);
|
|
xv += xx;
|
|
yv += yy;
|
|
|
|
len = sqrt((double)yv*yv + xv*xv);
|
|
if ( len == 0 ) return;
|
|
|
|
xv = (int)(double(xv*data_base[pos].wide)/len);
|
|
yv = (int)(double(yv*data_base[pos].wide)/len);
|
|
|
|
data_base[pos].xr = data_base[pos].x + xv;
|
|
data_base[pos].yr = data_base[pos].y + yv;
|
|
|
|
data_base[pos].xl = data_base[pos].x - xv;
|
|
data_base[pos].yl = data_base[pos].y - yv;
|
|
}
|
|
}
|
|
|
|
void eBranch::rebuild_wide( void ){
|
|
int i;
|
|
|
|
for( i = 1; i <= n_section; i++ ) set_wide( i );
|
|
}
|
|
|
|
void sTrack::build_all_node( void ){
|
|
int i;
|
|
eNode* l_node = node;
|
|
eBranch* l_branch = branch;
|
|
int* s;
|
|
|
|
s = new int[MAX_BRANCH];
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> rebuild_wide();
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> build_polygon( branch, s, 0 );
|
|
l_node = l_node -> r;
|
|
}
|
|
delete[] s;
|
|
build_all_branch();
|
|
}
|
|
|
|
void eNode::build_polygon( eBranch*& branch, int*& s, int what ){
|
|
int i, j;
|
|
double a[MAX_BRANCH];
|
|
|
|
if ( n_branch < 3 ) return;
|
|
|
|
polygon_on = 1;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
a[i] = get_alpha( branch, branches[i] );
|
|
s[i] = branches[i];
|
|
}
|
|
|
|
// Построение обхода путей s[i]
|
|
|
|
for( i = 0; i < n_branch-1; i++ ){
|
|
for( j = i+1; j < n_branch; j++ )
|
|
if ( a[j] < a[i] ) {
|
|
double tmp = a[i];
|
|
a[i] = a[j];
|
|
a[j] = tmp;
|
|
|
|
register int t = s[i];
|
|
s[i] = s[j];
|
|
s[j] = t;
|
|
} // end if
|
|
} // end for
|
|
|
|
if ( what ) return;
|
|
|
|
for( i = 0; i < n_branch-1; i++ ){
|
|
find_cross_point( branch, s[i], s[i+1], i );
|
|
}
|
|
find_cross_point( branch, s[i], s[0], i );
|
|
}
|
|
|
|
double eNode::get_alpha( eBranch *branch, int cBranch ){
|
|
int xx = 0, yy = 0;
|
|
int dop = 0;
|
|
|
|
while( branch -> index != cBranch ) branch = branch -> r;
|
|
|
|
if ( branch -> beg_node == index ){
|
|
dop = 0;
|
|
|
|
if (x - branch -> data_base[1].x + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (x - branch -> data_base[1].x - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
xx = branch -> data_base[1].x - x + dop;
|
|
yy = branch -> data_base[1].y - y;
|
|
} else if ( branch -> end_node == index ){
|
|
register int pos = branch -> n_section-2;
|
|
dop = 0;
|
|
|
|
if (x - branch -> data_base[pos].x + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (x - branch -> data_base[pos].x - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
xx = branch -> data_base[pos].x - x + dop;
|
|
yy = branch -> data_base[pos].y - y;
|
|
} else ErrH.Abort( "Error in node." );
|
|
|
|
return atan2((double)yy,(double)xx);
|
|
}
|
|
|
|
void eNode::find_cross_point( eBranch*& branch, int ls, int rs, int pos ){
|
|
eBranch* l_br = branch;
|
|
eBranch* r_br = branch;
|
|
gLine ll, rl;
|
|
int xx, yy;
|
|
int dop;
|
|
|
|
while( l_br -> index != ls ) l_br = l_br -> r;
|
|
while( r_br -> index != rs ) r_br = r_br -> r;
|
|
|
|
if ( l_br -> beg_node == index ){
|
|
calc_normal_vector( l_br -> data_base, 1, xx, yy);
|
|
|
|
ll.x = l_br -> data_base[0].xl;
|
|
ll.y = l_br -> data_base[0].yl;
|
|
} else {
|
|
register int p = l_br -> n_section-1;
|
|
|
|
calc_normal_vector( l_br -> data_base, p, xx, yy);
|
|
|
|
ll.x = l_br -> data_base[p].xr;
|
|
ll.y = l_br -> data_base[p].yr;
|
|
}
|
|
dop = 0;
|
|
|
|
if (x - ll.x + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (x - ll.x - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
ll.x += dop;
|
|
|
|
ll.a = -yy;
|
|
ll.b = xx;
|
|
|
|
if ( r_br -> beg_node == index ){
|
|
calc_normal_vector( r_br -> data_base, 1, xx, yy);
|
|
|
|
rl.x = r_br -> data_base[0].xr;
|
|
rl.y = r_br -> data_base[0].yr;
|
|
} else {
|
|
register int p = r_br -> n_section-1;
|
|
calc_normal_vector( r_br -> data_base, p, xx, yy);
|
|
|
|
rl.x = r_br -> data_base[p].xl;
|
|
rl.y = r_br -> data_base[p].yl;
|
|
}
|
|
dop = 0;
|
|
|
|
if (x - rl.x + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (x - rl.x - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
rl.x += dop;
|
|
|
|
rl.a = -yy;
|
|
rl.b = xx;
|
|
|
|
find_point_on_line( ll, rl, xx, yy );
|
|
|
|
if ( l_br -> beg_node == index ){
|
|
dop = 0;
|
|
|
|
if (xx - l_br -> data_base[0].xl + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (xx - l_br -> data_base[0].xl - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
l_br -> data_base[0].xl = xx - dop;
|
|
l_br -> data_base[0].yl = yy;
|
|
} else {
|
|
register int p = l_br -> n_section-1;
|
|
dop = 0;
|
|
|
|
if (xx - l_br -> data_base[p].xr + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (xx - l_br -> data_base[p].xr - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
l_br -> data_base[p].xr = xx - dop;
|
|
l_br -> data_base[p].yr = yy;
|
|
}
|
|
|
|
if ( r_br -> beg_node == index ){
|
|
dop = 0;
|
|
|
|
if (xx - r_br -> data_base[0].xr + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (xx - r_br -> data_base[0].xr - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
r_br -> data_base[0].xr = xx - dop;
|
|
r_br -> data_base[0].yr = yy;
|
|
} else {
|
|
register int p = r_br -> n_section-1;
|
|
dop = 0;
|
|
|
|
if (xx - r_br -> data_base[p].xl + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (xx - r_br -> data_base[p].xl - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
r_br -> data_base[p].xl = xx - dop;
|
|
r_br -> data_base[p].yl = yy;
|
|
}
|
|
|
|
xp[pos] = xx;
|
|
yp[pos] = yy;
|
|
}
|
|
|
|
void sTrack::render( int what )
|
|
{
|
|
set_height_from_ground(what);
|
|
|
|
build_all_spline();
|
|
// save(0);
|
|
saveKron(0);
|
|
|
|
if(linkingLog){
|
|
int i,j = ((curGMap -> CY - curGMap -> yside) & clip_mask_y) >> WPART_POWER;
|
|
int m = ((((curGMap -> CY + curGMap -> yside) & clip_mask_y) >> WPART_POWER) + 1) & (PART_MAX - 1);
|
|
eNode* l_node = node;
|
|
eBranch* l_branch = branch;
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> builded = 0;
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> builded = 0;
|
|
l_node = l_node -> r;
|
|
}
|
|
for(;j != m;j = (j + 1) & (PART_MAX - 1)){
|
|
l_branch = bTails[j];
|
|
while(l_branch){
|
|
if(!l_branch -> builded){
|
|
l_branch -> render(what);
|
|
l_branch -> builded = 1;
|
|
}
|
|
l_branch = l_branch -> next;
|
|
}
|
|
l_node = nTails[j];
|
|
while(l_node){
|
|
if(!l_node -> builded){
|
|
l_node -> render(what);
|
|
l_node -> builded = 1;
|
|
}
|
|
l_node = l_node -> next;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
int i;
|
|
eNode* l_node = node;
|
|
eBranch* l_branch = branch;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> render( what );
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> render( what );
|
|
l_node = l_node -> r;
|
|
}
|
|
}
|
|
}
|
|
|
|
void eNode::render( int what ){
|
|
int is_render = 0;
|
|
int i;
|
|
|
|
eBranch *l_branch = Track.branch;
|
|
|
|
for ( i = 0; i < n_branch; i++){
|
|
|
|
while ( l_branch -> index != branches[i] ) l_branch = l_branch -> r;
|
|
is_render |= l_branch -> is_render;
|
|
}
|
|
|
|
if ( !is_render ) return;
|
|
|
|
if ( polygon_on )
|
|
drawpoly( xp, yp, n_branch, h, h, 0.0, 0, 0, noise, dnoise, 0, what, 0.0, material, mode);
|
|
}
|
|
|
|
void eBranch::render( int what ){
|
|
int i,j;
|
|
int k;
|
|
int n;
|
|
int noise;
|
|
int dnoise;
|
|
int Amp;
|
|
int x[4];
|
|
int y[4];
|
|
int lhl,lhr;
|
|
double d_mode,t,t1;
|
|
int mode1,mode2;
|
|
|
|
if ( !is_render ) return;
|
|
|
|
i = 0;
|
|
rSection* ps = data_all;
|
|
eSection* pe = data_base;
|
|
eSection* pe1 = data_base + 1;
|
|
for(j = 0;j < n_section - 1;j++,pe++,pe1++){
|
|
n = pe -> point;
|
|
for(k = 0;k < n;i++,k++){
|
|
if ( i >= n_point ) ErrH.Abort( " Out n_point" );
|
|
|
|
lhl = ps -> hl;
|
|
lhr = ps -> hr;
|
|
|
|
x[0] = ps -> xr;
|
|
y[0] = ps -> yr;
|
|
x[3] = ps -> xl;
|
|
y[3] = ps -> yl;
|
|
ps++;
|
|
x[1] = ps -> xr;
|
|
y[1] = ps -> yr;
|
|
x[2] = ps -> xl;
|
|
y[2] = ps -> yl;
|
|
|
|
t = (double)k/n;
|
|
t1 = 1.0 - t;
|
|
|
|
mode1 = pe -> mode%2;
|
|
mode2 = pe1 -> mode%2;
|
|
|
|
if(mode1 != mode2) d_mode = t*mode2 + t1*mode1;
|
|
else d_mode = mode1;
|
|
|
|
noise = round((double)pe -> noise*t1 + (double)pe1 -> noise*t);
|
|
dnoise = round(pe -> dnoise*t1 + pe1 -> dnoise*t);
|
|
Amp = round(pe -> dprofil*t1 + pe1 -> dprofil*t);
|
|
|
|
drawpoly(x,y,4,lhl,lhr,t,pe -> profil,pe1 -> profil,noise,dnoise,Amp,what,d_mode, material, pe -> mode);
|
|
}
|
|
}
|
|
|
|
eNode *l_node = Track.node;
|
|
|
|
if(beg_node){
|
|
while( l_node -> index != beg_node ) l_node = l_node -> r;
|
|
|
|
// drawpoly(xpb,ypb,3,data_base[0].h,data_base[0].h,0.0,0,0,data_base[0].noise,data_base[0].dnoise,0,what,0.0);
|
|
drawpoly(xpb,ypb,3,l_node -> h,l_node -> h,0.0,0,0,l_node -> noise,l_node -> dnoise,0,what,0.0, material, data_base[0].mode);
|
|
}
|
|
|
|
if(end_node){
|
|
int pos = n_section-1;
|
|
while( l_node -> index != end_node ) l_node = l_node -> r;
|
|
|
|
// drawpoly(xpe,ype,3,data_base[pos].h,data_base[pos].h,0.0,0,0,data_base[pos].noise,data_base[pos].dnoise,0,what,0.0);
|
|
drawpoly(xpe,ype,3,l_node -> h, l_node -> h,0.0,0,0,l_node -> noise,l_node -> dnoise,0,what,0.0, material, data_base[pos].mode);
|
|
}
|
|
}
|
|
|
|
void find_point_on_line( gLine ll, gLine rl, int& xx, int& yy ){
|
|
|
|
if ( ll.a*rl.b == ll.b*rl.a ){
|
|
xx = ll.x;
|
|
yy = ll.y;
|
|
} else {
|
|
double t = double((rl.x - ll.x)*rl.b-(rl.y-ll.y)*rl.a)/(ll.a*rl.b-rl.a*ll.b);
|
|
xx = (int)(ll.x + t*ll.a);
|
|
yy = (int)(ll.y + t*ll.b);
|
|
}
|
|
}
|
|
|
|
#define DIVISION_PLUS(a,b,c) if(c) a = (b << 16)/c; else a = (b << 16);
|
|
#define DIVISION_MINUS(a,b,c) if(c) a = -(b << 16)/c; else a = -(b << 16);
|
|
|
|
void lline(int x,int y,int len,int color)
|
|
{
|
|
// if(y < VcutUp || y >= VcutDown) return;
|
|
// int xx = x + len - 1;
|
|
// if(xx < UcutLeft || x >= UcutRight) return;
|
|
// if(x < UcutLeft){
|
|
// len -= UcutLeft - x;
|
|
// x = UcutLeft;
|
|
// }
|
|
// if(xx >= UcutRight)
|
|
// len -= xx - UcutRight + 1;
|
|
int CX = curGMap -> CX;
|
|
int CY = curGMap -> CY;
|
|
int xc = curGMap -> xc;
|
|
int yc = curGMap -> yc;
|
|
|
|
XGR_LineTo(x+xc-CX, y+yc-CY, len+1, 2, color);
|
|
}
|
|
|
|
void drawpoly(int* x, int* y, int n, int hl, int hr, double t, int f1, int f2, int noise, int dnoise, int Amp, int what, double mode, int material, int ter_mode ){
|
|
int xl,xr;
|
|
int kl,kr;
|
|
int al,bl,ar,br;
|
|
int d;
|
|
int where;
|
|
int Y;
|
|
|
|
int minX = map_size_x,maxX = 0;
|
|
int minY = map_size_y,maxY = 0;
|
|
int* p = y;
|
|
register int i,j;
|
|
for(i = 0;i < n;i++){
|
|
j = *p++;
|
|
if(j > maxY) maxY = j;
|
|
if(j < minY) minY = j;
|
|
}
|
|
p = x;
|
|
for(i = 0;i < n;i++){
|
|
j = *p++;
|
|
if(j > maxX) maxX = j;
|
|
if(j < minX) minX = j;
|
|
}
|
|
uchar** lt = vMap -> lineT;
|
|
if((!lt[minY] || !lt[maxY]) && what) return;
|
|
if((maxX < curGMap -> CX - curGMap -> xside || minX > curGMap -> CX + curGMap -> xside) && what) return;
|
|
|
|
if(!what)
|
|
if(!lt[minY] || !lt[maxY])
|
|
vMap -> change(minY,maxY);
|
|
|
|
if(hl <= 1) hl = 2;
|
|
else if(hl >= 254) hl = 253;
|
|
|
|
if(hr <= 1) hr = 2;
|
|
else if(hr >= 254) hr = 253;
|
|
|
|
int lfrom = 0;
|
|
while(y[(lfrom + 1)%n] < y[lfrom])
|
|
lfrom = (lfrom + 1)%n;
|
|
while(y[(lfrom - 1 + n)%n] < y[lfrom])
|
|
lfrom = (lfrom - 1 + n)%n;
|
|
int rfrom = lfrom;
|
|
int lto = (lfrom - 1 + n)%n;
|
|
int rto = (rfrom + 1)%n;
|
|
int rfv = lfrom;
|
|
|
|
Y = y[lfrom];
|
|
|
|
xl = x[lfrom];
|
|
al = x[lto] - xl + 1;
|
|
bl = y[lto] - Y + 1;
|
|
ar = x[rto] - xl + 1;
|
|
br = y[rto] - Y + 1;
|
|
xl = (xl << 16) + (1 << 15);
|
|
xr = xl;
|
|
if(al < 0){
|
|
al = -al;
|
|
DIVISION_MINUS(kl,al,bl)
|
|
}
|
|
else
|
|
DIVISION_PLUS(kl,al,bl)
|
|
if(ar > 0)
|
|
DIVISION_PLUS(kr,ar,br)
|
|
else {
|
|
ar = -ar;
|
|
DIVISION_MINUS(kr,ar,br)
|
|
}
|
|
|
|
int xx = 0,height,max,cx,h;
|
|
uchar fld;
|
|
double tt = 0.0;
|
|
int xll,tmp_h,ii,jj,hh;
|
|
double tmp_t,tmp1,tmp2;
|
|
double t1 = 1.0 - t;
|
|
int cmode = (mode != 0.0) ? 1 : 0;
|
|
int xmode = (hl != hr || f1 || f2) ? 1 : 0;
|
|
uchar* pa,*pf,*pa0;
|
|
uchar* ch = vMap -> changedT + Y;
|
|
|
|
while(1){
|
|
if(bl > br){
|
|
d = br;
|
|
where = 0;
|
|
}
|
|
else {
|
|
d = bl;
|
|
where = 1;
|
|
}
|
|
while(d > 0){
|
|
d--;
|
|
max = ((xr >> 16) - (xl >> 16)) + 1;
|
|
xll = xl >> 16;
|
|
pa0 = lt[Y];
|
|
fld = FloodLvl[Y >> WPART_POWER];
|
|
|
|
for(j = 0,xx = xll;j < max;j++,xx++){
|
|
if(xmode){
|
|
if(n > 3){
|
|
tmp1 = sqrt((double)(x[0] - xx)*(x[0] - xx) + (y[0] - Y)*(y[0] - Y));
|
|
tmp2 = sqrt((double)(x[3] - xx)*(x[3] - xx) + (y[3] - Y)*(y[3] - Y));
|
|
tt = tmp1/(tmp1 + tmp2);
|
|
}
|
|
height = round(hr*tt + hl*(1.0 - tt));
|
|
height += round(profils[f1](tt,Amp)*t1 + profils[f2](tt,Amp)*t);
|
|
|
|
if(cmode){
|
|
tmp_t = (2.0*tt - 1.0);
|
|
tmp_t *= tmp_t;
|
|
|
|
tmp_h = 0;
|
|
// for(ii = -2; ii <= 2; ii++)
|
|
// for(jj = -2; jj <= 2; jj++)
|
|
|
|
for(ii = 0; ii < 5; ii++)
|
|
for(jj = 0; jj < 5; jj++)
|
|
tmp_h += lt[Y + ii][(xx + jj) & clip_mask_x];
|
|
tmp_h /= 25;
|
|
hh = height;
|
|
height = round(height*(1.0 - tmp_t) + tmp_h*tmp_t);
|
|
height = round(hh*(1.0 - mode) + height*mode);
|
|
}
|
|
}
|
|
else
|
|
height = hl;
|
|
if(noise)
|
|
if((int)realRND(100) < noise) height += dnoise - realRND((dnoise << 1) + 1);
|
|
|
|
pa = pa0 + (cx = XCYCL(xx));
|
|
pf = pa + H_SIZE;
|
|
if(!(*pf & DOUBLE_LEVEL) || (cx & 1)){
|
|
h = GET_UP_ALT(pf,*pa,pa0,cx);
|
|
#ifndef TERRAIN16
|
|
if(GET_TERRAIN_TYPE(*pf) != WATER_TERRAIN){
|
|
#endif
|
|
if(h + ROAD_FORCING <= height){
|
|
pixSet(cx,Y,height - *pa);
|
|
// *pa = height;
|
|
SET_REAL_TERRAIN(pf,material << TERRAIN_OFFSET,cx);
|
|
}
|
|
#ifndef TERRAIN16
|
|
}
|
|
else
|
|
if(fld - h < WATERLINE){
|
|
pixSet(cx,Y,height - *pa);
|
|
// *pa = height;
|
|
SET_REAL_TERRAIN(pf,material << TERRAIN_OFFSET,cx);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
xl += kl;
|
|
xr += kr;
|
|
Y++; *ch++ = 1;
|
|
}
|
|
if(where){
|
|
if(lto == rto) return;
|
|
lfrom = lto;
|
|
lto = (lto - 1 + n)%n;
|
|
|
|
br -= bl;
|
|
xl = x[lfrom];
|
|
al = x[lto] - xl + 1;
|
|
bl = y[lto] - Y + 1;
|
|
xl = (xl << 16) + (1 << 15);
|
|
if(al < 0){
|
|
al = -al;
|
|
DIVISION_MINUS(kl,al,bl)
|
|
}
|
|
else
|
|
DIVISION_PLUS(kl,al,bl)
|
|
}
|
|
else {
|
|
if(rto == lto) return;
|
|
rfv = rto;
|
|
rto = (rto + 1)%n;
|
|
|
|
bl -= br;
|
|
xr = x[rfv];
|
|
ar = x[rto] - xr + 1;
|
|
br = y[rto] - Y + 1;
|
|
xr = (xr << 16) + (1 << 15);
|
|
if(ar > 0)
|
|
DIVISION_PLUS(kr,ar,br)
|
|
else {
|
|
ar = -ar;
|
|
DIVISION_MINUS(kr,ar,br)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void m_line( int x1, int y1, int x2, int y2, int color ){
|
|
|
|
if (( x1 > UcutLeft)&&( x1 < UcutRight)&&
|
|
( x2 > UcutLeft)&&( x2 < UcutRight)&&
|
|
( y1 > VcutUp)&&( y1 < VcutDown)&&
|
|
( y2 > VcutUp)&&( y2 < VcutDown))
|
|
XGR_Line(x1, y1, x2, y2, color );
|
|
else {
|
|
double tminu, tmaxu, tminv, tmaxv;
|
|
int a1, a2, b1, b2;
|
|
int u1, u2, v1, v2;
|
|
|
|
a1 = UcutLeft - x1;
|
|
a2 = UcutRight - x1 - 1;
|
|
b1 = x2 - x1;
|
|
|
|
if ( b1 > 0.0 ){
|
|
tminu = double(a1)/b1;
|
|
tmaxu = double(a2)/b1;
|
|
} else if ( b1 < 0.0 ){
|
|
tminu = double(a2)/b1;
|
|
tmaxu = double(a1)/b1;
|
|
} else if (( x1 > UcutLeft ) && ( x1 < UcutRight )){
|
|
tminu = 0.0;
|
|
tmaxu = 1.0;
|
|
} else return;
|
|
|
|
a1 = VcutUp - y1;
|
|
a2 = VcutDown - y1 - 1;
|
|
b2 = y2 - y1;
|
|
|
|
if ( b2 > 0.0 ){
|
|
tminv = double(a1)/b2;
|
|
tmaxv = double(a2)/b2;
|
|
} else if ( b2 < 0.0 ){
|
|
tminv = double(a2)/b2;
|
|
tmaxv = double(a1)/b2;
|
|
} else if (( y1 > VcutUp ) && ( y1 < VcutDown )){
|
|
tminv = 0.0;
|
|
tmaxv = 1.0;
|
|
} else return;
|
|
|
|
if ( tminu < tminv ) tminu = tminv;
|
|
if ( tmaxu > tmaxv ) tmaxu = tmaxv;
|
|
|
|
if ( tminu < 0.0 ) tminu = 0.0;
|
|
if ( tmaxu > 1.0 ) tmaxu = 1.0;
|
|
if (( tminu >= tmaxu ) || ( tminu >= 1.0 ) || ( tmaxu <= 0.0 )) return;
|
|
|
|
u1 = (int)(x1 + tminu*b1);
|
|
v1 = (int)(y1 + tminu*b2);
|
|
|
|
u2 = (int)(x1 + tmaxu*b1);
|
|
v2 = (int)(y1 + tmaxu*b2);
|
|
|
|
XGR_Line(u1, v1, u2, v2, color);
|
|
}
|
|
}
|
|
|
|
void sTrack::set_height_from_ground(int what){
|
|
int i;
|
|
eBranch* l_branch = branch;
|
|
|
|
for( int j = 0; j < n_branch; j++ ){
|
|
for( i = 1; i < l_branch -> n_section-1; i++ )
|
|
set_height_in_branch_from_ground( l_branch, i, what);
|
|
|
|
if ( !l_branch -> beg_node )
|
|
set_height_in_branch_from_ground( l_branch, 0, what);
|
|
|
|
if ( !l_branch -> end_node )
|
|
set_height_in_branch_from_ground( l_branch, l_branch -> n_section-1, what);
|
|
|
|
l_branch = l_branch -> r;
|
|
}
|
|
}
|
|
|
|
//@caiiiycuk: memory leak at the end (not worth to fix)
|
|
char* trackName = strdup("track0.trk");
|
|
|
|
void sTrack::save(int n){
|
|
int i;
|
|
eNode *l_node = node;
|
|
eBranch *l_branch = branch;
|
|
|
|
trackName[5] += n;
|
|
XStream fout(GetTargetName(trackName), XS_OUT );
|
|
trackName[5] -= n;
|
|
|
|
fout < n_node < n_branch;
|
|
|
|
i = 0;
|
|
l_node = delNode;
|
|
while( l_node != 0 ) {
|
|
i++;
|
|
l_node = l_node -> r;
|
|
}
|
|
fout < i;
|
|
|
|
i = 0;
|
|
l_branch = delBranch;
|
|
while( l_branch != 0 ) {
|
|
i++;
|
|
l_branch = l_branch -> r;
|
|
}
|
|
fout < i;
|
|
|
|
l_node = node;
|
|
l_branch = branch;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> save( fout );
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> save( fout );
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
l_node = delNode;
|
|
while( l_node != 0 ) {
|
|
fout < l_node -> index;
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
l_branch = delBranch;
|
|
while( l_branch != 0 ) {
|
|
fout < l_branch -> index;
|
|
l_branch = l_branch -> r;
|
|
}
|
|
fout.close();
|
|
}
|
|
|
|
void eNode::save(XStream& fout){
|
|
int i;
|
|
fout < index;
|
|
fout < x < y < h;
|
|
|
|
fout < noise;
|
|
fout < dnoise;
|
|
fout < n_branch;
|
|
fout < color;
|
|
fout < mode;
|
|
fout < material;
|
|
|
|
for( i = 0; i < n_branch; i++ )
|
|
fout < branches[i];
|
|
}
|
|
|
|
void eBranch::save(XStream& fout){
|
|
int i;
|
|
fout < index;
|
|
fout < n_section;
|
|
fout < beg_node;
|
|
fout < end_node;
|
|
fout < color;
|
|
fout < material;
|
|
fout < is_render;
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
fout < data_base[i].x;
|
|
fout < data_base[i].y;
|
|
fout < data_base[i].h;
|
|
fout < data_base[i].hr;
|
|
fout < data_base[i].hl;
|
|
fout < data_base[i].wide;
|
|
fout < data_base[i].noise;
|
|
fout < data_base[i].dnoise;
|
|
fout < data_base[i].profil;
|
|
fout < data_base[i].dprofil;
|
|
fout < data_base[i].mode;
|
|
|
|
// fout < data_base[i].xl;
|
|
// fout < data_base[i].yl;
|
|
// fout < data_base[i].hl;
|
|
//
|
|
// fout < data_base[i].xr;
|
|
// fout < data_base[i].yr;
|
|
// fout < data_base[i].hr;
|
|
}
|
|
}
|
|
|
|
void sTrack::load(int n){
|
|
int i;
|
|
int ln_node, ln_branch, dn_node, dn_branch;
|
|
|
|
XStream fin(0);
|
|
|
|
trackName[5] += n;
|
|
if(!fin.open(GetTargetName(trackName),XS_IN)){
|
|
trackName[5] -= n;
|
|
return;
|
|
}
|
|
trackName[5] -= n;
|
|
|
|
eNode *l_node = node;
|
|
eBranch *l_branch = branch;
|
|
|
|
if ( n_branch > 0 ){
|
|
eBranch *tmp;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
tmp = l_branch;
|
|
l_branch = l_branch -> r;
|
|
delete tmp;
|
|
}
|
|
n_branch = 0;
|
|
branch = 0;
|
|
}
|
|
|
|
while( delBranch != 0 ){
|
|
eBranch *tmp = delBranch;
|
|
delBranch = delBranch -> r;
|
|
delete tmp;
|
|
}
|
|
|
|
if ( n_node > 0 ){
|
|
eNode *tmp;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
tmp = l_node;
|
|
l_node = l_node -> r;
|
|
delete tmp;
|
|
}
|
|
n_node = 0;
|
|
node = 0;
|
|
}
|
|
|
|
while( delNode != 0 ){
|
|
eNode *tmp = delNode;
|
|
delNode = delNode -> r;
|
|
delete tmp;
|
|
}
|
|
|
|
fin > ln_node > ln_branch > dn_node > dn_branch;
|
|
|
|
for( i = 0; i < ln_node; i++ ){
|
|
add_node(0, 0, H_MAIN);
|
|
}
|
|
|
|
int tmp;
|
|
for( i = 0; i < ln_branch; i++ ){
|
|
add_branch(0, 0, tmp, MIN_WIDE);
|
|
}
|
|
|
|
l_node = node;
|
|
l_branch = branch;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> load( fin );
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> load( fin );
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
delNode = 0;
|
|
for( i = 0; i < dn_node; i++){
|
|
l_node = new eNode(0, 0, 0);
|
|
fin > l_node -> index;
|
|
|
|
l_node -> r = delNode;
|
|
delNode = l_node;
|
|
}
|
|
|
|
delBranch = 0;
|
|
for( i = 0; i < dn_branch; i++){
|
|
l_branch = new eBranch;
|
|
fin > l_branch -> index;
|
|
|
|
l_branch -> r = delBranch;
|
|
delBranch = l_branch;
|
|
}
|
|
|
|
fin.close();
|
|
|
|
build_all_node();
|
|
// build_all_spline();
|
|
}
|
|
|
|
void eNode::load(XStream& fin){
|
|
int i;
|
|
fin > index;
|
|
fin > x > y > h;
|
|
|
|
fin > noise;
|
|
fin > dnoise;
|
|
fin > n_branch;
|
|
fin > color;
|
|
fin > mode;
|
|
fin > material;
|
|
|
|
for( i = 0; i < n_branch; i++ )
|
|
fin > branches[i];
|
|
}
|
|
|
|
void eBranch::load(XStream& fin){
|
|
int i;
|
|
fin > index;
|
|
fin > n_section;
|
|
fin > beg_node;
|
|
fin > end_node;
|
|
fin > color;
|
|
fin > material;
|
|
fin > is_render;
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
fin > data_base[i].x;
|
|
fin > data_base[i].y;
|
|
fin > data_base[i].h;
|
|
fin > data_base[i].hr;
|
|
fin > data_base[i].hl;
|
|
fin > data_base[i].wide;
|
|
fin > data_base[i].noise;
|
|
fin > data_base[i].dnoise;
|
|
fin > data_base[i].profil;
|
|
fin > data_base[i].dprofil;
|
|
fin > data_base[i].mode;
|
|
}
|
|
}
|
|
|
|
void sTrack::build_all_spline(void){
|
|
int i;
|
|
eBranch* l_branch = branch;
|
|
|
|
build_all_node();
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> build_spline();
|
|
l_branch = l_branch -> r;
|
|
}
|
|
}
|
|
|
|
static rSection l_all[MAX_ALL];
|
|
|
|
void eBranch::build_spline(void){
|
|
int i;
|
|
|
|
if ( all_on ) {
|
|
all_on = 0;
|
|
return;
|
|
}
|
|
|
|
n_point = 0;
|
|
|
|
if ( data_all != NULL ) delete[] data_all;
|
|
|
|
if ( n_section == 2 ){
|
|
data_all = new rSection[2];
|
|
data_all[0].xl = data_base[0].xl;
|
|
data_all[0].yl = data_base[0].yl;
|
|
data_all[0].hl = data_base[0].hl;
|
|
|
|
data_all[1].xl = data_base[1].xl;
|
|
data_all[1].yl = data_base[1].yl;
|
|
data_all[1].hl = data_base[1].hl;
|
|
|
|
data_all[0].xr = data_base[0].xr;
|
|
data_all[0].yr = data_base[0].yr;
|
|
data_all[0].hr = data_base[0].hr;
|
|
|
|
data_all[1].xr = data_base[1].xr;
|
|
data_all[1].yr = data_base[1].yr;
|
|
data_all[1].hr = data_base[1].hr;
|
|
|
|
data_base[0].point = 1;
|
|
n_point = 2;
|
|
all_on = 1;
|
|
} else {
|
|
//rSection *l_all;
|
|
//l_all = new rSection[MAX_ALL];
|
|
|
|
all_on = 1;
|
|
for( i = 0; i < n_section-1; i++ ){
|
|
spline( data_base, l_all, i, n_section-1, n_point );
|
|
// data_base[i].point = n_point;
|
|
}
|
|
|
|
data_all = new rSection[n_point];
|
|
for( i = 0; i < n_point; i++ ){
|
|
data_all[i].xl = l_all[i].xl;
|
|
data_all[i].yl = l_all[i].yl;
|
|
data_all[i].hl = l_all[i].hl;
|
|
data_all[i].xr = l_all[i].xr;
|
|
data_all[i].yr = l_all[i].yr;
|
|
data_all[i].hr = l_all[i].hr;
|
|
}
|
|
//delete l_all;
|
|
}
|
|
}
|
|
|
|
int min_len = 40;
|
|
|
|
void set_point_from_base( eSection* base, rSection& P, int pos, int pos0){
|
|
int dop = 0;
|
|
|
|
if (base[pos0].xl - base[pos].xl + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (base[pos0].xl - base[pos].xl - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
P.xl = base[pos].xl + dop;
|
|
P.yl = base[pos].yl;
|
|
P.hl = base[pos].hl;
|
|
|
|
dop = 0;
|
|
if (base[pos0].xl - base[pos].xl + XGR_MAXX > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
if (base[pos0].xl - base[pos].xl - XGR_MAXX < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
P.xr = base[pos].xr + dop;
|
|
P.yr = base[pos].yr;
|
|
P.hr = base[pos].hr;
|
|
}
|
|
|
|
void spline( eSection*& base, rSection* all, int k, int n_section, int& n_point ){
|
|
int i;
|
|
rSection P1, P2, P3, P4;
|
|
Vec al, bl, cl, dl;
|
|
Vec ar, br, cr, dr;
|
|
|
|
if ( k == 0 ){
|
|
set_point_from_base( base, P1, k, k);
|
|
set_point_from_base( base, P4, k+2, k);
|
|
} else if ( k == n_section-1) {
|
|
set_point_from_base( base, P1, k-1, k);
|
|
set_point_from_base( base, P4, k+1, k);
|
|
} else {
|
|
set_point_from_base( base, P1, k-1, k);
|
|
set_point_from_base( base, P4, k+2, k);
|
|
}
|
|
set_point_from_base( base, P2, k, k);
|
|
set_point_from_base( base, P3, k+1, k);
|
|
|
|
al.x = 0.5*(3.0*P2.xl - 3.0*P3.xl - P1.xl + P4.xl );
|
|
al.y = 0.5*(3.0*P2.yl - 3.0*P3.yl - P1.yl + P4.yl );
|
|
al.h = 0.5*(3.0*P2.hl - 3.0*P3.hl - P1.hl + P4.hl );
|
|
|
|
bl.x = 0.5*(4.0*P3.xl + 2.0*P1.xl - P4.xl - 5.0*P2.xl);
|
|
bl.y = 0.5*(4.0*P3.yl + 2.0*P1.yl - P4.yl - 5.0*P2.yl);
|
|
bl.h = 0.5*(4.0*P3.hl + 2.0*P1.hl - P4.hl - 5.0*P2.hl);
|
|
|
|
cl.x = 0.5*(P3.xl - P1.xl );
|
|
cl.y = 0.5*(P3.yl - P1.yl );
|
|
cl.h = 0.5*(P3.hl - P1.hl );
|
|
|
|
dl.x = P2.xl;
|
|
dl.y = P2.yl;
|
|
dl.h = P2.hl;
|
|
/*-------------------------------------------*/
|
|
ar.x = 0.5*(3.0*P2.xr - 3.0*P3.xr - P1.xr + P4.xr );
|
|
ar.y = 0.5*(3.0*P2.yr - 3.0*P3.yr - P1.yr + P4.yr );
|
|
ar.h = 0.5*(3.0*P2.hr - 3.0*P3.hr - P1.hr + P4.hr );
|
|
|
|
br.x = 0.5*(4.0*P3.xr + 2.0*P1.xr - P4.xr - 5.0*P2.xr);
|
|
br.y = 0.5*(4.0*P3.yr + 2.0*P1.yr - P4.yr - 5.0*P2.yr);
|
|
br.h = 0.5*(4.0*P3.hr + 2.0*P1.hr - P4.hr - 5.0*P2.hr);
|
|
|
|
cr.x = 0.5*(P3.xr - P1.xr );
|
|
cr.y = 0.5*(P3.yr - P1.yr );
|
|
cr.h = 0.5*(P3.hr - P1.hr );
|
|
|
|
dr.x = P2.xr;
|
|
dr.y = P2.yr;
|
|
dr.h = P2.hr;
|
|
|
|
double lenl = sqrt((double)(P2.xl-P3.xl)*(P2.xl-P3.xl) + (P2.yl-P3.yl)*(P2.yl-P3.yl) );
|
|
double lenr = sqrt((double)(P2.xr-P3.xr)*(P2.xr-P3.xr) + (P2.yr-P3.yr)*(P2.yr-P3.yr) );
|
|
double len;
|
|
|
|
if ( lenl > lenr ) len = lenl; else len = lenr;
|
|
|
|
int n = round(len) + 1;
|
|
double delta = 1.0/n;
|
|
double t = 0.0;
|
|
|
|
if ( n_point + n > MAX_ALL ) ErrH.Abort( "Out of all section" );
|
|
|
|
for( i = n_point; i < n_point+n; i++ ){
|
|
double t2, t3;
|
|
|
|
t2 = t*t;
|
|
t3 = t2*t;
|
|
|
|
all[i].xl = round(al.x*t3 + bl.x*t2 + cl.x*t + dl.x);
|
|
all[i].yl = round(al.y*t3 + bl.y*t2 + cl.y*t + dl.y);
|
|
all[i].hl = round(al.h*t3 + bl.h*t2 + cl.h*t + dl.h);
|
|
|
|
all[i].xr = round(ar.x*t3 + br.x*t2 + cr.x*t + dr.x);
|
|
all[i].yr = round(ar.y*t3 + br.y*t2 + cr.y*t + dr.y);
|
|
all[i].hr = round(ar.h*t3 + br.h*t2 + cr.h*t + dr.h);
|
|
|
|
t += delta;
|
|
}
|
|
n_point += n;
|
|
base[k].point = n;
|
|
|
|
if ( k == n_section-1 ) {
|
|
all[i].xl = base[k+1].xl;
|
|
all[i].yl = base[k+1].yl;
|
|
all[i].hl = base[k+1].hl;
|
|
|
|
all[i].xr = base[k+1].xr;
|
|
all[i].yr = base[k+1].yr;
|
|
all[i].hr = base[k+1].hr;
|
|
|
|
n_point++;
|
|
}
|
|
}
|
|
|
|
int sTrack::find_bound_point( int& cBranch, int& cPoint, int X, int Y ){
|
|
eBranch* l_branch = branch;
|
|
int i;
|
|
|
|
for( i = 0; i < n_branch; i++){
|
|
if ( l_branch -> find_bound_point( cPoint, X, Y ) ){
|
|
cBranch = l_branch -> index;
|
|
return 1;
|
|
}
|
|
l_branch = l_branch -> r;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void sTrack::set_wide_in_branch( int cBranch, int cPoint, int X, int Y ){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != cBranch ) l_branch = l_branch -> r;
|
|
|
|
l_branch -> set_wide_in_section( cPoint, X, Y );
|
|
}
|
|
|
|
void eBranch::set_wide_in_section( int pos, int X, int Y ){
|
|
int len;
|
|
|
|
pos--;
|
|
|
|
len = (int)sqrt((double)(data_base[pos].x-X)*(data_base[pos].x - X)+(data_base[pos].y-Y)*(data_base[pos].y-Y));
|
|
data_base[pos].wide = len;
|
|
|
|
set_wide( pos );
|
|
set_wide( pos+1 );
|
|
set_wide( pos+2 );
|
|
}
|
|
|
|
int eBranch::find_bound_point( int& cPoint, int X, int Y ){
|
|
int i;
|
|
int Xl;
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
int dop = 0;
|
|
|
|
if ((data_base[i].xr - X) > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
else if ((data_base[i].xr - X) < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
Xl = X + dop;
|
|
|
|
if ( abs(data_base[i].xr - Xl) < delta && abs(data_base[i].yr-Y) < delta ) {
|
|
cPoint = i+1;
|
|
return 1;
|
|
}
|
|
|
|
dop = 0;
|
|
if ((data_base[i].xl - X) > (int)clip_mask_x) dop = clip_mask_x+1;
|
|
else if ((data_base[i].xl - X) < -(int)clip_mask_x) dop = -((int)clip_mask_x+1);
|
|
|
|
Xl = X + dop;
|
|
|
|
if ( abs(data_base[i].xl - Xl) < delta && abs(data_base[i].yl-Y) < delta ) {
|
|
cPoint = i+1;
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const int COLOR_FON = 32;
|
|
|
|
void sTrack::show_branch_height(int cBranch, int cPoint){
|
|
int CX = curGMap -> CX;
|
|
int CY = curGMap -> CY;
|
|
int xc = curGMap -> xc;
|
|
int yc = curGMap -> yc;
|
|
eBranch* l_branch = branch;
|
|
char str[10];
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch ) l_branch = l_branch -> r;
|
|
|
|
cPoint--;
|
|
|
|
l_branch -> data_base[cPoint].h += DeltamH;
|
|
l_branch -> data_base[cPoint].hl += DeltalH+DeltamH;
|
|
l_branch -> data_base[cPoint].hr -= DeltalH-DeltamH;
|
|
|
|
if (l_branch -> data_base[cPoint].h < 0 ) l_branch -> data_base[cPoint].h -= DeltamH;
|
|
if (l_branch -> data_base[cPoint].h > 255 ) l_branch -> data_base[cPoint].h -= DeltamH;
|
|
|
|
if (l_branch -> data_base[cPoint].hl < 0 ) {
|
|
l_branch -> data_base[cPoint].h -= DeltamH;
|
|
l_branch -> data_base[cPoint].hl -= DeltalH+DeltamH;
|
|
l_branch -> data_base[cPoint].hr += DeltalH-DeltamH;
|
|
}
|
|
if (l_branch -> data_base[cPoint].hl > 255 ) {
|
|
l_branch -> data_base[cPoint].hl -= DeltalH+DeltamH;
|
|
l_branch -> data_base[cPoint].hr += DeltalH-DeltamH;
|
|
l_branch -> data_base[cPoint].h -= DeltamH;
|
|
}
|
|
|
|
if (l_branch -> data_base[cPoint].hr < 0 ) {
|
|
l_branch -> data_base[cPoint].hl -= DeltalH+DeltamH;
|
|
l_branch -> data_base[cPoint].hr += DeltalH-DeltamH;
|
|
l_branch -> data_base[cPoint].h -= DeltamH;
|
|
}
|
|
if (l_branch -> data_base[cPoint].hr > 255 ) {
|
|
l_branch -> data_base[cPoint].hr += DeltalH-DeltamH;
|
|
l_branch -> data_base[cPoint].hl -= DeltalH+DeltamH;
|
|
l_branch -> data_base[cPoint].h -= DeltamH;
|
|
}
|
|
|
|
// int u1 = l_branch -> data_base[cPoint].x;
|
|
// int v1 = l_branch -> data_base[cPoint].y;
|
|
int u1 = 20+CX-xc;
|
|
int v1 = 60+CY-yc;
|
|
int u2 = u1+150, v2 = v1+70;
|
|
|
|
for( i = v1; i < v2; i++)
|
|
line( u1, i, u2, i, COLOR_FON);
|
|
|
|
line( u1, v1, u1, v2, COLOR_TRACK);
|
|
line( u1, v1, u2, v1, COLOR_TRACK);
|
|
line( u2, v1, u2, v2, COLOR_TRACK);
|
|
line( u1, v2, u2, v2, COLOR_TRACK);
|
|
|
|
itoa( l_branch -> data_base[cPoint].h, str, 10 );
|
|
sysfont.draw( u1+xc-CX+2, v1+yc-CY+2, (uchar*)str, COLOR_TRACK, -1);
|
|
sysfont.draw( u1+xc-CX+26, v1+yc-CY+2, (uchar*)",", COLOR_TRACK, -1);
|
|
|
|
itoa( l_branch -> data_base[cPoint].hl, str, 10 );
|
|
sysfont.draw( u1+xc-CX+32, v1+yc-CY+2, (uchar*)str, COLOR_TRACK, -1);
|
|
|
|
line( (u1+u2)/2-20, v2-2, (u2+u1)/2-20, v2 - (l_branch -> data_base[cPoint].hl/4), COLOR_TRACK);
|
|
line( (u1+u2)/2+20, v2-2, (u2+u1)/2+20, v2 - (l_branch -> data_base[cPoint].hr/4), COLOR_TRACK);
|
|
line((u2+u1)/2-20, v2 - (l_branch -> data_base[cPoint].hl/4),(u2+u1)/2, v2 - (l_branch -> data_base[cPoint].h/4), COLOR_TRACK);
|
|
line((u2+u1)/2+20, v2 - (l_branch -> data_base[cPoint].hr/4),(u2+u1)/2, v2 - (l_branch -> data_base[cPoint].h/4), COLOR_TRACK);
|
|
|
|
line( (u1+u2)/2, v2-2, (u2+u1)/2, v2 - (l_branch -> data_base[cPoint].h/4), COLOR_TRACK);
|
|
|
|
if (cPoint > 0 ){
|
|
line( u1+2, v2-2, u1+2, v2 - (l_branch -> data_base[cPoint-1].h/4), COLOR_TRACK);
|
|
line( u1+2, v2 - (l_branch -> data_base[cPoint-1].h/4), (u2+u1)/2, v2 - (l_branch -> data_base[cPoint].h/4), COLOR_TRACK );
|
|
}
|
|
|
|
if ( cPoint+1 < l_branch -> n_section ){
|
|
line( u2-2, v2-2, u2-2, v2 - (l_branch -> data_base[cPoint+1].h/4), COLOR_TRACK);
|
|
line( u2-2, v2 - (l_branch -> data_base[cPoint+1].h/4), (u2+u1)/2, v2 - (l_branch -> data_base[cPoint].h/4), COLOR_TRACK );
|
|
}
|
|
DeltamH = 0;
|
|
DeltalH = 0;
|
|
|
|
XGR_Flush(20,60,150,70);
|
|
}
|
|
|
|
void sTrack::show_node_height(int cNode ){
|
|
int CX = curGMap -> CX;
|
|
int CY = curGMap -> CY;
|
|
int xc = curGMap -> xc;
|
|
int yc = curGMap -> yc;
|
|
eNode* l_node = node;
|
|
char str[10];
|
|
|
|
int i = 0;
|
|
while( l_node -> index != cNode ) l_node = l_node -> r;
|
|
|
|
l_node -> h += DeltamH;
|
|
|
|
if (l_node -> h < 0 ) l_node -> h = 0;
|
|
if (l_node -> h > 255 ) l_node -> h = 255;
|
|
|
|
register int H = l_node -> h;
|
|
|
|
/* for( i = 0; i < l_node -> n_branch; i++ ){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != l_node -> branches[i] ) l_branch = l_branch -> r;
|
|
|
|
if ( l_branch -> beg_node == cNode ) {
|
|
l_branch -> data_base[0].h = H;
|
|
l_branch -> data_base[0].hl = H;
|
|
l_branch -> data_base[0].hr = H;
|
|
}
|
|
|
|
register int pos = l_branch -> n_section-1;
|
|
|
|
if ( l_branch -> end_node == cNode ) {
|
|
l_branch -> data_base[pos].h = H;
|
|
l_branch -> data_base[pos].hr = H;
|
|
l_branch -> data_base[pos].hl = H;
|
|
}
|
|
}
|
|
*/
|
|
|
|
// int u1 = l_node -> x;
|
|
// int v1 = l_node -> y;
|
|
int u1 = 20+CX-xc;
|
|
int v1 = 60+CY-yc;
|
|
|
|
int u2 = u1+150, v2 = v1+70;
|
|
|
|
for( i = v1; i < v2; i++)
|
|
line( u1, i, u2, i, COLOR_FON);
|
|
|
|
line( u1, v1, u1, v2, COLOR_TRACK);
|
|
line( u1, v1, u2, v1, COLOR_TRACK);
|
|
line( u2, v1, u2, v2, COLOR_TRACK);
|
|
line( u1, v2, u2, v2, COLOR_TRACK);
|
|
|
|
itoa( l_node -> h, str, 10 );
|
|
sysfont.draw( u1+xc-CX+2, v1+yc-CY+2, (uchar*)str, COLOR_TRACK, -1);
|
|
|
|
line( (u1+u2)/2, v2-2, (u2+u1)/2, v2 - (H/4), COLOR_TRACK);
|
|
DeltamH = 0;
|
|
|
|
XGR_Flush(20,60,150,70);
|
|
}
|
|
|
|
void sTrack::build_all_branch(void){
|
|
int i;
|
|
eBranch* l_branch = branch;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> build_section();
|
|
l_branch = l_branch -> r;
|
|
}
|
|
}
|
|
|
|
void eBranch::build_section(void){
|
|
int xv, yv;
|
|
int xr, yr;
|
|
gLine ll, lr;
|
|
|
|
if ( beg_node != 0 ){
|
|
calc_normal_vector( data_base, 1, xv, yv);
|
|
|
|
xr = data_base[0].xr - data_base[0].xl;
|
|
yr = data_base[0].yr - data_base[0].yl;
|
|
|
|
ll.a = xv;
|
|
ll.b = yv;
|
|
lr.a = -yv;
|
|
lr.b = xv;
|
|
|
|
if ( (-yv*xr + xv*yr) > 0 ){
|
|
ll.x = data_base[0].xr;
|
|
ll.y = data_base[0].yr;
|
|
|
|
lr.x = data_base[0].xl;
|
|
lr.y = data_base[0].yl;
|
|
|
|
find_point_on_line( ll, lr, xpb[0], ypb[0] );
|
|
|
|
xpb[2] = data_base[0].xr;
|
|
ypb[2] = data_base[0].yr;
|
|
|
|
xpb[1] = data_base[0].xl;
|
|
ypb[1] = data_base[0].yl;
|
|
|
|
data_base[0].xl = xpb[0];
|
|
data_base[0].yl = ypb[0];
|
|
} else {
|
|
ll.x = data_base[0].xl;
|
|
ll.y = data_base[0].yl;
|
|
|
|
lr.x = data_base[0].xr;
|
|
lr.y = data_base[0].yr;
|
|
|
|
find_point_on_line( ll, lr, xpb[0], ypb[0] );
|
|
|
|
xpb[2] = data_base[0].xr;
|
|
ypb[2] = data_base[0].yr;
|
|
|
|
xpb[1] = data_base[0].xl;
|
|
ypb[1] = data_base[0].yl;
|
|
|
|
data_base[0].xr = xpb[0];
|
|
data_base[0].yr = ypb[0];
|
|
}
|
|
}
|
|
|
|
int pos = n_section-1;
|
|
if ( end_node != 0 ){
|
|
calc_normal_vector( data_base, pos, xv, yv);
|
|
|
|
xv = -xv;
|
|
yv = -yv;
|
|
|
|
xr = data_base[pos].xr - data_base[pos].xl;
|
|
yr = data_base[pos].yr - data_base[pos].yl;
|
|
|
|
ll.a = xv;
|
|
ll.b = yv;
|
|
lr.a = -yv;
|
|
lr.b = xv;
|
|
|
|
if ( (-yv*xr + xv*yr) > 0 ){
|
|
ll.x = data_base[pos].xr;
|
|
ll.y = data_base[pos].yr;
|
|
|
|
lr.x = data_base[pos].xl;
|
|
lr.y = data_base[pos].yl;
|
|
|
|
find_point_on_line( ll, lr, xpe[0], ype[0] );
|
|
|
|
xpe[1] = data_base[pos].xr;
|
|
ype[1] = data_base[pos].yr;
|
|
|
|
xpe[2] = data_base[pos].xl;
|
|
ype[2] = data_base[pos].yl;
|
|
|
|
data_base[pos].xl = xpe[0];
|
|
data_base[pos].yl = ype[0];
|
|
} else {
|
|
ll.x = data_base[pos].xl;
|
|
ll.y = data_base[pos].yl;
|
|
|
|
lr.x = data_base[pos].xr;
|
|
lr.y = data_base[pos].yr;
|
|
|
|
find_point_on_line( ll, lr, xpe[0], ype[0] );
|
|
|
|
xpe[1] = data_base[pos].xr;
|
|
ype[1] = data_base[pos].yr;
|
|
|
|
xpe[2] = data_base[pos].xl;
|
|
ype[2] = data_base[pos].yl;
|
|
|
|
data_base[pos].xr = xpe[0];
|
|
data_base[pos].yr = ype[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
void sTrack::get_section_parametr( int cBranch, int cPoint, int& NoiseLevel, int& profil, int& NoiseAmp, int& ShapeAmp, int& NodeHeight, int& NodeSlope, int& TerrainMode, int& ColorBase, int& RenderMode, int& WideSection, int& MaterSection ){
|
|
eBranch* l_branch = branch;
|
|
|
|
if ( cBranch < 1 ) ErrH.Abort( "Error in struct Track" );
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find Branchs parametor" );
|
|
|
|
NodeHeight = l_branch -> data_base[cPoint-1].h;
|
|
NodeSlope = l_branch -> data_base[cPoint-1].hl - NodeHeight;
|
|
NoiseLevel = l_branch -> data_base[cPoint-1].noise;
|
|
profil = l_branch -> data_base[cPoint-1].profil;
|
|
NoiseAmp = l_branch -> data_base[cPoint-1].dnoise;
|
|
ShapeAmp = l_branch -> data_base[cPoint-1].dprofil;
|
|
TerrainMode = l_branch -> data_base[cPoint-1].mode;
|
|
WideSection = l_branch -> data_base[cPoint-1].wide;
|
|
ColorBase = l_branch -> color;
|
|
RenderMode = l_branch -> is_render;
|
|
MaterSection = l_branch -> material;
|
|
}
|
|
|
|
void set_one_section(int i, eBranch*& l_branch, int NoiseLevel,int profil,int NoiseAmp,int ShapeAmp,int TerrainMode,int NodeHeight,int NodeSlope,int WideSection){
|
|
l_branch -> data_base[i].noise = NoiseLevel;
|
|
l_branch -> data_base[i].profil = profil;
|
|
l_branch -> data_base[i].dnoise = NoiseAmp;
|
|
l_branch -> data_base[i].dprofil = ShapeAmp;
|
|
l_branch -> data_base[i].wide = WideSection;
|
|
|
|
if ( TerrainMode < 2 ) {
|
|
l_branch -> data_base[i].h = NodeHeight;
|
|
l_branch -> data_base[i].hl = NodeHeight + NodeSlope;
|
|
l_branch -> data_base[i].hr = NodeHeight - NodeSlope;
|
|
|
|
l_branch -> data_base[i].mode = TerrainMode;
|
|
} else {
|
|
Track.set_height_in_branch_from_ground( l_branch, i, 1);
|
|
|
|
l_branch -> data_base[i].mode = TerrainMode;
|
|
// l_branch -> data_base[i].mode = TerrainMode - 2;
|
|
}
|
|
}
|
|
|
|
void sTrack::set_section_parametr( int cBranch, int cPoint, int NoiseLevel, int profil, int NoiseAmp, int ShapeAmp, int GroupToggle, int NodeHeight, int NodeSlope, int TerrainMode, int ColorBase, int RenderMode, int WideSection, int MaterSection){
|
|
eBranch* l_branch = branch;
|
|
|
|
if ( cBranch < 1 ) ErrH.Abort( "Error in struct Track" );
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch) {
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
if( i == n_branch ) ErrH.Abort( "Dont Find Branchs parametor" );
|
|
|
|
l_branch -> color = ColorBase;
|
|
l_branch -> material = MaterSection;
|
|
l_branch -> is_render = RenderMode;
|
|
|
|
if ( GroupToggle ) {
|
|
for( i = 1; i < l_branch -> n_section-1; i++ ){
|
|
set_one_section(i,l_branch,NoiseLevel,profil,NoiseAmp,ShapeAmp,TerrainMode,NodeHeight,NodeSlope,WideSection);
|
|
}
|
|
|
|
if ( !l_branch -> beg_node )
|
|
set_one_section(0,l_branch,NoiseLevel,profil,NoiseAmp,ShapeAmp,TerrainMode,NodeHeight,NodeSlope, WideSection);
|
|
|
|
if ( !l_branch -> end_node )
|
|
set_one_section(l_branch -> n_section-1,l_branch,NoiseLevel,profil,NoiseAmp,ShapeAmp,TerrainMode,NodeHeight,NodeSlope, WideSection);
|
|
} else {
|
|
i = cPoint-1;
|
|
set_one_section(i,l_branch,NoiseLevel,profil,NoiseAmp,ShapeAmp,TerrainMode,NodeHeight,NodeSlope, WideSection);
|
|
}
|
|
build_all_node();
|
|
}
|
|
|
|
void sTrack::get_node_parametr( int cNode, int& NoiseLevel, int& NoiseAmp, int& NodeHeight, int& ColorBase, int& MaterSection, int& TerrainMode ){
|
|
eNode* l_node = node;
|
|
|
|
if ( cNode < 1 ) ErrH.Abort( "Error in struct Track" );
|
|
|
|
int i = 0;
|
|
while( l_node -> index != cNode && i < n_node) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
if( i == n_node ) ErrH.Abort( "Dont Find nodes parametor" );
|
|
|
|
NoiseLevel = l_node -> noise;
|
|
NoiseAmp = l_node -> dnoise;
|
|
NodeHeight = l_node -> h;
|
|
ColorBase = l_node -> color;
|
|
MaterSection = l_node -> material;
|
|
TerrainMode = l_node -> mode;
|
|
}
|
|
|
|
void sTrack::set_node_parametr( int cNode, int CommonDoing, int NoiseLevel, int NoiseAmp, int NodeHeight, int ColorBase, int MaterSection, int TerrainMode ){
|
|
eNode* l_node = node;
|
|
int i;
|
|
|
|
if ( cNode < 1 ) ErrH.Abort( "Error in struct Track" );
|
|
|
|
i = 0;
|
|
while( l_node -> index != cNode && i < n_node) {
|
|
l_node = l_node -> r;
|
|
i++;
|
|
}
|
|
if( i == n_node ) ErrH.Abort( "Dont Find nodes parametor" );
|
|
|
|
if ( CommonDoing ){
|
|
set_node_height( cNode, NodeHeight);
|
|
for( i = 0; i < l_node -> n_branch; i++ )
|
|
set_noise_in_branch( cNode, l_node -> branches[i], NoiseLevel, NoiseAmp);
|
|
} else {
|
|
l_node -> h = NodeHeight;
|
|
}
|
|
|
|
l_node -> noise = NoiseLevel;
|
|
l_node -> dnoise = NoiseAmp;
|
|
l_node -> color = ColorBase;
|
|
l_node -> material = MaterSection;
|
|
l_node -> mode = TerrainMode;
|
|
}
|
|
|
|
void sTrack::set_noise_in_branch( int cNode, int cBranch, int NoiseLevel, int NoiseAmp){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != cBranch ) l_branch = l_branch -> r;
|
|
|
|
if ( l_branch -> beg_node == cNode ) {
|
|
l_branch -> data_base[0].noise = NoiseLevel;
|
|
l_branch -> data_base[0].dnoise = NoiseAmp;
|
|
}
|
|
|
|
int pos = l_branch -> n_section-1;
|
|
if ( l_branch -> end_node == cNode ) {
|
|
l_branch -> data_base[pos].noise = NoiseLevel;
|
|
l_branch -> data_base[pos].dnoise = NoiseAmp;
|
|
}
|
|
}
|
|
|
|
/*
|
|
void sTrack::save(int n){
|
|
int i;
|
|
eNode *l_node = node;
|
|
eBranch *l_branch = branch;
|
|
|
|
trackName[5] += n;
|
|
XStream fout( trackName, XS_OUT );
|
|
trackName[5] -= n;
|
|
|
|
fout <= n_node < "\t" <= n_branch < "\n";
|
|
|
|
i = 0;
|
|
l_node = delNode;
|
|
while( l_node != 0 ) {
|
|
i++;
|
|
l_node = l_node -> r;
|
|
}
|
|
fout <= i < "delNode\t";
|
|
|
|
i = 0;
|
|
l_branch = delBranch;
|
|
while( l_branch != 0 ) {
|
|
i++;
|
|
l_branch = l_branch -> r;
|
|
}
|
|
fout <= i < "delBranch\n";
|
|
|
|
l_node = node;
|
|
l_branch = branch;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> save( fout );
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> save( fout );
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
l_node = delNode;
|
|
while( l_node != 0 ) {
|
|
fout <= l_node -> index < "\t";
|
|
l_node = l_node -> r;
|
|
}
|
|
fout < "\n";
|
|
|
|
l_branch = delBranch;
|
|
while( l_branch != 0 ) {
|
|
fout <= l_branch -> index < "\t";
|
|
l_branch = l_branch -> r;
|
|
}
|
|
fout.close();
|
|
}
|
|
|
|
void eNode::save(XStream& fout){
|
|
int i;
|
|
fout <= index < " - node\n";
|
|
fout <= x < "\t" <= y < "\t" <= h < "\n";
|
|
|
|
// fout < noise;
|
|
fout <= n_branch < "\n";
|
|
|
|
for( i = 0; i < n_branch; i++ )
|
|
fout <= branches[i] < "\t";
|
|
fout < "\n";
|
|
}
|
|
|
|
void eBranch::save(XStream& fout){
|
|
int i;
|
|
fout <= index < "- branch\t";
|
|
fout <= n_section < "\t";
|
|
fout <= beg_node < "\t";
|
|
fout <= end_node < "\n";
|
|
|
|
for( i = 0; i < n_section; i++ ){
|
|
fout <= data_base[i].x < "\t";
|
|
fout <= data_base[i].y < "\n";
|
|
|
|
// fout < data_base[i].xl;
|
|
// fout < data_base[i].yl;
|
|
// fout < data_base[i].hl;
|
|
//
|
|
// fout < data_base[i].xr;
|
|
// fout < data_base[i].yr;
|
|
// fout < data_base[i].hr;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void sTrack::saveKron(int n){
|
|
int i;
|
|
eNode *l_node = node;
|
|
eBranch *l_branch = branch;
|
|
|
|
XBuffer fname;
|
|
fname.init();
|
|
fname < "track" <= n < ".krn";
|
|
XStream fout(GetTargetName(fname.GetBuf()), XS_OUT );
|
|
|
|
fout < n_node < n_branch;
|
|
|
|
l_node = node;
|
|
l_branch = branch;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> saveKron( branch, fout );
|
|
l_node = l_node -> r;
|
|
}
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> saveKron( fout );
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
fout.close();
|
|
}
|
|
|
|
void eNode::saveKron( eBranch*& branch, XStream& fout)
|
|
{
|
|
int* s = new int[MAX_BRANCH];
|
|
|
|
build_polygon( branch, s, 1 );
|
|
int i;
|
|
fout < index;
|
|
fout < x < y < h;
|
|
fout < n_branch;
|
|
for( i = 0; i < n_branch; i++ ){
|
|
fout < s[n_branch-i-1];
|
|
fout < xp[i];
|
|
fout < yp[i];
|
|
};
|
|
|
|
delete[] s;
|
|
}
|
|
|
|
void eBranch::saveKron(XStream& fout)
|
|
{
|
|
int i;
|
|
|
|
fout < index;
|
|
|
|
fout < beg_node;
|
|
fout < end_node;
|
|
|
|
i = n_point/min_len+1;
|
|
if ( beg_node > 0 ) i++;
|
|
if ( end_node > 0 ) i++;
|
|
|
|
fout < i;
|
|
int max_noise = 0;
|
|
|
|
for( i = 0; i < n_section; i++ )
|
|
if ( data_base[i].dnoise > max_noise ) max_noise = data_base[i].dnoise;
|
|
|
|
// fout < max_noise;
|
|
|
|
if ( beg_node > 0 ){
|
|
fout < (data_base[0].xl & clip_mask_x);
|
|
fout < data_base[0].yl;
|
|
fout < data_base[0].hl;
|
|
|
|
fout < (data_base[0].xr & clip_mask_x);
|
|
fout < data_base[0].yr;
|
|
fout < data_base[0].hr;
|
|
|
|
}
|
|
|
|
for( i = 0; i < n_point; i++ )
|
|
if ( i%min_len == 0 ){
|
|
fout < data_all[i].xl;
|
|
fout < data_all[i].yl;
|
|
fout < data_all[i].hl;
|
|
|
|
fout < data_all[i].xr;
|
|
fout < data_all[i].yr;
|
|
fout < data_all[i].hr;
|
|
};
|
|
|
|
i = n_point-1;
|
|
if ( n_point%min_len == 0 ){
|
|
fout < data_all[i].xl;
|
|
fout < data_all[i].yl;
|
|
fout < data_all[i].hl;
|
|
|
|
fout < data_all[i].xr;
|
|
fout < data_all[i].yr;
|
|
fout < data_all[i].hr;
|
|
};
|
|
|
|
if ( end_node > 0 ){
|
|
fout < data_base[n_section-1].xl;
|
|
fout < data_base[n_section-1].yl;
|
|
fout < data_base[n_section-1].hl;
|
|
|
|
fout < data_base[n_section-1].xr;
|
|
fout < data_base[n_section-1].yr;
|
|
fout < data_base[n_section-1].hr;
|
|
}
|
|
|
|
}
|
|
|
|
void sTrack::set_node_height(int cNode, int Height){
|
|
|
|
eNode* l_node = node;
|
|
|
|
int i = 0;
|
|
while( l_node -> index != cNode ) l_node = l_node -> r;
|
|
|
|
l_node -> h = Height;
|
|
|
|
if (l_node -> h < 0 ) l_node -> h = 0;
|
|
if (l_node -> h > 255 ) l_node -> h = 255;
|
|
|
|
register int H = l_node -> h;
|
|
|
|
for( i = 0; i < l_node -> n_branch; i++ ){
|
|
eBranch* l_branch = branch;
|
|
|
|
while( l_branch -> index != l_node -> branches[i] ) l_branch = l_branch -> r;
|
|
|
|
if ( l_branch -> beg_node == cNode ) {
|
|
l_branch -> data_base[0].h = H;
|
|
l_branch -> data_base[0].hl = H;
|
|
l_branch -> data_base[0].hr = H;
|
|
}
|
|
|
|
register int pos = l_branch -> n_section-1;
|
|
|
|
if ( l_branch -> end_node == cNode ) {
|
|
l_branch -> data_base[pos].h = H;
|
|
l_branch -> data_base[pos].hr = H;
|
|
l_branch -> data_base[pos].hl = H;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sTrack::set_height_in_branch_from_ground(eBranch* l_branch, int cSection, int what){
|
|
if ( l_branch -> data_base[cSection].mode < 2 ) return;
|
|
|
|
int xxl = l_branch -> data_base[cSection].xl;
|
|
int yyl = l_branch -> data_base[cSection].yl;
|
|
|
|
int xxr = l_branch -> data_base[cSection].xr;
|
|
int yyr = l_branch -> data_base[cSection].yr;
|
|
|
|
if((!vMap -> lineT[yyr] || !vMap -> lineT[yyl]) && what) return;
|
|
if(!what && (!vMap -> lineT[yyr] || !vMap -> lineT[yyl]))
|
|
vMap -> change(MIN(yyr,yyl),MAX(yyr,yyl));
|
|
|
|
l_branch -> data_base[cSection].hl = vMap -> lineT[yyl][xxl&clip_mask_x];
|
|
l_branch -> data_base[cSection].hr = vMap -> lineT[yyr][xxr&clip_mask_x];
|
|
l_branch -> data_base[cSection].h = (l_branch -> data_base[cSection].hr+l_branch -> data_base[cSection].hl)>>1;
|
|
}
|
|
|
|
void eNode::show_on_all(int UpX, int UpY, int x_size, int y_size){
|
|
int x1 = UpX + ((x*x_size)>>MAP_POWER_X);
|
|
int y1 = UpY + ((y*y_size)>>MAP_POWER_Y);
|
|
|
|
XGR_Line(x1, y1, x1, y1, ColorTable[ color ]);
|
|
}
|
|
|
|
void eBranch::show_on_all(int UpX, int UpY, int x_size, int y_size){
|
|
int i;
|
|
int x1,x2,y1,y2;
|
|
|
|
for( i = 0; i < n_section-1; i++ ){
|
|
x1 = UpX + ((data_base[i].x*x_size)>>MAP_POWER_X);
|
|
x2 = UpX + ((data_base[i+1].x*x_size)>>MAP_POWER_X);
|
|
y1 = UpY + ((data_base[i].y*y_size)>>MAP_POWER_Y);
|
|
y2 = UpY + ((data_base[i+1].y*y_size)>>MAP_POWER_Y);
|
|
|
|
if ( abs(data_base[i].x - data_base[i+1].x) < (int)clip_mask_x-XGR_MAXX ){
|
|
XGR_Line(x1, y1, x2, y2, ColorTable[ color ]);
|
|
}
|
|
}
|
|
}
|
|
int UpX = 5;
|
|
int UpY = 25;
|
|
|
|
void sTrack::show_all_track(void){
|
|
int color_boder = 255;
|
|
int color_back = 45;
|
|
int x_size;
|
|
int y_size;
|
|
int i;
|
|
int mX;
|
|
int mY;
|
|
|
|
if (!Track_show_all) return;
|
|
|
|
int xm = XGR_MouseObj.PosX;
|
|
int ym = XGR_MouseObj.PosY;
|
|
mX = (xm - curGMap -> xc + curGMap -> CX) & clip_mask_x;
|
|
mY = (ym - curGMap -> yc + curGMap -> CY) & clip_mask_y;
|
|
|
|
// UpY = 25;
|
|
y_size = XGR_MAXY - 50;
|
|
x_size = y_size>>(MAP_POWER_Y - MAP_POWER_X);
|
|
|
|
// UpX = (XGR_MAXX-x_size)>>1;
|
|
// UpX = 5;
|
|
|
|
XGR_Line(UpX-1, UpY-1, UpX+x_size, UpY-1, color_boder);
|
|
XGR_Line(UpX-1, UpY+y_size+1, UpX+x_size+1, UpY+y_size+1, color_boder);
|
|
XGR_Line(UpX+x_size+1, UpY-1, UpX+x_size+1, UpY+y_size+1, color_boder);
|
|
XGR_Line(UpX-1, UpY-1, UpX-1, UpY+y_size+1, color_boder);
|
|
|
|
for( i = 0; i < y_size; i++ ){
|
|
XGR_Line(UpX, UpY+i, UpX+x_size, UpY+i, color_back);
|
|
}
|
|
|
|
eBranch* l_branch = branch;
|
|
|
|
for( i = 0; i < n_branch; i++ ){
|
|
l_branch -> show_on_all(UpX, UpY, x_size, y_size);
|
|
l_branch = l_branch -> r;
|
|
}
|
|
|
|
eNode* l_node = node;
|
|
|
|
for( i = 0; i < n_node; i++ ){
|
|
l_node -> show_on_all(UpX, UpY, x_size, y_size);
|
|
l_node = l_node -> r;
|
|
}
|
|
int x1 = UpX + ((mX*x_size)>>MAP_POWER_X);
|
|
int y1 = UpY + ((mY*y_size)>>MAP_POWER_Y);
|
|
|
|
int color_mouse = 142;
|
|
XGR_Line(x1-1, y1-1, x1+1, y1-1, color_mouse);
|
|
XGR_Line(x1-1, y1, x1+1, y1, color_mouse);
|
|
XGR_Line(x1-1, y1+1, x1+1, y1+1, color_mouse);
|
|
}
|
|
|
|
void sTrack::lift_branch(int cBranch ){
|
|
eBranch* l_branch = branch;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch){
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_branch ) ErrH.Abort("Dont Find Branch in lift.");
|
|
|
|
if(branch == l_branch)
|
|
branch = l_branch -> r;
|
|
else {
|
|
l_branch->l->r = l_branch->r;
|
|
l_branch->r->l = l_branch->l;
|
|
|
|
l_branch->r = branch;
|
|
l_branch->l = branch->l;
|
|
|
|
branch->l = l_branch;
|
|
l_branch->l->r = l_branch;
|
|
}
|
|
}
|
|
|
|
void sTrack::recalc_height_branch(int cBranch ){
|
|
eBranch* l_branch = branch;
|
|
int hle, hbc, hlb;
|
|
int hre, hec, hrb;
|
|
|
|
int dhr, dhc, dhl;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch){
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_branch ) ErrH.Abort("Dont Find Branch in recalc_heght.");
|
|
|
|
hlb = l_branch -> data_base[0].hl;
|
|
hbc = l_branch -> data_base[0].h;
|
|
hrb = l_branch -> data_base[0].hr;
|
|
|
|
i = l_branch -> n_section-1;
|
|
|
|
hle = l_branch -> data_base[i].hl;
|
|
hec = l_branch -> data_base[i].h;
|
|
hre = l_branch -> data_base[i].hr;
|
|
|
|
dhl = (hle-hlb)/i;
|
|
dhr = (hre-hrb)/i;
|
|
dhc = (hec-hbc)/i;
|
|
|
|
for ( int j = 1; j < i; j++){
|
|
hlb += dhl;
|
|
hbc += dhr;
|
|
hrb += dhc;
|
|
|
|
l_branch -> data_base[j].hl = hlb;
|
|
l_branch -> data_base[j].h = hbc;
|
|
l_branch -> data_base[j].hr = hrb;
|
|
}
|
|
}
|
|
|
|
int sTrack::check_mouse_work(void){
|
|
int xc, yc;
|
|
|
|
if (!Track_show_all) return( 0 );
|
|
|
|
int mX = XGR_MouseObj.PosX;
|
|
int mY = XGR_MouseObj.PosY;
|
|
|
|
int y_size = XGR_MAXY - 50;
|
|
int x_size = y_size>>(MAP_POWER_Y - MAP_POWER_X);
|
|
|
|
if ( UpY < mY && UpY + y_size > mY && UpX < mX && UpX + x_size > mX) {
|
|
xc = ((mX - UpX)<<MAP_POWER_X)/x_size;
|
|
yc = ((mY - UpY)<<MAP_POWER_Y)/y_size;
|
|
curGMap -> gotoxy( xc, yc );
|
|
return( 1 );
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
void sTrack::recalc_wide_branch(int cBranch, int new_wide ){
|
|
eBranch* l_branch = branch;
|
|
|
|
int i = 0;
|
|
while( l_branch -> index != cBranch && i < n_branch){
|
|
l_branch = l_branch -> r;
|
|
i++;
|
|
}
|
|
|
|
if ( i == n_branch ) ErrH.Abort("Dont Find Branch in recalc new_wide.");
|
|
|
|
for( i = 0; i < l_branch -> n_section; i++){
|
|
l_branch -> data_base[i].wide = new_wide;
|
|
}
|
|
|
|
build_all_node();
|
|
}
|
|
|
|
/*void eBranch::saveKron(XStream& fout)
|
|
{
|
|
int i;
|
|
int n;
|
|
|
|
fout < index;
|
|
|
|
fout < beg_node;
|
|
fout < end_node;
|
|
|
|
for( i = 0, n = 0; i < n_point; i++, n++ ){
|
|
int i1, i2;
|
|
|
|
i1 = find_next_point_in_spline(i,0);
|
|
i2 = find_next_point_in_spline(i,1);
|
|
|
|
if ( i1 < i2 ) i = i1; else i = i2;
|
|
};
|
|
|
|
if ( beg_node > 0 ) n++;
|
|
if ( end_node > 0 ) n++;
|
|
|
|
fout < n;
|
|
int max_noise = 0;
|
|
|
|
for( i = 0; i < n_section; i++ )
|
|
if ( data_base[i].dnoise > max_noise ) max_noise = data_base[i].dnoise;
|
|
|
|
// fout < max_noise;
|
|
|
|
if ( beg_node > 0 ){
|
|
fout < (data_base[0].xl & clip_mask_x);
|
|
fout < data_base[0].yl;
|
|
fout < data_base[0].hl;
|
|
|
|
fout < (data_base[0].xr & clip_mask_x);
|
|
fout < data_base[0].yr;
|
|
fout < data_base[0].hr;
|
|
|
|
}
|
|
|
|
for( i = 0; i < n_point; i++ ){
|
|
int i1, i2;
|
|
|
|
i1 = find_next_point_in_spline(i,0);
|
|
i2 = find_next_point_in_spline(i,1);
|
|
|
|
if ( i1 < i2 ) i = i1; else i = i2;
|
|
|
|
fout < data_all[i].xl;
|
|
fout < data_all[i].yl;
|
|
fout < data_all[i].hl;
|
|
|
|
fout < data_all[i].xr;
|
|
fout < data_all[i].yr;
|
|
fout < data_all[i].hr;
|
|
};
|
|
|
|
if ( end_node > 0 ){
|
|
fout < data_base[n_section-1].xl;
|
|
fout < data_base[n_section-1].yl;
|
|
fout < data_base[n_section-1].hl;
|
|
|
|
fout < data_base[n_section-1].xr;
|
|
fout < data_base[n_section-1].yr;
|
|
fout < data_base[n_section-1].hr;
|
|
}
|
|
|
|
}*/
|
|
|
|
int eBranch::find_next_point_in_spline(int n, int w){
|
|
double sum = 0.0;
|
|
int i, j;
|
|
int a,b;
|
|
double DD = 1;
|
|
double t;
|
|
|
|
for( i = n+2;( (i < n_point)&&(sum/(i-n+1) < DD) ); i++){
|
|
if ( w == 0 ){
|
|
a = data_all[i].xl - data_all[n].xl;
|
|
b = data_all[i].yl - data_all[n].yl;
|
|
|
|
sum = 0.0;
|
|
for( j = n+1; j < i; j++ ){
|
|
t = double(data_all[j].yl*b+data_all[j].xl*a-data_all[n].yl*b-data_all[n].xl*a)/(a*a+b*b);
|
|
|
|
sum += sqrt(sqr(data_all[n].xl+a*t-data_all[j].xl)+sqr(data_all[n].yl+b*t-data_all[j].yl));
|
|
}
|
|
} else {
|
|
a = data_all[i].xr - data_all[n].xr;
|
|
b = data_all[i].yr - data_all[n].yr;
|
|
|
|
sum = 0.0;
|
|
for( j = n+1; j < i; j++ ){
|
|
t = double(data_all[j].yr*b+data_all[j].xr*a-data_all[n].yr*b-data_all[n].xr*a)/(a*a+b*b);
|
|
|
|
sum += sqrt(sqr(data_all[n].xr+a*t-data_all[j].xr)+sqr(data_all[n].yr+b*t-data_all[j].yr));
|
|
}
|
|
} // end if
|
|
} // end for i
|
|
|
|
if ( i >= n_point ) return n_point-1; else return i;
|
|
}
|
|
|