Files
Vangers/surmap/track.cpp

3515 lines
89 KiB
C++
Raw Permalink Normal View History

#include "../src/global.h"
2021-01-15 10:10:58 +07:00
#include "sqint.h"
2021-01-15 10:10:58 +07:00
#include "../src/common.h"
2021-01-15 10:10:58 +07:00
#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"
2021-01-15 10:10:58 +07:00
//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);
2021-01-15 10:10:58 +07:00
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];
2021-02-06 01:42:56 +07:00
data_all = NULL;
2021-01-15 10:10:58 +07:00
l = 0;
r = 0;
}
eBranch::~eBranch(void){
2021-02-06 01:42:56 +07:00
delete[] data_base;
delete[] xpb;
delete[] ypb;
delete[] xpe;
delete[] ype;
if ( data_all != NULL ) delete[] data_all;
2021-01-15 10:10:58 +07:00
}
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){
2021-02-05 23:57:17 +07:00
delete[] xp;
delete[] yp;
delete[] branches;
2021-01-15 10:10:58 +07:00
}
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;
2021-01-15 10:10:58 +07:00
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]
2021-01-15 10:10:58 +07:00
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");
2021-01-15 10:10:58 +07:00
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;
2021-02-06 01:42:56 +07:00
if ( data_all != NULL ) delete[] data_all;
2021-01-15 10:10:58 +07:00
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;
2021-01-15 10:10:58 +07:00
}
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;
}