#include "Model3D.h" #include "Animation3D.h" #include "Bild.h" #include "DXBuffer.h" #include "Model2D.h" #include "Textur.h" #include "Welt3D.h" #ifdef WIN32 # include #endif #include using namespace Framework; // Constructor // \param id the id of the bone Bone::Bone(int id) { pos = Vec3(0, 0, 0); rot = Vec3(0, 0, 0); sibling = 0; child = 0; this->id = id; } //! Destructor Bone::~Bone() { delete sibling; delete child; } //! set the position of the bone relative to the parent bone //! \param pos the position void Bone::setPosition(const Vec3& pos) { this->pos = pos; } //! Set the rotation of the bone relative to the parent bone //! \param rot thr rotation void Bone::setRotation(const Vec3& rot) { this->rot = rot; } //! add a sibling bone to this bone that shares the same parent bone //! \param b Der Knochen, der hinzugefügt werden soll void Bone::addSiblingBone(Bone* b) { if (!sibling) sibling = b; else sibling->addSiblingBone(b); } //! add a child bone to a specific child bone //! \param id the id of the bone the new bone should be a child of //! \param b the bone that should be added bool Bone::addChildBone(int id, Bone* b) { if (this->id == id) { if (!child) { child = b; return 1; } else { child->addSiblingBone(b); return 1; } } else { if (child) { if (child->addChildBone(id, b)) { return 1; } } else if (sibling) { return sibling->addChildBone(id, b); } return 0; } } //! calculates the matrixes of this bone, all child bones and sibling //! bones //! \param elternMat the already calculated matrix of the parent bone //! \param matBuffer the array to store the calculated matrixes //! \param scaleFactor the scaling of the object //! \param camMatrix the view-projection matrix of the used camera void Bone::calculateMatrix(const Mat4& elternMat, Mat4* matBuffer, float scaleFactor, const Mat4& kamMat) { if (sibling) sibling->calculateMatrix(elternMat, matBuffer, scaleFactor, kamMat); matBuffer[id] = matBuffer[id].translation(pos * scaleFactor) * matBuffer[id].rotationZ(rot.z) * matBuffer[id].rotationX(rot.x) * matBuffer[id].rotationY(rot.y) * matBuffer[id].scaling(scaleFactor); matBuffer[id] = elternMat * matBuffer[id]; if (child) child->calculateMatrix(matBuffer[id], matBuffer, scaleFactor, kamMat); matBuffer[id] = kamMat * matBuffer[id]; } Bone* Framework::Bone::zFirstSibling() const { return sibling; } Bone* Framework::Bone::zFirstChild() const { return child; } //! returns a copy of this bone with copies of all child and //! sibling bones Bone* Bone::copyBone() const { Bone* ret = new Bone(id); ret->pos = pos; ret->rot = rot; if (sibling) ret->sibling = sibling->copyBone(); if (child) ret->child = child->copyBone(); return ret; } //! \return the id of this bone int Bone::getId() const { return id; } //! \return the rotation of this bone Vec3 Bone::getRotation() const { return rot; } //! \return the position of this bone Vec3 Bone::getPosition() const { return pos; } //! \return the radius of this bone float Bone::getRadius() const { float r = pos.getLength(); if (sibling) r = MAX(r, sibling->getRadius()); if (child) r += child->getRadius(); return r; } // Inhalt der Skelett Klasse // Constructor Skeleton::Skeleton() : ReferenceCounter() { rootBone = 0; nextId = 0; } // Destructor Skeleton::~Skeleton() { if (rootBone) delete rootBone; } Bone* Skeleton::zBone(Bone* zCurrent, int id) const { while (zCurrent) { if (zCurrent->getId() == id) { return zCurrent; } if (zCurrent->zFirstChild()) { Bone* ret = zBone(zCurrent->zFirstChild(), id); if (ret) return ret; } zCurrent = zCurrent->zFirstSibling(); } return 0; } //! add a bone to the sceleton //! \param pos the position of the bone //! \param rot the rotation of the bone //! \param the id of the parent bone where the new bone should be added //! as a child //! \return the id of the added bone or -1 if the bone could not be //! added int Skeleton::addBone(Vec3 pos, Vec3 rot, int parentId) { if (parentId == -1) { if (!this->rootBone) { this->rootBone = new Bone(nextId++); this->rootBone->setPosition(pos); this->rootBone->setRotation(rot); return this->rootBone->getId(); } else { Bone* bone = new Bone(nextId++); bone->setPosition(pos); bone->setRotation(rot); this->rootBone->addSiblingBone(bone); return bone->getId(); } } else { if (!this->rootBone) return -1; Bone* bone = new Bone(nextId++); bone->setPosition(pos); bone->setRotation(rot); if (rootBone->addChildBone(parentId, bone)) { return bone->getId(); } else { nextId--; return -1; } } } //! calculates the matrices of all bones in this sceleton //! \param modelMatrix the already calculated matrix of the used 3d //! model \param matBuffer the array to store the calculated matrixes //! \param scaleFactor the scaling of the object //! \param camMatrix the view-projection matrix of the used camera int Skeleton::calculateMatrix(const Mat4& modelMatrix, Mat4* matBuffer, float scaleFactor, const Mat4& kamMatrix) { rootBone->calculateMatrix(modelMatrix, matBuffer, scaleFactor, kamMatrix); return nextId; } //! \return the radius of the sceleton float Skeleton::getRadius() const { if (rootBone) return rootBone->getRadius(); return 0; } //! \return the root bone of the sceleton Bone* Framework::Skeleton::zRootBone() const { return rootBone; } //! \return the bone with a specific id Bone* Framework::Skeleton::zBone(int id) const { if (!rootBone) return 0; return zBone(rootBone, id); } //! \return a deep copy of the sceleton Skeleton* Skeleton::copySceleton() const { Skeleton* ret = new Skeleton(); ret->nextId = nextId; if (rootBone) ret->rootBone = rootBone->copyBone(); return ret; } //! \return the next id for a bone ther can be only MAX_KNOCHEN_ANZ //! bones in a sceleton. if the sceleton is full -1 is returned int Framework::Skeleton::getNextBoneId() const { return nextId; } // Inhalt des Polygon3D Struct // Konstruktor Polygon3D::Polygon3D() { indexAnz = 0; indexList = 0; } // Destruktor Polygon3D::~Polygon3D() { delete[] indexList; } // Inhalt der Model3DData Klasse // Konstruktor Model3DData::Model3DData( DXBuffer* dxVertexBuffer, DXBuffer* dxIndexBuffer, int id) : ReferenceCounter(), dxIndexBuffer(dxIndexBuffer), dxVertexBuffer(dxVertexBuffer), id(id) { skelett = 0; vertexList = 0; vertexCount = 0; polygons = new Array(); ambientFactor = 1.f; diffusFactor = 0.f; specularFactor = 0.f; indexCount = 0; indexBuffer = 0; radius = 0; } // Destruktor Model3DData::~Model3DData() { clearModel(); polygons->release(); dxIndexBuffer->release(); dxVertexBuffer->release(); delete[] indexBuffer; } // updates the DX Buffer gpu memory if changed DLLEXPORT void Model3DData::updateGPUMemory() { dxIndexBuffer->copieren(); dxVertexBuffer->copieren(); } // Löscht alle Model daten void Model3DData::clearModel() { delete[] vertexList; vertexCount = 0; vertexList = 0; for (Polygon3D* i : *polygons) delete i; polygons->leeren(); if (skelett) skelett->release(); skelett = 0; radius = 0; delete[] indexBuffer; indexBuffer = 0; indexCount = 0; } // Berechnet die normalen für die Eckpunkte des Modells void Model3DData::calculateNormals() { for (int i = 0; i < vertexCount; i++) { Vec3 normal(0, 0, 0); for (Polygon3D* p : *polygons) { int begin = 0; for (int j = 0; j < p->indexAnz; j++) { if (j % 3 == 0) begin = j; if (p->indexList[j] == i) { Vec3 a = vertexList[p->indexList[begin]].pos; Vec3 b = vertexList[p->indexList[begin + 1]].pos; Vec3 c = vertexList[p->indexList[begin + 2]].pos; normal += (b - a).crossProduct(c - a).normalize(); normal.normalize(); } } } vertexList[i].normal = normal; } } //! Erstellt einen buffer für alle polygon indizes void Model3DData::buildIndexBuffer() { delete[] indexBuffer; indexCount = 0; for (Polygon3D* p : *polygons) indexCount += p->indexAnz; indexBuffer = new int[indexCount]; int current = 0; for (Polygon3D* p : *polygons) { memcpy(indexBuffer + current, p->indexList, sizeof(int) * p->indexAnz); current += p->indexAnz; } dxIndexBuffer->setLength((int)(indexCount * sizeof(int))); dxIndexBuffer->setData(indexBuffer); } // Setzt den Zeiger auf ein standartmäßig verwendete Skelett // s: Das Skelett, das verwendet werden soll void Model3DData::setSkelettZ(Skeleton* s) { if (skelett) skelett->release(); skelett = s; } // Setzt einen Zeiger auf eine Liste mit allen Vertecies des Models // vertexList: Ein Array mit Vertecies // anz: Die Anzahl der Vertecies im Array void Model3DData::setVertecies(Vertex3D* vertexList, int anz) { delete[] this->vertexList; this->vertexList = vertexList; vertexCount = anz; maxPos = {-INFINITY, -INFINITY, -INFINITY}; minPos = {INFINITY, INFINITY, INFINITY}; radius = 0; for (int i = 0; i < anz; i++) { float r = vertexList[i].pos.getLength(); if (r > radius) radius = r; if (vertexList[i].pos.x < minPos.x) minPos.x = vertexList[i].pos.x; if (vertexList[i].pos.y < minPos.y) minPos.y = vertexList[i].pos.y; if (vertexList[i].pos.z < minPos.z) minPos.z = vertexList[i].pos.z; if (vertexList[i].pos.x > maxPos.x) maxPos.x = vertexList[i].pos.x; if (vertexList[i].pos.y > maxPos.y) maxPos.y = vertexList[i].pos.y; if (vertexList[i].pos.z > maxPos.z) maxPos.z = vertexList[i].pos.z; vertexList[i].id = i; } dxVertexBuffer->setLength((int)(anz * sizeof(Vertex3D))); dxVertexBuffer->setData(vertexList); } // Fügt ein Polygon zum Model hinzu // polygon: Das Polygon, das hinzugefügt erden soll void Model3DData::addPolygon(Polygon3D* polygon) { polygons->add(polygon); buildIndexBuffer(); } // Git den Factor an, mit dem das umgebungslicht (textur farbe) multipliziert // wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Model3DData::setAmbientFactor(float f) { ambientFactor = f; } // Git den Factor an, mit dem die Lichtfarbe von Lichtquellen multipliziert wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Model3DData::setDiffusFactor(float f) { diffusFactor = f; } // Git den Factor an, mit dem die Reflektion von Lichtquellen multipliziert wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Model3DData::setSpecularFactor(float f) { specularFactor = f; } // Konvertiert ein 2d Model zu 3D // model: Das 2d Model, das zu 3d konvertiert werden soll // z: Die z koordinate aller punkte des Models void Model3DData::copyModel2D(Model2DData* model, float z) { if (model && model->vListen && model->polygons) { clearModel(); int vAnz = 0; for (const Polygon2D& p : *model->polygons) vAnz += p.vertex->getEintragAnzahl(); Vertex3D* vertexList = new Vertex3D[vAnz]; int index = 0; for (auto i : *model->vListen) { Polygon3D* p = new Polygon3D(); p->indexAnz = 0; for (auto j : *i) { for (auto k = j->zListe()->begin(); k && k.hasNext() && k.next().hasNext(); k++) p->indexAnz += 3; } p->indexList = new int[p->indexAnz]; p->indexAnz = 0; for (auto j : *i) { for (auto k = j->zListe()->begin(); k; k++) { assert(index < vAnz); if (index < vAnz) { vertexList[index].pos = Vec3(k->punkt->x, k->punkt->y, z); vertexList[index].tPos = (Vec2)*k->textur; if (k.hasNext() && k.next().hasNext()) { p->indexList[p->indexAnz] = index; p->indexAnz++; p->indexList[p->indexAnz] = index + 1; p->indexAnz++; p->indexList[p->indexAnz] = index + 2; p->indexAnz++; } } else break; index++; } } addPolygon(p); } this->setVertecies(vertexList, vAnz); buildIndexBuffer(); calculateNormals(); } } // Entfernt ein Polygon // index: Der Index des Polygons void Model3DData::removePolygon(int index) { if (!polygons->hat(index)) return; delete polygons->get(index); polygons->remove(index); buildIndexBuffer(); } // Berechnet die Matrizen der Knochen // modelMatrix: Die Matrix, die das Skelett in den Raum der Welt transformiert // matBuffer: Ein Array von Matrizen, der durch die Knochen Matrizen gefüllt // wird scaleFactor: Die Skallierung des Modells kamMatrix: Die vereiniegung // der view und projektions Matrizen return: gibt die Anzahl der verwendeten // Matrizen zurück int Model3DData::kalkulateMatrix(const Mat4& modelMatrix, Mat4* matBuffer, float scaleFactor, const Mat4& kamMatrix) const { if (!skelett) return 0; return skelett->calculateMatrix( modelMatrix, matBuffer, scaleFactor, kamMatrix); } // Gibt die Anzahl an Polygonen zurück int Model3DData::getPolygonAnzahl() const { return polygons->getEintragAnzahl(); } // Gibt ein bestimmtes Polygon zurück // index: Der Index des Polygons Polygon3D* Model3DData::getPolygon(int index) const { if (!polygons->hat(index)) return 0; return polygons->get(index); } // Gibt einen Iterator zurück, mit dem sich die Polygons auflisten lassen ArrayIterator Model3DData::getPolygons() const { return polygons->begin(); } // Gibt den radius einer Kugel zurück, die das gesammte Model umschließt float Model3DData::getRadius() const { return radius; } // Gibt die Id der Daten zurück, wenn sie in einer Model3DList registriert // wurden. (siehe Framework::zM3DRegister()) int Model3DData::getId() const { return id; } // Git den Factor an, mit dem das umgebungslicht (textur farbe) multipliziert // wird float Model3DData::getAmbientFactor() const { return ambientFactor; } // Git den Factor an, mit dem die Lichtfarbe von Lichtquellen multipliziert wird float Model3DData::getDiffusFactor() const { return diffusFactor; } // Git den Factor an, mit dem die Reflektion von Lichtquellen multipliziert wird float Model3DData::getSpecularFactor() const { return specularFactor; } // Gibt eine Kopie des Skeletts zurück, welches für annimationen verwendet // werden kann Skeleton* Model3DData::copySkelett() const { return skelett ? skelett->copySceleton() : 0; } // Gibt die Anzahl an Vertices zurück int Model3DData::getVertexAnzahl() const { return vertexCount; } // Gibt einen Buffer mit allen Vertecies des Models zurück const Vertex3D* Model3DData::zVertexBuffer() const { return vertexList; } //! Gibt eine refferenz auf den beginn des indexBuffers zurück const int* Model3DData::getIndexBuffer() const { return indexBuffer; } //! Gibt eine die Anzahl der indizes im indexBuffer zurück int Model3DData::getIndexCount() const { return indexCount; } //! Gibt den Index buffer zurück; DXBuffer* Model3DData::zDXIndexBuffer() const { return dxIndexBuffer; } //! Gibt den Vertex buffer zurück; DXBuffer* Model3DData::zDXVertexBuffer() const { return dxVertexBuffer; } //! gibt den minnimalen Punkt der Bounding box des Models zurück Vec3 Model3DData::getMinPos() const { return minPos; } //! gibt den maximalen Punkt der bounding box des Mopdels zurück Vec3 Model3DData::getMaxPos() const { return maxPos; } // Inhalt der Model3DTextur // Konstruktor Model3DTextur::Model3DTextur() : ReferenceCounter() { textures = new Textur*[1]; textures[0] = 0; textureCount = 1; } // Destruktor Model3DTextur::~Model3DTextur() { for (int i = 0; i < textureCount; i++) { if (textures[i]) textures[i]->release(); } delete[] textures; } // Legt fest, welche Textur für welches Polygon ist // pI: Der Index des Polygons // txt: Die Textur des Polygons void Model3DTextur::setPolygonTextur(int pI, Textur* txt) { if (pI >= textureCount) { Textur** tmp = textures; textures = new Textur*[pI + 1]; memcpy(textures, tmp, sizeof(Textur*) * textureCount); memset(textures + textureCount, 0, sizeof(Textur*) * (pI + 1 - textureCount)); delete[] tmp; textureCount = pI + 1; } if (textures[pI]) textures[pI]->release(); textures[pI] = txt; } // Gibt einen Zeiger auf die Textur eines Polygons zurück ohne erhöhten // Reference Counter // i: Der Index des Polygons Textur* Model3DTextur::zPolygonTextur(int i) const { if (i >= textureCount) return 0; return textures[i]; } // Inhalt der Model3D Klasse // Konstruktor Model3D::Model3D() : Zeichnung3D() { model = 0; textur = 0; skelett = 0; ambientFactor = 1.f; diffusFactor = 0.f; specularFactor = 0.f; } // Destruktor Model3D::~Model3D() { if (model) model->release(); if (textur) textur->release(); if (skelett) skelett->release(); } // Setzt die Daten des Models // data: Die Daten void Model3D::setModelDaten(Model3DData* data) { if (model) model->release(); if (skelett) skelett = (Skeleton*)skelett->release(); model = data; if (model) { skelett = model->copySkelett(); this->ambientFactor = model->getAmbientFactor(); this->specularFactor = model->getSpecularFactor(); this->diffusFactor = model->getDiffusFactor(); } } // Setzt die zum Zeichnen zu benutzenden Texturen // txt: Ein Liste mit Texturen zu den verschiedenen Polygonen zugeordnet void Model3D::setModelTextur(Model3DTextur* txt) { if (textur) textur->release(); textur = txt; } // Git den Factor an, mit dem das umgebungslicht (textur farbe) multipliziert // wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Framework::Model3D::setAmbientFactor(float f) { this->ambientFactor = f; } // Git den Factor an, mit dem die Lichtfarbe von Lichtquellen multipliziert wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Framework::Model3D::setDiffusFactor(float f) { diffusFactor = f; } // Git den Factor an, mit dem das umgebungslicht (textur farbe) multipliziert // wird // f: der neue Faktor (von 0 bis 1, ambient + specular + diffuse = 1) void Framework::Model3D::setSpecularFactor(float f) { specularFactor = f; } // Errechnet die Matrizen aller Knochen des Skeletts des Models // viewProj: Die miteinander multiplizierten Kameramatrizen // matBuffer: Ein Array mit Matrizen, der gefüllt werden soll // return: Die Anzahl der Matrizen, die das Model benötigt int Model3D::errechneMatrizen( const Mat4& viewProj, Mat4* matBuffer) { int ret = 0; if (skelett) ret = skelett->calculateMatrix(welt, matBuffer, size, viewProj); else if (model) ret = model->kalkulateMatrix(welt, matBuffer, size, viewProj); if (!ret) return Zeichnung3D::errechneMatrizen(viewProj, matBuffer); return ret; } // Verarbeitet die vergangene Zeit // tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion // vergangen ist return: true, wenn sich das Objekt verändert hat, false // sonnst. bool Model3D::tick(double tickval) { radius = model ? model->getRadius() : 0; if (skelett) { radius += skelett->getRadius(); } return Zeichnung3D::tick(tickval); } //! zum aktualisieren der shader daten void Model3D::beforeRender( GraphicsApi* api, Shader* zVertexShader, Shader* zPixelShader) {} void Model3D::afterRender( GraphicsApi* api, Shader* zVertexShader, Shader* zPixelShader) {} // Gibt die Textur zurück Model3DTextur* Model3D::getTextur() { return textur ? dynamic_cast(textur->getThis()) : 0; } // Gibt die Textur zurück (ohne erhöhten Reference Counter) Model3DTextur* Model3D::zTextur() { return textur; } // Gibt die ModelDaten zurück Model3DData* Model3D::getModelData() { return model ? dynamic_cast(model->getThis()) : 0; } // Gibt die ModelDaten zurück (ohne erhöhten Reference Counter) Model3DData* Model3D::zModelData() { return model; } // prüft, ob ein Strahl dieses Objekt trifft // point: der startpunkt des Strahls in Weltkoordinaten // dir: die Richtung des Strahls in Weltkoordinaten // maxSqDist: Die maximale quadratische distanz die erlaubt ist // pId: die Id des Polygons, zu dem der Schnittpunkt gehört // return: den quadratischen Abstand des Schnittpunktes zum Ursprung des // Strahls oder -1, wenn kein schnittpunkt existiert float Model3D::traceRay( const Vec3& p, const Vec3& d, float maxSqDist, int& pId) const { if (!model) return -1; Vec3 dir = d; dir.rotateY(-angle.y); dir.rotateX(-angle.x); dir.rotateZ(-angle.z); Vec3 point = p; point.rotateY(-angle.y); point.rotateX(-angle.x); point.rotateZ(-angle.z); point -= pos; float nearest = (-dir.x * point.x - dir.y * point.y - dir.z * point.z) / (dir.x * dir.x + dir.y * dir.y + dir.z * dir.z); float dist = (point + dir * nearest).getLengthSq(); if (dist > (radius * size) * (radius * size) || (dir * nearest).getLength() - radius * size > sqrt(maxSqDist) || (nearest < 0 && (dir * nearest).getLengthSq() > radius * size * radius * size)) // es gibt kein schnittpunkt return -1; bool existsHit = 0; if (skelett) { // todo } else { int index = 0; for (auto p = model->getPolygons(); p; p++) { for (int j = 0; j < p->indexAnz; j++) { if (j % 3 == 0) { Vec3 a = model->zVertexBuffer()[p->indexList[j]].pos; Vec3 b = model->zVertexBuffer()[p->indexList[j + 1]].pos; Vec3 c = model->zVertexBuffer()[p->indexList[j + 2]].pos; Vec3 normal = (b - a).crossProduct(c - a).normalize(); if (normal * dir < 0) // Prüfe ob die Normale in Richtung // des Strahl ursprungs zeigt { nearest = (a * normal - point * normal) / (dir * normal); Vec3 hit = point + dir * nearest; if ((b - a).angle(hit - a) <= (b - a).angle(c - a) && (c - a).angle(hit - a) <= (b - a).angle(c - a) && (a - b).angle(hit - b) <= (a - b).angle(c - b)) { maxSqDist = (hit - point).getLengthSq(); pId = index; existsHit = 1; } } index++; } } } } return existsHit ? maxSqDist : -1; } // berechnet die Farbe des Schnittpunktes deines Strahls // point: der startpunkt des Strahls in Weltkoordinaten // dir: die Richtung des Strahls in Weltkoordinaten // zWelt: die Welt, aus der der Strahl kommt // return: die Farbe des Schnittpunktes int Model3D::traceRay( Vec3& p, Vec3& d, int pId, Welt3D* zWelt) const { Vec3 dir = d; dir.rotateY(-angle.y); dir.rotateX(-angle.x); dir.rotateZ(-angle.z); Vec3 point = p; point.rotateY(-angle.y); point.rotateX(-angle.x); point.rotateZ(-angle.z); point -= pos; int index = 0; for (auto p = model->getPolygons(); p; p++, index++) { for (int j = 0; j < p->indexAnz; j++) { if (j % 3 == 0) { if (pId == 0) { const Vec3& a = model->zVertexBuffer()[p->indexList[j]].pos; const Vec3& b = model->zVertexBuffer()[p->indexList[j + 1]].pos; const Vec3& c = model->zVertexBuffer()[p->indexList[j + 2]].pos; Vertex at = model->zVertexBuffer()[p->indexList[j]].tPos; Vertex bt = model->zVertexBuffer()[p->indexList[j + 1]].tPos; Vertex ct = model->zVertexBuffer()[p->indexList[j + 2]].tPos; Vec3 normal = (b - a).crossProduct(c - a).normalize(); float t = (a * normal - point * normal) / (dir * normal); Vec3 hit = point + dir * t; float a0 = (a - b).crossProduct(a - c).getLength() / 2; float a1 = (b - hit).crossProduct(c - hit).getLength() / 2 / a0; float a2 = (c - hit).crossProduct(a - hit).getLength() / 2 / a0; float a3 = (a - hit).crossProduct(b - hit).getLength() / 2 / a0; Vertex ht = at * a1 + bt * a2 + ct * a3; Bild* tex = textur->zPolygonTextur(index)->zBild(); if (ht.x >= 0 && ht.y >= 0 && ht.x <= 1 && ht.y <= 1) return tex->getPixel( (int)(ht.x * ((float)tex->getBreite() - 1.f) + 0.5f), (int)(ht.y * ((float)tex->getHeight() - 1.f) + 0.5f)); return 0xFF000000; } pId--; } } } return 0xFF000000; } // Gibt die Id der Daten zurück, wenn sie in einer Model3DList registriert // wurden. (siehe Framework::zM3DRegister()) int Model3D::getDatenId() const { return model ? model->getId() : -1; } // Git den Factor an, mit dem das umgebungslicht (textur farbe) multipliziert // wird float Model3D::getAmbientFactor() const { return ambientFactor; } // Git den Factor an, mit dem die Lichtfarbe von Lichtquellen multipliziert wird float Model3D::getDiffusFactor() const { return diffusFactor; } // Git den Factor an, mit dem die Reflektion von Lichtquellen multipliziert wird float Model3D::getSpecularFactor() const { return specularFactor; } // Gibt die Anzahl an Vertices zurück int Model3D::getVertexAnzahl() const { return model ? model->getVertexAnzahl() : 0; } // Gibt einen Buffer mit allen Vertecies des Models zurück const Vertex3D* Model3D::zVertexBuffer() const { return model ? model->zVertexBuffer() : 0; } //! Gibt true zurück wenn ein bestimmtes polygon gezeichnet werden muss bool Model3D::needRenderPolygon(int index) { return 1; } Textur* Model3D::zEffectTextur() { return 0; } float Model3D::getEffectPercentage() { return 0; }