RNBoolean R3Contains(const R3Triangle& triangle, const R3Point& point) { // Check whether triangle bounding shape contains point if (!R3Contains(triangle.Box(), point)) return FALSE; // Check whether triangle plane contains point if (!R3Contains(triangle.Plane(), point)) return FALSE; // Compute whether point is on correct side of each edge const R3Point& p0 = triangle.Vertex(0)->Position(); const R3Point& p1 = triangle.Vertex(1)->Position(); const R3Point& p2 = triangle.Vertex(2)->Position(); R3Plane h01(p1, triangle.Normal(), p1 - p0); if (RNIsNegative(R3SignedDistance(h01, point))) return FALSE; R3Plane plane01(p1, triangle.Normal(), p1 - p0); if (RNIsNegative(R3SignedDistance(plane01, point))) return FALSE; R3Plane plane12(p2, triangle.Normal(), p2 - p1); if (RNIsNegative(R3SignedDistance(plane12, point))) return FALSE; R3Plane plane20(p0, triangle.Normal(), p0 - p2); if (RNIsNegative(R3SignedDistance(plane20, point))) return FALSE; // Triangle contains point return TRUE; }
void R3Model:: Draw(const R3DrawFlags draw_flags) const { // Check triangles if (!triangles) return; if (triangles->NTriangles() == 0) return; assert(triangle_materials.NEntries() == NTriangles()); assert(material_triangles.NEntries() == NMaterials()); // Draw model if (draw_flags != 0) { # if (DRAW_METHOD == DRAW_WITH_VBO) // Initialize material R3null_material.Draw(TRUE); // Create VBO if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Create VBO vertex array VBOVertex *vbo_vertices = new VBOVertex [ NVertices() ]; for (int i = 0; i < NVertices(); i++) { R3TriangleVertex *vertex = Vertex(i); const R3Point& position = vertex->Position(); const R2Point& texcoords = vertex->TextureCoords(); vbo_vertices[i].x = position.X(); vbo_vertices[i].y = position.Y(); vbo_vertices[i].z = position.Z(); vbo_vertices[i].s = texcoords.X(); vbo_vertices[i].t = texcoords.Y(); vertex->SetMark(i); } // Create VBO triangle array GLint *vbo_triangles = new GLint [ 3 * NTriangles() ]; for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3TriangleVertex *v0 = triangle->Vertex(0); R3TriangleVertex *v1 = triangle->Vertex(0); R3TriangleVertex *v2 = triangle->Vertex(0); vbo_triangles[3*i+0] = v0->Mark(); vbo_triangles[3*i+1] = v1->Mark(); vbo_triangles[3*i+2] = v2->Mark(); } // Create VBO for vertices glGenBuffers(1, &opengl_id); glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glBufferData(GL_ARRAY_BUFFER, NVertices() * sizeof(VBOVertex), vbo_vertices, GL_STATIC_DRAW); // Create VBO for triangles glGenBuffers(1, &opengl_id2); glBindBuffer(GL_ARRAY_BUFFER, opengl_id2); glBufferData(GL_ELEMENT_BUFFER, 3 * NTriangles() * sizeof(GLuint), vbo_triangles, GL_STATIC_DRAW); // Delete VBO data delete [] vbo_vertices; delete [] vbo_triangles; } // Draw VBO glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VBOVertex), (void *) 0); glTexCoordPointer(2, GL_FLOAT, sizeof(VBOVertex), (void *) (3 * sizeof(GLfloat))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, opengl_id2); glDrawElements(GL_TRIANGLES, NTriangles(), GL_UNSIGNED_INT, (void *) 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Reset material R3null_material.Draw(TRUE); # elif (DRAW_METHOD == DRAW_WITH_DISPLAY_LIST) // Initialize material R3null_material.Draw(TRUE); // Create display list if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Begin display list R3Model *model = (R3Model *) this; model->opengl_id = glGenLists(1); glNewList(opengl_id, GL_COMPILE); // Draw triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } // End display list glEndList(); } // Call display list glCallList(opengl_id); // Reset material R3null_material.Draw(TRUE); # else // Draw individual triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } # endif } else { // Draw triangles glBegin(GL_TRIANGLES); for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadPoint(v2->Position()); } glEnd(); } }