diff options
Diffstat (limited to 'binfilter/bf_goodies/source/base3d/goodies_b3dgeom.cxx')
-rw-r--r-- | binfilter/bf_goodies/source/base3d/goodies_b3dgeom.cxx | 852 |
1 files changed, 0 insertions, 852 deletions
diff --git a/binfilter/bf_goodies/source/base3d/goodies_b3dgeom.cxx b/binfilter/bf_goodies/source/base3d/goodies_b3dgeom.cxx deleted file mode 100644 index 048f66d17eb3..000000000000 --- a/binfilter/bf_goodies/source/base3d/goodies_b3dgeom.cxx +++ /dev/null @@ -1,852 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "b3dgeom.hxx" - -#include "b3dcompo.hxx" - -#include "hmatrix.hxx" - -#include "base3d.hxx" - -#include <tools/debug.hxx> - -#ifndef _INC_MATH -#include <math.h> -#endif - -namespace binfilter { -/************************************************************************* -|* -|* Bucket fuer Index -|* -\************************************************************************/ - -SV_IMPL_VARARR(GeometryIndexValueBucketMemArr, char*) -GeometryIndexValueBucket::GeometryIndexValueBucket(UINT16 TheSize) { - InitializeSize(TheSize); -} -void GeometryIndexValueBucket::InitializeSize(UINT16 TheSize) { - UINT16 nSiz; - for(nShift=0,nSiz=1;nSiz<sizeof(GeometryIndexValue);nSiz<<=1,nShift++); - nBlockShift = TheSize - nShift; - nMask = (1L << nBlockShift)-1L; - nSlotSize = 1<<nShift; - nEntriesPerArray = (UINT16)((1L << TheSize) >> nShift); - Empty(); -} -void GeometryIndexValueBucket::operator=(const GeometryIndexValueBucket& rObj) { - Erase(); - GeometryIndexValueBucket& rSrc = (GeometryIndexValueBucket&)rObj; - for(UINT32 a=0;a<rSrc.Count();a++) - Append(rSrc[a]); -} -void GeometryIndexValueBucket::Empty() { - for(UINT16 i=0;i<aMemArray.Count();i++) - /*#90353#*/ delete [] aMemArray[i]; - if(aMemArray.Count()) - aMemArray.Remove(0, aMemArray.Count()); - nFreeMemArray = 0; - nActMemArray = -1; - Erase(); -} -void GeometryIndexValueBucket::Erase() { - nFreeEntry = nEntriesPerArray; - nCount = 0; - nActMemArray = -1; -} -GeometryIndexValueBucket::~GeometryIndexValueBucket() { - Empty(); -} -BOOL GeometryIndexValueBucket::ImplAppend(GeometryIndexValue& rVec) { - *((GeometryIndexValue*)(aMemArray[nActMemArray] + (nFreeEntry++ << nShift))) = rVec; - nCount++; - return TRUE; -} -BOOL GeometryIndexValueBucket::ImplCareForSpace() { - /* neues array bestimmem */ - if(nActMemArray + 1 < nFreeMemArray) { - /* ist scon allokiert, gehe auf naechstes */ - nActMemArray++; - } else { - /* neues muss allokiert werden */ - char* pNew = new char[nEntriesPerArray << nShift]; - if(!pNew) - return FALSE; - aMemArray.Insert((const char*&) pNew, aMemArray.Count()); - nActMemArray = nFreeMemArray++; - } - nFreeEntry = 0; - return TRUE; -} -GeometryIndexValue& GeometryIndexValueBucket::operator[] (UINT32 nPos) { - if(nPos >= nCount) { - DBG_ERROR("Access to Bucket out of range!"); - return *((GeometryIndexValue*)aMemArray[0]); - } - return *((GeometryIndexValue*)(aMemArray[(UINT16)(nPos >> nBlockShift)] + ((nPos & nMask) << nShift))); -} - -/************************************************************************* -|* -|* Konstruktor -|* -\************************************************************************/ - -B3dGeometry::B3dGeometry() -: pComplexPolygon(NULL), - aEntityBucket(14), // 16K - aIndexBucket(8) // 256Byte -{ - Reset(); -} - -/************************************************************************* -|* -|* Ausgangszustand der Variablen herstellen -|* -\************************************************************************/ - -void B3dGeometry::Reset() -{ - bHintIsComplex = FALSE; - if(pComplexPolygon) - delete pComplexPolygon; - pComplexPolygon = NULL; - - // #93136# since #92030# uses bOutline flag now as indication - // if the filled object is to be drawn, it MUST be initialized now. - bOutline = FALSE; -} - -/************************************************************************* -|* -|* Freien Eintrag zum fuellen holen -|* -\************************************************************************/ - -B3dEntity& B3dGeometry::GetFreeEntity() -{ - aEntityBucket.Append(); - return aEntityBucket[aEntityBucket.Count() - 1]; -} - -/************************************************************************* -|* -|* Inhalte loeschen -|* -\************************************************************************/ - -void B3dGeometry::Erase() -{ - aEntityBucket.Erase(); - aIndexBucket.Erase(); - Reset(); -} - -/************************************************************************* -|* -|* Start der Geometriebeschreibung -|* -\************************************************************************/ - -void B3dGeometry::StartDescription() -{ - Erase(); -} - -/************************************************************************* -|* -|* Ende der Geometriebeschreibung -|* -\************************************************************************/ - -void B3dGeometry::EndDescription() -{ - if(pComplexPolygon) - delete pComplexPolygon; - pComplexPolygon = NULL; -} - -/************************************************************************* -|* -|* Neues Primitiv beginnen -|* -\************************************************************************/ - -void B3dGeometry::StartObject(BOOL bHintComplex, BOOL bOutl) -{ - // Hint uebernehmen - bHintIsComplex = bHintComplex; - bOutline = bOutl; - - // ComplexPolygon anlegen falls nicht vorhanden - if(bHintIsComplex) - { - if(!pComplexPolygon) - pComplexPolygon = new B3dComplexPolygon; - pComplexPolygon->StartPrimitive(); - } - else - { - // Direkt neues Polygon beginnen - StartPolygon(); - } -} - -/************************************************************************* -|* -|* Primitiv abschliessen -|* -\************************************************************************/ - -void B3dGeometry::EndObject() -{ - // Unteren Index holen - UINT32 nLow = 0L; - if(aIndexBucket.Count()) - nLow = aIndexBucket[aIndexBucket.Count()-1].GetIndex(); - - if(bHintIsComplex) - { - pComplexPolygon->EndPrimitive(this); - } - else - { - // Polygon abschliessen - EndPolygon(); - } - - // EbenenNormale berechnen und setzen; bei Linien und - // Punkten wird PlaneNormal auf (0,0,0) gesetzt - UINT32 nHigh = aIndexBucket[aIndexBucket.Count()-1].GetIndex(); - Vector3D aPlaneNormal = -CalcNormal(nLow, nHigh); - while(nLow < nHigh) - aEntityBucket[nLow++].PlaneNormal() = aPlaneNormal; -} - -/************************************************************************* -|* -|* Geometrieuebergabe -|* -\************************************************************************/ - -void B3dGeometry::AddEdge(const Vector3D& rPoint) -{ - if(bHintIsComplex) - { - B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.SetEdgeVisible(TRUE); - - pComplexPolygon->PostAddVertex(rNew); - } - else - { - B3dEntity& rNew = GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.SetEdgeVisible(TRUE); - } -} - -void B3dGeometry::AddEdge( - const Vector3D& rPoint, - const Vector3D& rNormal) -{ - if(bHintIsComplex) - { - B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.Normal() = rNormal; - rNew.SetNormalUsed(); - rNew.SetEdgeVisible(TRUE); - - pComplexPolygon->PostAddVertex(rNew); - } - else - { - B3dEntity& rNew = GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.Normal() = rNormal; - rNew.SetNormalUsed(); - rNew.SetEdgeVisible(TRUE); - } -} - -void B3dGeometry::AddEdge( - const Vector3D& rPoint, - const Vector3D& rNormal, - const Vector3D& rTexture) -{ - if(bHintIsComplex) - { - B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.Normal() = rNormal; - rNew.SetNormalUsed(); - rNew.TexCoor() = rTexture; - rNew.SetTexCoorUsed(); - rNew.SetEdgeVisible(TRUE); - - pComplexPolygon->PostAddVertex(rNew); - } - else - { - B3dEntity& rNew = GetFreeEntity(); - - rNew.Reset(); - rNew.Point() = rPoint; - rNew.SetValid(); - rNew.Normal() = rNormal; - rNew.SetNormalUsed(); - rNew.TexCoor() = rTexture; - rNew.SetTexCoorUsed(); - rNew.SetEdgeVisible(TRUE); - } -} - -/************************************************************************* -|* -|* Copy-Operator -|* -\************************************************************************/ - -void B3dGeometry::operator=(const B3dGeometry& rObj) -{ - // Bucket kopieren - aEntityBucket = rObj.aEntityBucket; - aIndexBucket = rObj.aIndexBucket; - - // ComplexPolygon nicht kopieren - pComplexPolygon = NULL; - - // Hint auch nicht - bHintIsComplex = FALSE; -} - -/************************************************************************* -|* -|* Callbacks bei komplexen Primitiven -|* -\************************************************************************/ - -void B3dGeometry::StartComplexPrimitive() -{ - StartPolygon(); -} - -void B3dGeometry::EndComplexPrimitive() -{ - EndPolygon(); -} - -void B3dGeometry::AddComplexVertex(B3dEntity& rNew, BOOL bIsVisible) -{ - // Kopieren - B3dEntity& rLocal = GetFreeEntity(); - rLocal = rNew; - - // EdgeFlag anpassen - rLocal.SetEdgeVisible(bIsVisible); -} - -/************************************************************************* -|* -|* PolygonStart und -Ende aufzeichnen -|* -\************************************************************************/ - -void B3dGeometry::StartPolygon() -{ -} - -void B3dGeometry::EndPolygon() -{ - GeometryIndexValue aNewIndex(aEntityBucket.Count()); - if(bOutline) - aNewIndex.SetMode(B3D_INDEX_MODE_LINE); - aIndexBucket.Append(aNewIndex); -} - -/************************************************************************* -|* -|* Hittest auf Geometrie -|* Liegt der angegebene Schnittpunkt innerhalb eines der Polygone? -|* -\************************************************************************/ - -sal_Bool B3dGeometry::CheckHit(const Vector3D& rFront, const Vector3D& rBack, sal_uInt16 nTol) -{ - sal_uInt32 nPolyCounter(0L); - sal_uInt32 nEntityCounter(0L); - sal_uInt32 nUpperBound(0L); - - while(nPolyCounter < aIndexBucket.Count()) - { - // Obergrenze neues Polygon holen - nUpperBound = aIndexBucket[nPolyCounter++].GetIndex(); - - // Hittest fuer momentanes Polygon - Vector3D aCut; - - if(CheckSinglePolygonHit(nEntityCounter, nUpperBound, rFront, rBack, aCut)) - { - return sal_True; - } - - // Auf naechstes Polygon - nEntityCounter = nUpperBound; - } - - return sal_False; -} - -sal_Bool B3dGeometry::CheckSinglePolygonHit(UINT32 nLow, UINT32 nHigh, const Vector3D& rFront, - const Vector3D& rBack, Vector3D& rCut) const -{ - if(nLow + 2 < nHigh) - { - // calculate cut with plane - if(GetCutPoint(nLow, rCut, rFront, rBack)) - { - // cut exists, is it inside the polygon? - if(IsInside(nLow, nHigh, rCut)) - { - return sal_True; - } - } - } - - return sal_False; -} - -sal_Bool B3dGeometry::GetCutPoint(UINT32 nLow, Vector3D& rCut, const Vector3D& rFront, const Vector3D& rBack) const -{ - BOOL bCutValid = FALSE; - - // Normale und Skalar der Ebenengleichung ermitteln - Vector3D aNormal = ((B3dGeometry*)this)->aEntityBucket[nLow].PlaneNormal(); - double fScalar = -(((B3dGeometry*)this)->aEntityBucket[nLow + 1].Point().GetVector3D().Scalar(aNormal)); - Vector3D aLineVec = rFront - rBack; - double fZwi = aNormal.Scalar(aLineVec); - - if(fabs(fZwi) > SMALL_DVALUE) - { - fZwi = (-fScalar - (rBack.Scalar(aNormal))) / fZwi; - rCut.X() = rBack.X() + (aLineVec.X() * fZwi); - rCut.Y() = rBack.Y() + (aLineVec.Y() * fZwi); - rCut.Z() = rBack.Z() + (aLineVec.Z() * fZwi); - - bCutValid = TRUE; - } - return bCutValid; -} - -sal_Bool B3dGeometry::IsInside(UINT32 nLow, UINT32 nHigh, const Vector3D& rPnt) const -{ - BOOL bInside(FALSE); - B3dVolume aVolume; - - // Volume von genau dieser Flaeche feststellen - for(UINT32 a=nLow;a<nHigh;a++) - aVolume.Union(((B3dGeometry*)this)->aEntityBucket[a].Point().GetVector3D()); - - // Hier eigentlich ein aVolume.IsInside(rPnt), doch da hier ein - // Vergleich mit Epsilon-Umgebung gebraucht wird, vergleiche selbst - BOOL bIsInside = - (rPnt.X() + SMALL_DVALUE >= aVolume.MinVec().X() && rPnt.X() - SMALL_DVALUE <= aVolume.MaxVec().X() - && rPnt.Y() + SMALL_DVALUE >= aVolume.MinVec().Y() && rPnt.Y() - SMALL_DVALUE <= aVolume.MaxVec().Y() - && rPnt.Z() + SMALL_DVALUE >= aVolume.MinVec().Z() && rPnt.Z() - SMALL_DVALUE <= aVolume.MaxVec().Z()); - - if(bIsInside) - { - BOOL bInsideXY(FALSE); - BOOL bInsideXZ(FALSE); - BOOL bInsideYZ(FALSE); - const Vector3D* pPrev = &(((B3dGeometry*)this)->aEntityBucket[nHigh - 1].Point().GetVector3D()); - const Vector3D* pActual; - Vector3D aDiffPrev, aDiffActual; - - while(nLow < nHigh) - { - // Neuen Punkt holen - pActual = &(((B3dGeometry*)this)->aEntityBucket[nLow++].Point().GetVector3D()); - - // Diffs bilden - aDiffPrev = *pPrev - rPnt; - aDiffActual = *pActual - rPnt; - - // Ueberschneidung in Y moeglich? - if((aDiffPrev.Y() > 0.0 && aDiffActual.Y() <= 0.0) || (aDiffActual.Y() > 0.0 && aDiffPrev.Y() <= 0.0)) - { - // in welchem Bereich liegt X? - if(aDiffPrev.X() >= 0.0 && aDiffActual.X() >= 0.0) - { - // Ueberschneidung - bInsideXY = !bInsideXY; - } - else if((aDiffPrev.X() > 0.0 && aDiffActual.X() <= 0.0) || (aDiffActual.X() > 0.0 && aDiffPrev.X() <= 0.0)) - { - // eventuell Ueberschneidung - // wo liegt die X-Koordinate des Schnitts mit der X-Achse? - if(aDiffActual.Y() != aDiffPrev.Y()) - if(aDiffPrev.X() - ((aDiffPrev.Y() * (aDiffActual.X() - aDiffPrev.X())) / (aDiffActual.Y() - aDiffPrev.Y())) >= 0.0) - // Ueberschneidung - bInsideXY = !bInsideXY; - } - - // in welchem Bereich liegt Z? - if(aDiffPrev.Z() >= 0.0 && aDiffActual.Z() >= 0.0) - { - // Ueberschneidung - bInsideYZ = !bInsideYZ; - } - else if((aDiffPrev.Z() > 0.0 && aDiffActual.Z() <= 0.0) || (aDiffActual.Z() > 0.0 && aDiffPrev.Z() <= 0.0)) - { - // eventuell Ueberschneidung - // wo liegt die X-Koordinate des Schnitts mit der X-Achse? - if(aDiffActual.Y() != aDiffPrev.Y()) - if(aDiffPrev.Z() - ((aDiffPrev.Y() * (aDiffActual.Z() - aDiffPrev.Z())) / (aDiffActual.Y() - aDiffPrev.Y())) >= 0.0) - // Ueberschneidung - bInsideYZ = !bInsideYZ; - } - } - - // Ueberschneidung in X moeglich? - if((aDiffPrev.X() > 0.0 && aDiffActual.X() <= 0.0) || (aDiffActual.X() > 0.0 && aDiffPrev.X() <= 0.0)) - { - // in welchem Bereich liegt Z? - if(aDiffPrev.Z() >= 0.0 && aDiffActual.Z() >= 0.0) - { - // Ueberschneidung - bInsideXZ = !bInsideXZ; - } - else if((aDiffPrev.Z() > 0.0 && aDiffActual.Z() <= 0.0) || (aDiffActual.Z() > 0.0 && aDiffPrev.Z() <= 0.0)) - { - // eventuell Ueberschneidung - // wo liegt die X-Koordinate des Schnitts mit der X-Achse? - if(aDiffActual.X() != aDiffPrev.X()) - if(aDiffPrev.Z() - ((aDiffPrev.X() * (aDiffActual.Z() - aDiffPrev.Z())) / (aDiffActual.X() - aDiffPrev.X())) >= 0.0) - // Ueberschneidung - bInsideXZ = !bInsideXZ; - } - } - - // Punkt als Vorgaenger merken - pPrev = pActual; - } - // Wahrheitswert bilden - bInside = bInsideXY || bInsideXZ || bInsideYZ; - } - return bInside; -} - -/************************************************************************* -|* -|* BoundVolume liefern -|* -\************************************************************************/ - -B3dVolume B3dGeometry::GetBoundVolume() const -{ - B3dVolume aRetval; - - for(UINT32 a=0;a<((B3dGeometry*)this)->aEntityBucket.Count();a++) - aRetval.Union(((B3dGeometry*)this)->aEntityBucket[a].Point().GetVector3D()); - - return aRetval; -} - -/************************************************************************* -|* -|* Mittelpunkt liefern -|* -\************************************************************************/ - -Vector3D B3dGeometry::GetCenter() const -{ - B3dVolume aVolume = GetBoundVolume(); - return (aVolume.MaxVec() + aVolume.MinVec()) / 2.0; -} - -/************************************************************************* -|* -|* Standard - Normalen generieren -|* -\************************************************************************/ - -void B3dGeometry::CreateDefaultNormalsSphere() -{ - // Alle Normalen ausgehend vom Zentrum der Geometrie bilden - Vector3D aCenter = GetCenter(); - - for(UINT32 a=0;a<aEntityBucket.Count();a++) - { - const Vector3D& aPoint = aEntityBucket[a].Point().GetVector3D(); - Vector3D aNewNormal = aPoint - aCenter; - aNewNormal.Normalize(); - aEntityBucket[a].Normal() = aNewNormal; - aEntityBucket[a].SetNormalUsed(TRUE); - } -} - -/************************************************************************* -|* -|* Normale ermitteln fuer einzelnes Polygon -|* -\************************************************************************/ - -Vector3D B3dGeometry::CalcNormal(UINT32 nLow, UINT32 nHigh) const -{ - const Vector3D* pVec1 = NULL; - const Vector3D* pVec2 = NULL; - const Vector3D* pVec3 = NULL; - Vector3D aNormal; - - while(nLow < nHigh && !(pVec1 && pVec2 && pVec3)) - { - if(!pVec1) - { - pVec1 = &(((B3dGeometry*)this)->aEntityBucket[nLow++].Point().GetVector3D()); - } - else if(!pVec2) - { - pVec2 = &(((B3dGeometry*)this)->aEntityBucket[nLow++].Point().GetVector3D()); - if(*pVec2 == *pVec1) - pVec2 = NULL; - } - else if(!pVec3) - { - pVec3 = &(((B3dGeometry*)this)->aEntityBucket[nLow++].Point().GetVector3D()); - if(*pVec3 == *pVec2 || pVec3 == pVec1) - pVec3 = NULL; - } - } - if(pVec1 && pVec2 && pVec3) - { - aNormal = (*pVec2 - *pVec1)|(*pVec2 - *pVec3); - aNormal.Normalize(); - } - return aNormal; -} - -/************************************************************************* -|* -|* Standard - Texturkoordinaten generieren -|* -\************************************************************************/ - -void B3dGeometry::CreateDefaultTexture(UINT16 nCreateWhat, BOOL bUseSphere) -{ - if(nCreateWhat) - { - if(bUseSphere) - { - // Texturkoordinaten mittels Kugelprojektion ermitteln, - // dazu das Zentrum der Geometrie benutzen - // Alle Normalen ausgehend vom Zentrum der Geometrie bilden - Vector3D aCenter = GetCenter(); - UINT32 nPointCounter = 0; - - for(UINT32 a=0;a<aIndexBucket.Count();a++) - { - // Lokales Zentrum der zu behandelnden Flaeche bilden, - // um zu wissen von welcher Seite sich diese Flaeche - // dem Winkel F_PI bzw. -F_PI naehert - Vector3D aLocalCenter; - for(UINT32 b=nPointCounter;b<aIndexBucket[a].GetIndex();b++) - aLocalCenter += aEntityBucket[b].Point().GetVector3D(); - aLocalCenter /= aIndexBucket[a].GetIndex() - nPointCounter; - - // Vektor vom Mittelpunkt zum lokalen Zentrum bilden - aLocalCenter = aLocalCenter - aCenter; - if(fabs(aLocalCenter.X()) < SMALL_DVALUE) - aLocalCenter.X() = 0.0; - if(fabs(aLocalCenter.Y()) < SMALL_DVALUE) - aLocalCenter.Y() = 0.0; - if(fabs(aLocalCenter.Z()) < SMALL_DVALUE) - aLocalCenter.Z() = 0.0; - - // X,Y fuer das lokale Zentrum bilden - double fXCenter = atan2(aLocalCenter.Z(), aLocalCenter.X()); - double fYCenter = atan2(aLocalCenter.Y(), aLocalCenter.GetXZLength()); - fXCenter = 1.0 - ((fXCenter + F_PI) / F_2PI); - fYCenter = 1.0 - ((fYCenter + F_PI2) / F_PI); - - // Einzelne Punkte behandeln - UINT32 nRememberPointCounter = nPointCounter; - while(nPointCounter < aIndexBucket[a].GetIndex()) - { - // Vektor vom Mittelpunkt zum Punkt bilden - const Vector3D& aPoint = aEntityBucket[nPointCounter].Point().GetVector3D(); - Vector3D aDirection = aPoint - aCenter; - if(fabs(aDirection.X()) < SMALL_DVALUE) - aDirection.X() = 0.0; - if(fabs(aDirection.Y()) < SMALL_DVALUE) - aDirection.Y() = 0.0; - if(fabs(aDirection.Z()) < SMALL_DVALUE) - aDirection.Z() = 0.0; - - // X,Y fuer Punkt bilden - double fXPoint = atan2(aDirection.Z(), aDirection.X()); - double fYPoint = atan2(aDirection.Y(), aDirection.GetXZLength()); - fXPoint = 1.0 - ((fXPoint + F_PI) / F_2PI); - fYPoint = 1.0 - ((fYPoint + F_PI2) / F_PI); - - // X,Y des Punktes korrigieren - if(fXPoint > fXCenter + 0.5) - fXPoint -= 1.0; - if(fXPoint < fXCenter - 0.5) - fXPoint += 1.0; - - // Polarkoordinaten als Texturkoordinaten zuweisen - if(nCreateWhat & B3D_CREATE_DEFAULT_X) - aEntityBucket[nPointCounter].TexCoor().X() = fXPoint; - if(nCreateWhat & B3D_CREATE_DEFAULT_Y) - aEntityBucket[nPointCounter].TexCoor().Y() = fYPoint; - if(nCreateWhat & B3D_CREATE_DEFAULT_Z) - aEntityBucket[nPointCounter].TexCoor().Z() = 0.0; - - aEntityBucket[nPointCounter++].SetTexCoorUsed(TRUE); - } - - // Punkte korrigieren, die direkt in den Polarregionen liegen. Deren - // X-Koordinate kann nicht korrekt sein. Die korrekte X-Koordinate - // ist diejenige des Punktes, der in den Pol hinein oder aus diesem heraus - // fuehrt, auf der Kugel also direkt darauf zu. - if(nCreateWhat & B3D_CREATE_DEFAULT_X) - { - nPointCounter = nRememberPointCounter; - while(nPointCounter < aIndexBucket[a].GetIndex()) - { - Vector3D& aCoor = aEntityBucket[nPointCounter].TexCoor(); - if(fabs(aCoor.Y()) < SMALL_DVALUE || fabs(aCoor.Y() - 1.0) < SMALL_DVALUE) - { - // Nachfolger finden - UINT32 nNextIndex = (nPointCounter + 1 < aIndexBucket[a].GetIndex()) - ? nPointCounter + 1 : nRememberPointCounter; - Vector3D& aNextCoor = aEntityBucket[nNextIndex].TexCoor(); - - // Vorgaenger finden - UINT32 nPrevIndex = (nPointCounter && nPointCounter - 1 >= nRememberPointCounter) - ? nPointCounter - 1 : aIndexBucket[a].GetIndex() - 1; - Vector3D& aPrevCoor = aEntityBucket[nPrevIndex].TexCoor(); - - // Nachfolger testen: Liegt dieser ausserhalb des Pols? - if(fabs(aNextCoor.Y()) > SMALL_DVALUE && fabs(aNextCoor.Y() - 1.0) > SMALL_DVALUE) - { - // falls ja: X-Koordinate uebernehmen - aCoor.X() = aNextCoor.X(); - } - // Vorgaenger testen: Liegt dieser ausserhalb des Pols? - else if(fabs(aPrevCoor.Y()) > SMALL_DVALUE && fabs(aPrevCoor.Y() - 1.0) > SMALL_DVALUE) - { - // falls ja, X-Koordinate uebernehmen - aCoor.X() = aPrevCoor.X(); - } - else - { - // Weder Vorgaenger noch Nachfolger liegen ausserhalb des Pols. - // Uebernimm daher wenigstens den bereits korrigierten X-Wert - // des Vorgaengers - aCoor.X() = aPrevCoor.X(); - } - } - // naechster Punkt - nPointCounter++; - } - } - } - } - else - { - // Texturkoordinaten als Parallelprojektion auf X,Y,Z - Koordinaten - // im Bereich 1.0 bis 0.0 der Geometrie abstellen - // Gesamtabmessungen holen - B3dVolume aVolume = GetBoundVolume(); - - for(UINT32 a=0;a<aEntityBucket.Count();a++) - { - const Vector3D& aPoint = aEntityBucket[a].Point().GetVector3D(); - - if(nCreateWhat & B3D_CREATE_DEFAULT_X) - { - if(aVolume.GetWidth()) - aEntityBucket[a].TexCoor().X() = (aPoint.X() - aVolume.MinVec().X()) / aVolume.GetWidth(); - else - aEntityBucket[a].TexCoor().X() = 0.0; - } - - if(nCreateWhat & B3D_CREATE_DEFAULT_Y) - { - if(aVolume.GetHeight()) - aEntityBucket[a].TexCoor().Y() = 1.0 - ((aPoint.Y() - aVolume.MinVec().Y()) / aVolume.GetHeight()); - else - aEntityBucket[a].TexCoor().Y() = 1.0; - } - - if(nCreateWhat & B3D_CREATE_DEFAULT_Z) - aEntityBucket[a].TexCoor().Z() = 0.0; - - aEntityBucket[a].SetTexCoorUsed(TRUE); - } - } - } -} - -/************************************************************************* -|* -|* Normalen invertieren -|* -\************************************************************************/ - -void B3dGeometry::InvertNormals() -{ - for(UINT32 a=0;a<aEntityBucket.Count();a++) - aEntityBucket[a].Normal() = -aEntityBucket[a].Normal(); -} -}//end of namespace binfilter - -// eof - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |