Simon's object placement fix

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@6608 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: d1baa2819c5983337362a1b4ca3f1cb188d4f046
Former-commit-id: 296366b1cba8c158003092ebfcb4ef2814b1612e
This commit is contained in:
beaglejoe 2019-02-15 18:26:25 +00:00
parent d21c2931c9
commit d0a3289fff
4 changed files with 130 additions and 3 deletions

View file

@ -720,6 +720,8 @@ typedef struct Track
#define TRK_ATT_FINISH "finish segment"
#define TRK_ATT_BORDER_DISTANCE "border distance"
#endif /* _TRACKV1_H_ */

View file

@ -81,11 +81,12 @@ public:
typedef struct objdef
{
GF_TAILQ_ENTRY(objdef) link;
int random, trackOriented, terrainOriented;
int random, trackOriented, terrainOriented, borderOriented;
unsigned int color;
ssgEntity *obj;
tdble deltaHeight;
tdble deltaVert;
float distance;
} tobjdef;
GF_TAILQ_HEAD(objlist, objdef);
@ -173,6 +174,10 @@ InitObjects(tTrack *track, void *TrackHandle)
if (strcmp(GfParmGetCurStr(TrackHandle, TRK_SECT_OBJECTS, TRK_ATT_ORIENTATION_TYPE, ""), "terrain") == 0) {
curObj->terrainOriented = 1;
} else {curObj->terrainOriented =0;}
if (strcmp(GfParmGetCurStr(TrackHandle, TRK_SECT_OBJECTS, TRK_ATT_ORIENTATION_TYPE, ""), "border") == 0) {
curObj->borderOriented = 1;
curObj->distance = GfParmGetCurNum(TrackHandle, TRK_SECT_OBJECTS, TRK_ATT_BORDER_DISTANCE, NULL, 1.0);
} else {curObj->borderOriented =0;}
GF_TAILQ_INSERT_HEAD(&objhead, curObj, link);
GfParmListSeekNext(TrackHandle, TRK_SECT_OBJECTS);
@ -204,6 +209,8 @@ AddObject(tTrack *track, void *TrackHandle, unsigned int clr, tdble x, tdble y)
ssgEntity *obj;
sgMat4 m;
tdble dv=0, angle=0;
float z=0;
float xNeu, yNeu, zNeu;
for (curObj = GF_TAILQ_FIRST(&objhead); curObj; curObj = GF_TAILQ_NEXT(curObj, link)) {
if (clr == curObj->color) {
@ -224,9 +231,26 @@ AddObject(tTrack *track, void *TrackHandle, unsigned int clr, tdble x, tdble y)
/* NEW: calculate angle for track-aligned orientation */
angle= getTrackAngle(track, TrackHandle, x, y);
}
if (curObj->borderOriented) {
/* NEW: calculate angle for border-aligned orientation */
angle= getBorderAngle(track, TrackHandle, x, y, curObj->distance, &xNeu, &yNeu, &zNeu);
//noch was mit x und y machen
x= xNeu;
y= yNeu;
z= zNeu;
printf("tried to align to border: x: %g y: %g z: %g angle: %g \n", x, y, z);
}
else
{
z=getHOT(TrackRoot, x, y);
}
printf("placing object so: x: %g y: %g z: %g \n", x, y, z);
sgMakeRotMat4(m, angle, dv / 2.0 - dv * rand() / (RAND_MAX + 1.0), dv / 2.0 - dv * rand() / (RAND_MAX + 1.0));
ApplyTransform(m, obj);
sgMakeTransMat4(m, x, y, getHOT(TrackRoot, x, y));
sgMakeTransMat4(m, x, y, z);
ApplyTransform(m, obj);
AddToRoot(obj);
return;
@ -477,7 +501,7 @@ GenerateObjects(tTrack *track, void *TrackHandle, void *CfgHandle, FILE *save_fd
sprintf(buf, "tracks/%s/%s/%s", track->category, track->internalname, map);
printf("Processing object map %s\n", buf);
MapImage = GfTexReadImageFromPNG(buf, 2.2, &width, &height, 0, 0);
MapImage = GfTexReadImageFromPNG(buf, 2.2, &width, &height, 0, 0, false);
if (!MapImage) {
return;
}

View file

@ -197,6 +197,106 @@ float getTrackAngle(tTrack *Track, void *TrackHandle, float x, float y)
return angle;
}
/*
* same thing for border alignment, just one difference: a new position
* x/y/z is returned to keep it aligned with the track in distance & height
* need additional input in xml object definition:
* <attnum...
*
*/
float getBorderAngle(tTrack *Track, void *TrackHandle, float x, float y, float distance, float *xRet, float *yRet, float *zRet )
{
float angle=0, dst=100000, shDst=100000;
int i;
tTrackSeg *seg = Track->seg;
tTrkLocPos curPos, closePos, objPos;
float x2, y2, x3, y3;
for(i = 0; i < Track->nseg; i++)
{
seg=seg->next;
curPos.seg=seg;
curPos.toMiddle=0;
switch (seg->type) {
case TR_STR:
for (float toStart=0; toStart<seg->length; toStart+=(seg->length/5.0))
{
curPos.toStart=toStart;
RtTrackLocal2Global(&curPos, &x2, &y2, TR_TOMIDDLE);
dst=Distance(x,y,0,x2,y2,0);
//printf("distance: %g\n",dst);
if ( dst < shDst ){
shDst=dst;
closePos=curPos;
}
}
break;
case TR_RGT:
for (float toStart=0; toStart<seg->arc; toStart+=(seg->arc/5.0))
{
curPos.toStart=toStart;
RtTrackLocal2Global(&curPos, &x2, &y2, TR_TOMIDDLE);
dst=Distance(x,y,0,x2,y2,0);
//printf("distance: %g\n",dst);
if ( dst < shDst ){
shDst=dst;
closePos=curPos;
}
}
break;
case TR_LFT:
for (float toStart=0; toStart<seg->arc; toStart+=(seg->arc/10.0))
{
curPos.toStart=toStart;
RtTrackLocal2Global(&curPos, &x2, &y2, TR_TOMIDDLE);
dst=Distance(x,y,0,x2,y2,0);
//printf("distance: %g\n",dst);
if ( dst < shDst ){
shDst=dst;
closePos=curPos;
}
}
break;
}
}
//check if left or right
curPos=closePos;
seg=curPos.seg;
//check if left or right
RtTrackGlobal2Local(seg, x, y, &objPos, 1);
if ( objPos.toMiddle < 0 )
// object on right side
{
curPos.toRight = 0;
objPos.toRight = -distance;
RtTrackLocal2Global(&curPos, &x3, &y3, TR_TORIGHT);
curPos.toStart+=0.001;
RtTrackLocal2Global(&curPos, &x2, &y2, TR_TORIGHT);
angle=-90.0-atan2f(x2-x3,y2-y3)*180/PI;
RtTrackLocal2Global(&objPos, &*xRet, &*yRet, TR_TORIGHT);
}
else
// left side
{ curPos.toLeft = 0;
objPos.toLeft = -distance;
RtTrackLocal2Global(&curPos, &x3, &y3, TR_TOLEFT);
curPos.toStart+=0.001;
RtTrackLocal2Global(&curPos, &x2, &y2, TR_TOLEFT);
angle=90.0-atan2f(x2-x3,y2-y3)*180/PI;
RtTrackLocal2Global(&objPos, &*xRet, &*yRet, TR_TOLEFT);
}
*zRet=RtTrackHeightG(seg, *xRet, *yRet);
printf("tried to align to border: x: %g y: %g z: %g angle: %g \n", *xRet, *yRet, *zRet, angle);
//return values
return angle;
}
/*
* calculates an angle based on plane equation (face normal) of the
* terrain in this spot. * Angle is determined so that the x axis is

View file

@ -32,6 +32,7 @@ extern int GetFilename(const char *filename, const char *filepath, char *buf);
extern float getHOT(ssgRoot *root, float x, float y);
extern float getTerrainAngle(ssgRoot *root, float x, float y);
extern float getTrackAngle(tTrack *Track, void *TrackHandle, float x, float y);
extern float getBorderAngle(tTrack *Track, void *TrackHandle, float x, float y, float distance, float *xRet, float *yRet, float *zRet);
extern tdble Distance(tdble x0, tdble y0, tdble z0, tdble x1, tdble y1, tdble z1);
/* Use the texture name to select options like mipmap */