#include "Model.h" bool ModelMesh::Load(String file, VBOLibrary &lib, Point3f scale) { FileIn fin(file); if (!fin.IsOpen()) return false; Vector t; Vector v; bool smoothnormals; s % alphasort % smoothnormals; v.Serialize(fin); t.Serialize(t); Scale(v, t, scale, smoothnormals); vbo = lib.GetVertexBuffer(v); if (!vbo) return false; ibo = lib.GetIndexBuffer(t); return ibo > 0; } void ModelMesh::Draw() { #error Do model drawing } void ModelMesh::Scale(Vector &v, Vector &tri, Point3f scale, bool smooth_normals) { for (int i = 0; i < v.GetCount(); i++) { v[i].pos.x *= scale.x; v[i].pos.y *= scale.y; v[i].pos.z *= scale.z; v[i].normal = Point3f(0.0f, 0.0f, 0.0f); } if (smooth_normals) { for (int i = 0; i < tri.GetCount(); i++) { Triangle &t = tri[i]; Point3f n = t.GetNormal(v[t.a].pos, v[t.b].pos, v[t.v].pos); v[t.a].normal += n; v[t.b].normal += n; v[t.c].normal += n; } for (int i = 0; i < v.GetCount(); i++) v[i].normal.Unit(); } else for (int i = 0; i < tri.GetCount(); i++) { Triangle &t = tri[i]; Point3f n = t.GetNormal(v[t.a].pos, v[t.b].pos, v[t.v].pos); v[t.a].normal = n; v[t.b].normal = n; v[t.c].normal = n; } } void CreateUpStair(Vector &v, Vector &t, float floorcy) { float landingcx = 0.2; float stairstart = 1.0f - landingcx; // 0 - 3 Landing upper face v.Add(Vertex(0.0f, 0.0f, 0.5f)); v.Add(Vertex(landingcx, 0.0f, 0.5f)); v.Add(Vertex(landingcx, 1.0f, 0.5f)); v.Add(Vertex(0.0f, 1.0f, 0.5f)); // 4 - 7 Landing lower face v.Add(Vertex(0.0f, 0.0f, 0.5f - floorcy)); v.Add(Vertex(landingcx, 0.0f, 0.5f - floorcy)); v.Add(Vertex(landingcx, 1.0f, 0.5f - floorcy)); v.Add(Vertex(0.0f, 1.0f, 0.5f - floorcy)); // 8 - 10 Ramp upper face v.Add(Vertex(stairstart, stairstart, 0.0f)); v.Add(Vertex(stairstart, 1.0f, 0.0f)); v.Add(Vertex(landingcx, 1.0f, 0.5f)); v.Add(Vertex(landingcx, stairstart, 0.5f)); // 11 - 13 Ramp lower face v.Add(Vertex(stairstart, stairstart, 0.5f - floorcy)); v.Add(Vertex(stairstart, 1.0f, -floorcy)); v.Add(Vertex(landingcx, 1.0f, 0.5f - floorcy)); v.Add(Vertex(landingcx, stairstart, 0.5f - floorcy)); float a = floorcy float c = 1.0f - landingcx*2; float d = 0.5f - floorcy; AddCube(t, 0, true, true, true); AddCube(t, 8, true, false, true); } void CreateDownStair(Vector &v, Vector &t, float floorcy) { float landingcx = 0.2; float stairend = 1.0f - landingcx; floorcy = -floorcy; // 0 - 3 Floor pt1 upper face v.Add(Vertex(0.0f, landingcx, 0.0)); v.Add(Vertex(1.0f, landingcx, 0.0)); v.Add(Vertex(1.0f, 1.0f, 0.0)); v.Add(Vertex(0.0f, 1.0f, 0.0)); // 4 - 7 Floor pt1 lower face v.Add(Vertex(0.0f, landingcx, floorcy)); v.Add(Vertex(1.0f, landingcx, floorcy)); v.Add(Vertex(1.0f, 1.0f, floorcy)); v.Add(Vertex(0.0f, 1.0f, floorcy)); // 8 - 11 Floor pt2 upper face v.Add(Vertex(stairend, 0.0f, 0.0f)); v.Add(Vertex(1.0f, 0.0f, 0.0f)); v.Add(Vertex(1.0f, landingcx, 0.0f)); v.Add(Vertex(stairend, landingcx, 0.0f)); // 12 - 15 Floor pt2 lower face v.Add(Vertex(stairend, 0.0f, floorcy)); v.Add(Vertex(1.0f, 0.0f, floorcy)); v.Add(Vertex(1.0f, landingcx, floorcy)); v.Add(Vertex(stairend, landingcx, floorcy)); // 16 - 19 Ramp upper face v.Add(Vertex(landingcx, 0.0f, 0.5f)); v.Add(Vertex(stairend, 0.0f, 0.5f)); v.Add(Vertex(stairend, landingcx, 0.0f)); v.Add(Vertex(landingcx, landingcx, 0.0f)); // 20 - 23 Ramp lower face v.Add(Vertex(landingcx, 0.0f, 0.5f+floorcy)); v.Add(Vertex(stairend, 0.0f, 0.5f+floorcy)); v.Add(Vertex(stairend, landingcx, floorcy)); v.Add(Vertex(landingcx, landingcx, floorcy)); // Upper/lower faces AddCube(t, 0, true, true, true); AddCube(t, 8, true, true, true); t.Remove(t.GetCount()-2); // Remove top face AddCube(t, 16, true, true, true); t.Remove(t.GetCount()-3); // Remove right face } void CreateTrunk(Vector &v, Vector &t) { float thick = 0.1; float height = 0.3; Point3f c(0.5, 0.5, 0.0f) v.Add(Vertex(c.x - thick, c.y - thick, c.z)); v.Add(Vertex(c.x + thick, c.y - thick, c.z)); v.Add(Vertex(c.x + thick, c.y + thick, c.z)); v.Add(Vertex(c.x - thick, c.y + thick, c.z)); c.z += height; v.Add(Vertex(c.x - thick, c.y - thick, c.z)); v.Add(Vertex(c.x + thick, c.y - thick, c.z)); v.Add(Vertex(c.x + thick, c.y + thick, c.z)); v.Add(Vertex(c.x - thick, c.y + thick, c.z)); AddCube(t, 0, false, true, true); } void CreateDownStair(Vector &v, Vector &t, float floorcy) { float landingcx = 0.2; float stairend = 1.0f - landingcx; CreateDownStair(v, t, floorcy); v[2].y = stairend; v[3].y = stairend; v[6].y = stairend; v[7].y = stairend; CreateUpStair(v, t, floorcy); int pt3ix = v.GetCount(); // Floor pt3 upper face v.Add(Vertex(stairend, 0.0f, 0.0f)); v.Add(Vertex(1.0f, 0.0f, 0.0f)); v.Add(Vertex(1.0f, 1.0f, 0.0f)); v.Add(Vertex(stairend, 1.0f, 0.0f)); // Floor pt3 lower face v.Add(Vertex(stairend, 0.0f, floorcy)); v.Add(Vertex(1.0f, 0.0f, floorcy)); v.Add(Vertex(1.0f, 1.0f, floorcy)); v.Add(Vertex(stairend, 1.0f, floorcy)); // Upper/lower faces AddCube(t, pt3ix, true, true, true); t.Remove(t.GetCount() - 4); // Remove left face t.Remove(t.GetCount() - 2); // Remove bottom face } void AddCube(Vector &t, int ix, bool vertical, bool sides, bool ends) { // Up/Down if (vertical) { AddQuad(t, ix+0, ix+1, ix+2, ix+3); // Up AddQuad(t, ix+7, ix+6, ix+5, ix+4); // Down } if (sides) { // Sides AddQuad(t, ix+4, ix+5, ix+1, ix+0); // Left - 4 AddQuad(t, ix+3, ix+2, ix+6, ix+7); // Right - 3 } if (ends) { // Ends AddQuad(t, ix+0, ix+3, ix+7, ix+4); // Bottom - 2 AddQuad(t, ix+1, ix+2, ix+6, ix+5); // Top - 1 } } void AddQuad(Vector &t, int a, int b, int c, int d) { t.Add(Triangle(a, b, c, d)); } void SplitTriVertex(Vector &v, Vector &t, Vector &vout, Vector &tout) { out.Reserve(t.GetCount()*4); for (int i = 0; i < t.GetCount(); i++) { Quad &q = t[i]; int ix = vout.GetCount() Triangle t1(ix, ix+1, ix+2); Triangle t2(ix+2, ix+3, ix); SetTextureCoords(v[t.a], v[t.b], v[t.c], v[t.d]); vout.Add(v[t.a]); vout.Add(v[t.b]); vout.Add(v[t.c]); vout.Add(v[t.d]); tout.Add(t1); tout.Add(t2); } } void SetTextureCoords(Vertex &a, Vertex &b, Vertex &c, Vertex &d) { Point2f t; t.x = (a.pos - b.pos).Length(); t.y = (d.pos - a.pos).Length(); a.tex.x = 0.0f; a.tex.y = 0.0f; b.tex.x = t.x; b.tex.y = 0.0f; c.tex.x = t.xf; c.tex.y = t.yf; d.tex.x = 0.0; d.tex.y = t.yf; }