- TOOBoundingBox=record
- SizeX,SizeY,SizeZ:single;
- vX,vY,vZ:TVector3f;
- mitte:TVector3f;
- end;
- function CalculateLeaveOBB(const daten:TList):TOOBoundingBox;
- var objekt:TTriangle;
- temp:THomogeneousFltVector;
- tempMat:TMatrix4f;
- v1, v2, v3:TVector4f;
- tempMinMax:TMinMax;
- begin
- //Objekt bestimmen
- objekt:=PTriangle(daten[0])^;
- //OBB bestimmen
- temp:=NullVector4;
- result.vZ:=VectorAffineSubtract(objekt.normale,objekt.mitte); //Z Achse ist der Normalen Vektor
- //Y Achse ist der um 90° um die X Achse gedrehte Normalenvektor
- move(result.vZ,temp,sizeof(result.vZ));
- VectorRotate(temp,XVector,pi/2);
- move(temp,Result.vY,sizeof(Result.vY));
- //X Achse ist der um 90° um die Y Achse gedrehte Normalenvektor
- move(result.vZ,temp,sizeof(result.vZ));
- VectorRotate(temp,YVector,pi/2);
- move(temp,Result.vX,sizeof(Result.vX));
- //Jetzt muss das Dreieck so gedreht werden, dass seine Achsen Weltachsen sind:
- //Erstmal Matrix berechnen, um ein Dreieck, das AA ist, zu einem O zu machen
- move(IdentityMatrix4f[3],tempMat[3],sizeof(IdentityMatrix4f)); //Letzte Spalte, Identiy
- tempMat[0][3]:=0; //Letzte Zeile: Identity
- tempMat[1][3]:=0; //Letzte Zeile: Identity
- tempMat[2][3]:=0; //Letzte Zeile: Identity
- move(result.vX,tempMat[0],sizeof(result.vX));
- move(result.vY,tempMat[1],sizeof(result.vY));
- move(result.vZ,tempMat[2],sizeof(result.vZ));
- MatrixInvert(tempMat); //Jetzt erfüllte sie den gegenteiligen Zweck
- //Die Matrix auf alle Punkte anwenden
- v1[3]:=0;
- move(objekt.v1,v1,sizeof(objekt.v1));
- VectorTransform(v1,tempMat);
- v2[3]:=0;
- move(objekt.v2,v2,sizeof(objekt.v2));
- VectorTransform(v2,tempMat);
- v3[3]:=0;
- move(objekt.v3,v3,sizeof(objekt.v3));
- VectorTransform(v3,tempMat);
- //Min und Max für X berechnen
- if v1[0]<v2[0] then begin
- if v2[0]<v3[0] then begin
- tempMinMax.MinX:= v1[0];
- tempMinMax.MaxX:= v3[0];
- end else begin
- if v1[0]<v3[0] then tempMinMax.MinX:= v1[0]
- else tempMinMax.MinX:= v3[0];
- tempMinMax.MaxX:= v2[0];
- end;
- end else begin //v2<v1
- if v1[0]<v3[0] then begin //v2<v1<v3
- tempMinMax.MinX:= v2[0];
- tempMinMax.MaxX:= v3[0];
- end else begin //v3<v2<v1 oder v2<v3<v1
- if v2[0]<v1[0] then tempMinMax.MinX:= v3[0] //v3<v2<v1
- else tempMinMax.MinX:= v2[0]; //v2<v3<v1
- tempMinMax.MaxX:= v1[0];
- end;
- end;
- //Min und Max für Y berechnen
- if v1[1]<v2[1] then begin
- if v2[1]<v3[1] then begin
- tempMinMax.MinY:= v1[1];
- tempMinMax.MaxY:= v3[1];
- end else begin
- if v1[1]<v3[1] then tempMinMax.MinY:= v1[1]
- else tempMinMax.MinY:= v3[1];
- tempMinMax.MaxY:= v2[1];
- end;
- end else begin //v2<v1
- if v1[1]<v3[1] then begin //v2<v1<v3
- tempMinMax.MinY:= v2[1];
- tempMinMax.MaxY:= v3[1];
- end else begin //v3<v2<v1 oder v2<v3<v1
- if v2[1]<v1[1] then tempMinMax.MinY:= v3[1] //v3<v2<v1
- else tempMinMax.MinY:= v2[1]; //v2<v3<v1
- tempMinMax.MaxY:= v1[1];
- end;
- end;
- //Min und Max für Z berechnen
- if v1[2]<v2[2] then begin
- if v2[2]<v3[2] then begin
- tempMinMax.MinZ:= v1[2];
- tempMinMax.MaxZ:= v3[2];
- end else begin
- if v1[2]<v3[2] then tempMinMax.MinZ:= v1[2]
- else tempMinMax.MinZ:= v3[2];
- tempMinMax.MaxZ:= v2[2];
- end;
- end else begin //v2<v1
- if v1[2]<v3[2] then begin //v2<v1<v3
- tempMinMax.MinZ:= v2[2];
- tempMinMax.MaxZ:= v3[2];
- end else begin //v3<v2<v1 oder v2<v3<v1
- if v2[2]<v1[2] then tempMinMax.MinZ:= v3[2] //v3<v2<v1
- else tempMinMax.MinZ:= v2[2]; //v2<v3<v1
- tempMinMax.MaxZ:= v1[2];
- end;
- end;
- Result.SizeX:=(tempminMax.MaxX-tempminMax.MinX)/2;
- Result.SizeY:=(tempminMax.MaxY-tempminMax.MinY)/2;
- Result.SizeZ:=(tempminMax.MaxZ-tempminMax.MinZ)/2;
- result.mitte:=objekt.mitte;
- end;