/* (c) Daniel Lichtenberger 28.1.97-??
6.4.98: an ALLEGRO angepaát ->
VESA 2.0 - Support, Pageflipping
und entgltig zur Include-Datei
"degradiert" (Testprogramm 3d_test.cc) */
#define fakt 8192
#define faktshift 13
#define coordfakt 128
#define coordshift 7
int sintable[361],costable[361];
#include "_vector.cc"
BITMAP *BaseAddr;
int ScrWidth,ScrHeight;
#include "_dlline.c"
#define angle 45 // "Blickwinkel"
#define Grad(x) ((x/PI)*180) /* Bogenmaá -> Grad */
#define Rad(x) ((x/180)*PI) /* Grad -> Bogenmaá */
typedef struct {
int nr;
int Intense;
int tex_x,tex_y; // Koordinaten innerhalb der Textur (falls
// Texture Mapping verwendet wird, bei Gouraud bedeutungslos)
} TPointRef; /* Fr die TBody-Klasse */
typedef struct {
int ref[100]; // Nummer des K”rpers usw.
int dist[100]; // Entfernung (= z-Koordinate)
} TZBuf;
/* TPoly: NICHT fr den Gebrauch in TBody, da TPoly ein v”llig eigenst„ndiges
Polygon darstellt */
class TPoly {
TVector PolyPoints[10];
char nPoint;
public:
TPoly() { nPoint = 0; }
void SetPoint(int x,int y,int z,char nr) { PolyPoints[nr].x = x; PolyPoints[nr].y = y; PolyPoints[nr].z = z; }
void AddPoint(int x,int y,int z) { SetPoint(x,y,z,nPoint); nPoint++; }
void SetnPoint(char n) { nPoint = n; }
char GetnPoint() { return(nPoint); }
};
/* TBody: Die einzelnen Polygone bestehen nur aus Verweisen auf das BodyPoints-
Punke-Array, aber nicht aus "echten" Koordinaten */
class TBody {
protected:
TVector BodyPointsOrig[20]; // Nicht nicht-rotierten Eckpunkte
TVector PolySchwp[20]; // Die Schwerpunkte der einzelnen Polygone
TVector Schwerpunkt;
int ShadeLight; // Werden die Polygone von einer Lichtquelle beleuchtet
int TextureMapping; // Wird der K”rper "gemappt", bei 0 -> Gouraud Shading
BITMAP *PaintAddr; // Die Bitmap, wo der K”rper gezeichnet werden soll
public:
int ColorRange[20][2]; // Bereich der Farbpalette, in dem Abstufungen der Grundfarbe zu finden sind (z.B. alle Rotstufen) - [0] = Start [1] = Ende
BITMAP *Textures[20]; // Zeiger auf die Texturen fr alle Polygone
TVector BodyPoints[20]; // Alle Eckpunkte des K”rpers
TPointRef Poly[20][10]; // 1. Zahl - Nummer des Polygons / 2. Zahl - z.B. 4. Punkt des 2. Polygons Poly[2][4]
int nBodyPoint,nPoly;
TVector2D TranslPoints[20]; // Die auf den Bildschirm transformierten Eckpunkte
int nPoint[20]; // Anzahl der Punkte fr jedes Polygon
int RecalcTrans; // Muá die Position der transformierten Punkte auf dem Bildschirm neu berechnet werden?
int DrawLines; // sollen die Begrenzungslinien & Eckpunkte gezeichnet werden?
int AktPoint; // Dieser Punkt wird hervorgehoben (v.a. fr Editoren)
int AktPoly; // Dieses Polygon wird in anderer Farbe gezeichnet (-> Editoren)
TBody() { nBodyPoint = 0; nPoly = 0; ShadeLight = 0;
RecalcTrans = 1; DrawLines = 0; TextureMapping = 0; }
void SetPaintAddr(BITMAP *bmp) { PaintAddr = bmp; }
void SetShade(int on) { ShadeLight = on; }
void SetMapping(int on) { TextureMapping = on; }
void SetBodyPoint(int x,int y,int z,char n) { BodyPoints[n].x = x << coordshift; BodyPoints[n].y = y << coordshift; BodyPoints[n].z = z << coordshift; RecalcTrans = 1; }
void AddBodyPoint(int x,int y,int z) { SetBodyPoint(x,y,z,nBodyPoint); nBodyPoint++; }
TVector GetBodyPoint(int nr) { return BodyPoints[nr]; }
void SetOrigPoints(void);
TVector GetSchwerpunkt(void) { return Schwerpunkt; }
void AddPoly(int RangeStart,int RangeEnd) { ColorRange[nPoly][0] = RangeStart; ColorRange[nPoly][1] = RangeEnd; nPoint[nPoly] = 0; nPoly++; }
void DelPoly(int nr);
void SetPolyPoint(char refnr,unsigned char intense,char nPol,char nPnt) { Poly[nPol][nPnt].nr = refnr; Poly[nPol][nPnt].Intense = intense; }
void AddPolyPoint(char refnr,unsigned char intense,char nPol) { SetPolyPoint(refnr,intense,nPol,nPoint[nPol]); nPoint[nPol]++; }
/* _AddPolyPoint: Wie AddPolyPoint, allerdings wird automatisch das letzte
Polygon verwendet */
void _AddPolyPoint(char refnr,unsigned char intense) { AddPolyPoint(refnr,intense,nPoly-1); }
void SetTexture(int polynr, BITMAP *bmp) { Textures[polynr] = bmp; }
void CalcSchwerpunkt();
void Translate(TVector v);
void Scale(int sx,int sy,int sz); // Der K”rper wird um die Faktoren sx,sy und sz gestreckt / 1 = coordfakt
void TranslateTranslPoints(TVector2D v); // Es wird nur die Position des K”rpers am Bildschirm ge„ndert, fr Spielereien
void RotateX(int rotangle);
void RotateY(int rotangle);
void RotateZ(int rotangle);
void Draw();
void PrintPoly();
};
class TComplexBody {
protected:
TZBuf BodyZBuf;
TVector Schwerpunkt;
BITMAP *PaintAddr;
public:
int nBodies;
TBody *bodies[20];
int DrawLines;
TComplexBody() { nBodies = 0; }
TBody *GetBody(int n) { return(bodies[n]); }
int GetNBodies() { return nBodies; }
void SetBody(TBody *tb,int n) { bodies[n] = tb; }
void SetnBodies(int n) { nBodies = n; }
void Draw();
void DelBody(int nr);
void Translate(TVector v) { int i; for (i = 0; i < nBodies; i++) bodies[i]->Translate(v); Schwerpunkt = Schwerpunkt+v; }
void SetPaintAddr(BITMAP *adr) { int i; PaintAddr = adr; for (i = 0; i < nBodies; i++) bodies[i]->SetPaintAddr(adr); }
void SetShade(int on) { int i; for (i = 0; i < nBodies; i++) bodies[i]->SetShade(on); }
void SetOrigPoints() { int i; for (i = 0; i < nBodies; i++) bodies[i]->SetOrigPoints(); }
void SetDrawLines(int DL) { int i; for (i = 0; i < nBodies; i++) bodies[i]->DrawLines = DL; }
void CalcSchwerpunkt();
};
class TViewPoint {
public:
TVector at,up,from;
TViewPoint() { }
void SetAt(int x,int y,int z) { at.x = x; at.y = y; at.z = z; }
void SetUp(int x,int y,int z) { up.x = x; up.y = y; up.z = z; }
void SetFrom(int x,int y,int z) { from.x = x; from.y = y; from.z = z; }
TVector GetAt(void) { return at; }
TVector GetFrom(void) { return from; }
TVector GetUp(void) { return up; }
void SetViewPoint(); /* Macht diesen Viewpoint zum aktuellen Vp. fr alle
Transformationen. Auáerdem werden alle notwendigen
globalen Variablen berechnet */
};
/* -----------------------------------------------------------------------
----------------------------------------------------------------------- */
int RotateOrig; // Wird der Ursprungsk”rper rotiert (BodyPointsOrig), oder der eventuell bereits rotierte (BodyPoints)?
double DVal;
int DVal_Int;
TVector a1,a2,a3;
int offset_x,offset_y,offset_z;
int W2Dev_a,W2Dev_c,W2Dev_d;
TVector light;
int LightBetr;
TViewPoint viewpoint;
TZBuf ZBuf; // Die K”rper, nach Entfernung geordnet
int nDraw;
// -----------------------------------------------------------------------
#include "3d_add.cc"
// -----------------------------------------------------------------------
// --------------- Die Texture-Mapping-Routinen --------------- (c) DL
// DrawTxtLine: Zeichnet eine (horizontale) Linie, deren Pixel aus einer Geraden zwischen x1/y1 und x2/y2 aus der Textur txt kommen
// x1,y1,x2,y2: Start/End-Punkte einer Linie in der Textzre
// len: Die L„nge der horizontalen Linie
// xscr,yscr: Die Startposition der Linie auf dem Bildschirm
// *txt: Zeiger auf eine Bitmap
// txtw,txth: Dimensionen der Textur
void DrawTxtLine(int x1,int y1,int x2,int y2,int len,int xscr,int yscr, unsigned char *txt, int txtw,int txth) {
TInterpol ipol;
unsigned char pix,*scrp;
int xpc,x,y,dx,dy,offset; // (Achtung: x,y beziehen sich auf Koordinaten innerhalb der Textur, nicht auf den Bildschirm!!)
if (len <= 0) return;
dx = ((x2-x1) << faktshift) / len;
dy = ((y2-y1) << faktshift) / len;
x = x1 << faktshift;
y = y1 << faktshift;
xpc = xscr;
scrp = (unsigned char *)BaseAddr+yscr*ScrWidth+xpc;
do {
offset = (y >> faktshift)*txtw+(x >> faktshift);
if ((offset < txtw*txth) || (offset > 0))
*scrp = txt[offset];
x += dx;
y += dy;
scrp++;
xpc++;
} while (xpc < xscr+len);
}
// Prft, ob das Polygon sichtbar ist (unsichtbar, wenn das Polygon
// entgegen dem Uhrzeigersinn gespeichert ist), prft auáerdem,
// ob das Polygon berhaupt auf dem Bildschirm liegt
// Entnommen aus DL_HLineGouraud256, deshalb etwas lang
int IsPolyVisible(char nPoint,int points[][2]) {
int x,y;
int i,top_point,bottom_point,top_point2; /* Der h”chste und der niedrigste Punkt des Polygons */
int point_left,point_right,opoint; /* Nummer des akt. rechten/linken Eckpunktes des Polygons */
int leftswap,rightswap;
int top_y,bottom_y;
TInterpol ipol_left,ipol_right; /* Interpolationsvariablen fr beide Seiten */
int left_x,right_x; /* x-Koordinate des interpolierten linken/rechten Punkts */
int leftpointx,leftpointy;
int rightpointx,rightpointy;
top_y = 0xFFFF; /* Vorsicht: "top" bedeutet NIEDRIGE y-Koordinate */
bottom_y = -0xFFFF;
for (i = 0; i < nPoint; i++) { /* H”chsten und niedrigsten Punkt des Polygons finden */
x = points[i][0];
y = points[i][1];
if (y <= top_y) {
if (y == top_y) top_point2 = i;
else {
top_y = y;
top_point = top_point2 = i;
}
}
if (y > bottom_y) {
bottom_y = y;
bottom_point = i;
}
}
if ((bottom_y-top_y < 1) || ((top_y <= 0) && (bottom_y <= 0)) ||
((top_y >= ScrHeight) && (bottom_y >= ScrHeight))) return(0);
if ((top_point != top_point2) && (top_point == 0) && (top_point2 == nPoint-1) &&
(points[top_point][0] < points[top_point2][0])) return(0);
/* Annahme: Polygon ist im Uhrzeigersinn gespeichert */
point_left = top_point-1; if (point_left < 0) point_left = nPoint-1;
if (point_left == top_point2) point_left--;
point_right = top_point2+1; if (point_right > nPoint-1) point_right = 0;
if (point_right == top_point) point_right++;
if (points[top_point][0] > points[top_point2][0])
if ((top_point == 0) && (top_point2 == nPoint-1)) xchg(top_point,top_point2);
else
if (!drawback) return(0);
else xchg(top_point,top_point2);
leftpointx = points[point_left][0]; leftpointy = points[point_left][1];
rightpointx = points[point_right][0]; rightpointy = points[point_right][1];
SetLine_Interpol(points[top_point][0],points[top_point][1],
leftpointx,leftpointy,&ipol_left);
SetLine_Interpol(points[top_point2][0],points[top_point2][1],
rightpointx,rightpointy,&ipol_right);
leftswap = ipol_left.swp;
rightswap = ipol_right.swp;
/* --------- Die Hauptschleife ---------------- */
for (y = top_y; y <= bottom_y; y++) {
if (leftswap) {
left_x = ipol_left.ipcoord;
Do_Interpol(&ipol_left);
}
else {
left_x = ipol_left.fcoord;
if (ipol_left.Dec_a)
do { } while (!Do_Interpol(&ipol_left));
}
if (rightswap) {
right_x = ipol_right.ipcoord;
Do_Interpol(&ipol_right);
}
else {
right_x = ipol_right.fcoord;
if (ipol_right.Dec_a)
do { } while (!Do_Interpol(&ipol_right));
}
if (left_x > right_x) return(0);
else ;
/* --- Eventuell neue Eckpunkte setzen ---- */
if (y == leftpointy) { /* Wenn eine linke Kante fertiggezeichnet ist, neuen Punkt berechnen */
opoint = point_left;
point_left--;
if (point_left < 0) point_left += nPoint;
else if (point_left > nPoint-1) point_left -= nPoint;
leftpointx = points[point_left][0]; leftpointy = points[point_left][1];
SetLine_Interpol(points[opoint][0],points[opoint][1],
leftpointx,leftpointy,&ipol_left);
leftswap = ipol_left.swp;
}
if (y == rightpointy) { /* Fr die rechte Kante ebenso.... */
opoint = point_right;
point_right++;
if (point_right < 0) point_right += nPoint;
else if (point_right > nPoint-1) point_right -= nPoint;
rightpointx = points[point_right][0]; rightpointy = points[point_right][1];
SetLine_Interpol(points[opoint][0],points[opoint][1],
rightpointx,rightpointy,&ipol_right);
rightswap = ipol_right.swp;
}
}
return(1);
}
void ZSort(TBody *body[],int nBodies,TZBuf *zbuf) {
int i,k,j,nz,point,zmax;
TVector v;
TVector2D v2d;
for (i = 0; i < 50; i++) {
zbuf->ref[i] = 0;
zbuf->dist[i] = -0xFFFFFFFF;
}
nDraw = 0;
for (i = 0; i < nBodies; i++) {
v = body[i]->GetSchwerpunkt() >> coordshift;
nz = v.x*a3.x + a3.y*v.y + a3.z*v.z + offset_z;
/* zmax = 0;
for (point = 0; point < body[i]->nBodyPoint; point++) {
v = body[i]->BodyPoints[point] >> coordshift;
nz = v.x*a3.x + a3.y*v.y + a3.z*v.z + offset_z;
if (nz > zmax) zmax = nz;
}*/
if (nz > 0) {
k = 0;
while ((zbuf->dist[k] > nz) && (k < i)) k++;
for (j = i+1; j > k; j--) {
zbuf->ref[j] = zbuf->ref[j-1];
zbuf->dist[j] = zbuf->dist[j-1];
}
zbuf->ref[k] = i;
zbuf->dist[k] = nz;
nDraw++;
}
}
}
/* -----------------------------------------------------------------------
----------------------------------------------------------------------- */
void TViewPoint::SetViewPoint() {
TVector_Real _at,_from,_up;
TVector_Real _a1,_a2,_a3;
TVector_Real temp,temp2;
// DVal = 1/(sin(0.39)/cos(0.39));
// DVal_Int = (int)(DVal*fakt);
DVal_Int = 14188;
_at.x = at.x; _at.y = at.y; _at.z = at.z;
_from.x = from.x; _from.y = from.y; _from.z = from.z;
_up.x = up.x; _up.y = up.y; _up.z = up.z;
temp2 = _at-_from;
_a3 = temp2/Betrag_Real(temp2);
KreuzProdukt_Real(_up,temp2,&temp);
_a1 = temp/Betrag_Real(temp);
KreuzProdukt_Real(_a3,_a1,&temp);
_a2 = temp/Betrag_Real(temp);
a1.x = (int)(_a1.x*fakt); a1.y = (int)(_a1.y*fakt); a1.z = (int)(_a1.z*fakt);
a2.x = (int)(_a2.x*fakt); a2.y = (int)(_a2.y*fakt); a2.z = (int)(_a2.z*fakt);
a3.x = (int)(_a3.x*fakt); a3.y = (int)(_a3.y*fakt); a3.z = (int)(_a3.z*fakt);
offset_x = -from.x*a1.x-from.y*a1.y-from.z*a1.z;
offset_y = -a2.x*from.x-a2.y*from.y-a2.z*from.z;
offset_z = -a3.x*from.x-a3.y*from.y-a3.z*from.z;
}
void TBody::SetOrigPoints() {
int i;
for (i = 0; i < nBodyPoint; i++)
CopyVector(BodyPoints[i],&BodyPointsOrig[i]);
}
void TBody::Draw() {
int i,k;
int nx,ny,nz;
int xpc,ypc;
char nr;
unsigned char *scrp;
int points[10][2];
int colors[10];
int LightAngle,DeltaColor;
TVector NormV,v1,v2;
int b;
V3D *AllegPoints[10];
for (i = 0; i < 10; i++)
AllegPoints[i] = malloc(24);
if (RecalcTrans) {
RecalcTrans = 0;
if (!IsOnScreen(Schwerpunkt)) return;
for (i = 0; i < nBodyPoint; i++)
if (!TransformXYZ(BodyPoints[i],&TranslPoints[i])) return;
}
drawback = 0;
for (i = 0; i < nPoly; i++) {
if (!TextureMapping) { // Gouraudshading
if (ShadeLight) {
v1 = BodyPoints[Poly[i][1].nr]-BodyPoints[Poly[i][0].nr];
v2 = BodyPoints[Poly[i][2].nr]-BodyPoints[Poly[i][1].nr];
v1 = v1 >> coordshift;
v2 = v2 >> coordshift;
KreuzProdukt(v1,v2,&NormV);
b = Betrag(NormV);
if (b > 1000000) {
NormV = NormV >> 10;
b >>= 10;
}
LightAngle = CalcAngle2(light,NormV,LightBetr,b);
if (LightAngle < 0)
DeltaColor = -LightAngle >> 10;
else DeltaColor = 0;
} else DeltaColor = 0;
for (k = 0; k < nPoint[i]; k++) {
nr = Poly[i][k].nr;
colors[k] = Poly[i][k].Intense+DeltaColor;
if (colors[k] > ColorRange[i][1]) colors[k] = ColorRange[i][1]-1;
points[k][0] = TranslPoints[nr].x;
points[k][1] = TranslPoints[nr].y;
}
DL_FillPolyGouraud(nPoint[i],points,colors);
}
else { // Texturemapping
for (k = 0; k < nPoint[i]; k++) {
nr = Poly[i][k].nr;
AllegPoints[k]->x = itofix(TranslPoints[nr].x);
AllegPoints[k]->y = itofix(TranslPoints[nr].y);
AllegPoints[k]->z = itofix(100);
AllegPoints[k]->u = itofix(Poly[i][k].tex_x);
AllegPoints[k]->v = itofix(Poly[i][k].tex_y);
points[k][0] = TranslPoints[nr].x;
points[k][1] = TranslPoints[nr].y;
}
// Die Adresse ist BaseAddr (muá im Hauptprogramm definiert werden), aus Kompatibilt„tsgrnden
if (IsPolyVisible(nPoint[i],points))
polygon3d(BaseAddr,POLYTYPE_ATEX,Textures[i],nPoint[i],AllegPoints);
}
if (DrawLines) {
for (k = 0; k < nPoint[AktPoly]; k++) {
nr = Poly[AktPoly][k].nr;
colors[k] = 9;
points[k][0] = TranslPoints[nr].x;
points[k][1] = TranslPoints[nr].y;
}
drawback = 1;
DL_FillPolyGouraud(nPoint[AktPoly],points,colors);
drawback = 0;
for (k = 0; k < nBodyPoint; k++)
if (k == AktPoint) putpixel(BaseAddr,TranslPoints[k].x,TranslPoints[k].y,255);
else putpixel(BaseAddr,TranslPoints[k].x,TranslPoints[k].y,5);
}
}
}
void TBody::PrintPoly() {
int i,k;
char nr;
printf("\nSchwerpunkt: (%d/%d/%d)\n",Schwerpunkt.x >> coordshift,Schwerpunkt.y >> coordshift,Schwerpunkt.z >> coordshift);
for (i = 0; i < nPoly; i++) {
printf("\nPolygon #%d: %d Punkte\n",i,nPoint[i]);
for (k = 0; k < nPoint[i]; k++) {
nr = Poly[i][k].nr;
printf(" (%d/%d/%d),",BodyPoints[nr].x >> coordshift,BodyPoints[nr].y >> coordshift,BodyPoints[nr].z >> coordshift);
}
}
}
void TBody::CalcSchwerpunkt() {
int i,k;
TVector Schwp;
ClearVector(Schwerpunkt);
for (i = 0; i < nPoly; i++) {
ClearVector(Schwp);
for (k = 0; k < nPoint[i]; k++)
Schwp = Schwp+BodyPoints[Poly[i][k].nr];
Schwp = Schwp/nPoint[i];
CopyVector(Schwp,&PolySchwp[i]);
Schwerpunkt = Schwerpunkt+Schwp;
}
Schwerpunkt = (Schwerpunkt/nPoly);
}
void TBody::Translate(TVector v) {
int i;
RecalcTrans = 1;
for (i = 0; i < nBodyPoint; i++) {
BodyPoints[i] = BodyPoints[i]+v;
BodyPointsOrig[i] = BodyPointsOrig[i]+v;
}
Schwerpunkt = Schwerpunkt+v;
}
void TBody::TranslateTranslPoints(TVector2D v) {
int i;
for (i = 0; i < nBodyPoint; i++)
TranslPoints[i] = TranslPoints[i]+v;
}
void TBody::Scale(int sx,int sy,int sz) {
int i;
TVector tmp;
RecalcTrans = 1;
CopyVector(Schwerpunkt,&tmp);
NegVector(tmp);
Translate(tmp);
for (i = 0; i < nBodyPoint; i++) {
BodyPoints[i].x = (BodyPoints[i].x*sx) >> coordshift;
BodyPoints[i].y = (BodyPoints[i].y*sy) >> coordshift;
BodyPoints[i].z = (BodyPoints[i].z*sz) >> coordshift;
CopyVector(BodyPoints[i],&BodyPointsOrig[i]);
}
NegVector(tmp);
Translate(tmp);
}
void TBody::RotateX(int rotangle) {
TVector OldSchwp,tmp;
int i;
RecalcTrans = 1;
CopyVector(Schwerpunkt,&OldSchwp);
CopyVector(Schwerpunkt,&tmp);
NegVector(tmp);
Translate(tmp); // Der K”rper kann nur im Nullpunkt gedreht werden
if (RotateOrig)
for (i = 0; i < nBodyPoint; i++)
v_RotateX(BodyPointsOrig[i],rotangle,&BodyPoints[i]);
else
for (i = 0; i < nBodyPoint; i++)
v_RotateX(BodyPoints[i],rotangle,&BodyPoints[i]);
Translate(OldSchwp);
}
void TBody::RotateY(int rotangle) {
TVector OldSchwp,tmp;
int i;
RecalcTrans = 1;
CopyVector(Schwerpunkt,&OldSchwp);
CopyVector(Schwerpunkt,&tmp);
NegVector(tmp);
Translate(tmp); // Der K”rper kann nur im Nullpunkt gedreht werden
if (RotateOrig)
for (i = 0; i < nBodyPoint; i++)
v_RotateY(BodyPointsOrig[i],rotangle,BodyPoints[i]);
else
for (i = 0; i < nBodyPoint; i++)
v_RotateY(BodyPoints[i],rotangle,BodyPoints[i]);
Translate(OldSchwp);
}
void TBody::RotateZ(int rotangle) {
TVector OldSchwp,tmp;
int i;
RecalcTrans = 1;
CopyVector(Schwerpunkt,&OldSchwp);
CopyVector(Schwerpunkt,&tmp);
NegVector(tmp);
Translate(tmp); // Der K”rper kann nur im Nullpunkt gedreht werden
if (RotateOrig)
for (i = 0; i < nBodyPoint; i++)
v_RotateZ(BodyPointsOrig[i],rotangle,&BodyPoints[i]);
else
for (i = 0; i < nBodyPoint; i++)
v_RotateZ(BodyPoints[i],rotangle,&BodyPoints[i]);
Translate(OldSchwp);
}
void TBody::DelPoly(int nr) {
int i,k;
if (nPoly <= 1) return;
for (i = nr; i < nPoly-1; i++) {
for (k = 0; k < nPoint[i+1]; k++)
Poly[i][k] = Poly[i+1][k];
nPoint[i] = nPoint[i+1];
PolySchwp[i] = PolySchwp[i+1];
ColorRange[i][0] = ColorRange[i+1][0];
ColorRange[i][1] = ColorRange[i+1][1];
}
nPoly--;
}
void TComplexBody::Draw() {
int i;
ZSort(bodies,nBodies,&BodyZBuf);
for (i = 0; i < nDraw; i++) {
bodies[BodyZBuf.ref[i]]->RecalcTrans = 1;
bodies[BodyZBuf.ref[i]]->Draw();
}
}
void TComplexBody::DelBody(int nr) {
int i;
if (nBodies <= 1) return;
for (i = nr; i < nBodies-1; i++)
bodies[i] = bodies[i+1];
// free(bodies[nBodies-1]);
nBodies--;
CalcSchwerpunkt();
}
void TComplexBody::CalcSchwerpunkt() {
int i;
TVector Schwp;
ClearVector(Schwp);
for (i = 0; i < nBodies; i++) {
bodies[i]->CalcSchwerpunkt();
Schwp = Schwp+bodies[i]->GetSchwerpunkt();
}
Schwerpunkt = Schwp / nBodies;
}
void DrawAllBodies(int nBody, TBody *bodies[]) {
int i;
ZSort(bodies,nBody,&ZBuf);
for (i = 0; i < nDraw; i++) {
bodies[ZBuf.ref[i]]->RecalcTrans = 1;
bodies[ZBuf.ref[i]]->Draw();
}
}
void LoadBody(int n, char *fn, TBody *bodies[]) {
bodies[n] = new TBody;
Read3DBody(fn,bodies[n]);
bodies[n]->SetShade(1);
bodies[n]->CalcSchwerpunkt();
bodies[n]->SetOrigPoints();
}
void LoadComplexBody(int n, char *fn, TComplexBody *complexbodies[]) {
complexbodies[n] = new TComplexBody;
ReadComplex3DBody(fn,complexbodies[n]);
complexbodies[n]->SetShade(1);
complexbodies[n]->CalcSchwerpunkt();
complexbodies[n]->SetOrigPoints();
}
void Init3D() { // Erst NACH der Initialisierung des Grafikmodus' aufrufen!!
int i;
W2Dev_a = ScrWidth/2;
W2Dev_c = -ScrHeight/2;
W2Dev_d = ScrHeight + W2Dev_c;
drawback = 0;
for (i = 0; i <= 360; i++) {
sintable[i] = (int)(sin(Rad((float)i))*fakt);
costable[i] = (int)(cos(Rad((float)i))*fakt);
}
}