/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include #include "core/renderer_toolbox.h" #include "core/core_profiler.h" #include "core/item.h" #include "core/raster_font.h" #include "log/log.h" #if __PLATFORM_NINTENDO_WII__ #include "system/wii_memory.h" #include "wii_platform.h" #endif using namespace GS::Units; using namespace GS::Math; namespace GS { namespace RendererToolbox { //------------------------------------------------------------------------------ void Triangle3D(Renderer &render, const Vector4 vtx[3], const Color color[3], const Vector2 uv[3], const Render::Texture *t, Material::BlendOperator blendop, Material::RenderWord rword) { render.DrawTriangle(1, vtx, NULL, color, uv, t, blendop, rword); } void Line3D(Renderer &render, const Vector4 &a, const Vector4 &b, const Color *c, Material::BlendOperator bo, Material::RenderWord rw) { Vector4 v[2] = { a, b }; Color u[2] = { c ? *c : Color(1, 1, 1), c ? *c : Color(1, 1, 1) }; render.DrawLine(1, v, u, bo, rw); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DrawCircle(Renderer &render, const Vector4 &position, float radius, const Matrix3 *m, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Matrix3 m3 = m ? *m : Matrix3::IdentityMatrix(); for (float a = Deg(0.f); a < Deg(360.f); a += Deg(10.f)) Line3D(render, Vector4(Cos(a), Sin(a), 0) * m3 * radius + position, Vector4(Cos(a + Deg(10.f)), Sin(a + Deg(10.f)), 0) * m3 * radius + position, color, bo); } void DrawCylinder(Renderer &render, const Vector4 &position, float radius, float length, const Matrix3 *m, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Matrix3 m3 = m ? *m : Matrix3::IdentityMatrix(); DrawCircle(render, position + Vector4(0, 0, length * 0.5f) * m3, radius, &m3, color); DrawCircle(render, position + Vector4(0, 0, length * -0.5f) * m3, radius, &m3, color); Line3D(render, position + Vector4(radius, 0, length * 0.5f) * m3, position + Vector4(radius, 0, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(-radius, 0, length * 0.5f) * m3, position + Vector4(-radius, 0, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(0, radius, length * 0.5f) * m3, position + Vector4(0, radius, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(0, -radius, length * 0.5f) * m3, position + Vector4(0, -radius, length * -0.5f) * m3, color, bo); } void DrawCapsule(Renderer &render, const Vector4 &position, float radius, float length, const Matrix3 *m, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Matrix3 m3 = m ? *m : Matrix3::IdentityMatrix(); DrawSphere(render, position + Vector4(0, 0, length * 0.5f) * m3, radius, color); DrawSphere(render, position - Vector4(0, 0, length * 0.5f) * m3, radius, color); Line3D(render, position + Vector4(radius, 0, length * 0.5f) * m3, position + Vector4(radius, 0, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(-radius, 0, length * 0.5f) * m3, position + Vector4(-radius, 0, length * -0.5f) * m3, color, bo); } void DrawCone(Renderer &render, const Vector4 &position, float radius, float length, const Matrix3 *m, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Matrix3 m3 = m ? *m : Matrix3::IdentityMatrix(); DrawCircle(render, position + Vector4(0, 0, length * -0.5f) * m3, radius, &m3, color); Line3D(render, position + Vector4(0, 0, length * 0.5f) * m3, position + Vector4(radius, 0, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(0, 0, length * 0.5f) * m3, position + Vector4(-radius, 0, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(0, 0, length * 0.5f) * m3, position + Vector4(0, radius, length * -0.5f) * m3, color, bo); Line3D(render, position + Vector4(0, 0, length * 0.5f) * m3, position + Vector4(0, -radius, length * -0.5f) * m3, color, bo); } void DrawSphere(Renderer &render, const Vector4 &p, float r, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); #define SPHERE_NSEG 36 uint n; float sn, cs; Vector4 a[2], b[2], c[2]; float angle, dt; Color _r(1, 1, 0), _g(1, 1, 0), _b(1, 1, 0); angle = 0; dt = Deg(360.f) / SPHERE_NSEG; sn = Sin(angle) * r; cs = Cos(angle) * r; a[1].Set(p.x, p.y + cs, p.z + sn); b[1].Set(p.x + sn, p.y + cs, p.z); c[1].Set(p.x + cs, p.y, p.z + sn); for (n = 0; n < SPHERE_NSEG; n++) { a[0] = a[1]; b[0] = b[1]; c[0] = c[1]; angle += dt; sn = Sin(angle) * r; cs = Cos(angle) * r; a[1].Set(p.x, p.y + cs, p.z + sn); b[1].Set(p.x + sn, p.y + cs, p.z); c[1].Set(p.x + cs, p.y, p.z + sn); Line3D(render, a[0], a[1], color ? color : &_r); Line3D(render, b[0], b[1], color ? color : &_g); Line3D(render, c[0], c[1], color ? color : &_b); } } void DrawBall(Renderer &render, const Matrix4 &m, float r, Color *uc, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); #define BALL_NSEG 24 uint n; float sn, cs; Vector4 a[2], b[2], c[2]; float angle, dt; angle = 0; dt = Deg(360.f) / BALL_NSEG; sn = Sin(angle) * r; cs = Cos(angle) * r; a[1].Set(0, cs, sn); b[1].Set(sn, cs, 0); c[1].Set(cs, 0, sn); a[1] *= m; b[1] *= m; c[1] *= m; Color color(1, 1, 1); if (!uc) uc = &color; for (n = 0; n < BALL_NSEG; n++) { a[0] = a[1]; b[0] = b[1]; c[0] = c[1]; angle += dt; sn = Sin(angle) * r; cs = Cos(angle) * r; a[1].Set(0, cs, sn); b[1].Set(sn, cs, 0); c[1].Set(cs, 0, sn); a[1] *= m; b[1] *= m; c[1] *= m; Line3D(render, a[0], a[1], uc, bo); Line3D(render, b[0], b[1], uc, bo); Line3D(render, c[0], c[1], uc, bo); } } void DrawCross(Renderer &render, const Vector4 &c, float size, const Color *color, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); const Color dft(1, 1, 1), *cl; if (color) cl = color; else cl = &dft; Vector4 o(c); Vector4 a[2]; a[0] = o; a[1] = o; a[0].x -= size; a[1].x += size; Line3D(render, a[0], a[1], cl, bo); a[0] = o; a[1] = o; a[0].y -= size; a[1].y += size; Line3D(render, a[0], a[1], cl, bo); a[0] = o; a[1] = o; a[0].z -= size; a[1].z += size; Line3D(render, a[0], a[1], cl, bo); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DrawAABB(Renderer &render, const MinMax &minmax, const Color *c, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); const Color color(0.5, 1.0, 0); if (!c) c = &color; const Vector4 *min = &minmax.mn, *max = &minmax.mx; Vector4 v[2]; v[0].Set(min->x, min->y, min->z); v[1].Set(max->x, min->y, min->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, min->y, min->z); v[1].Set(min->x, min->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(max->x, min->y, min->z); v[1].Set(max->x, min->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, min->y, max->z); v[1].Set(max->x, min->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, max->y, min->z); v[1].Set(max->x, max->y, min->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, max->y, min->z); v[1].Set(min->x, max->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(max->x, max->y, min->z); v[1].Set(max->x, max->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, max->y, max->z); v[1].Set(max->x, max->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, min->y, min->z); v[1].Set(min->x, max->y, min->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(max->x, min->y, min->z); v[1].Set(max->x, max->y, min->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(max->x, min->y, max->z); v[1].Set(max->x, max->y, max->z); Line3D(render, v[0], v[1], c, bo); v[0].Set(min->x, min->y, max->z); v[1].Set(min->x, max->y, max->z); Line3D(render, v[0], v[1], c, bo); } void DrawOBB(Renderer &render, const OBB &obb, const Color *color, Material::BlendOperator bo) { Vector4 vtx[8], _vtx[8]; _vtx[0].Set(-0.5, 0.5, 0.5); _vtx[1].Set( 0.5, 0.5, 0.5); _vtx[2].Set( 0.5, -0.5, 0.5); _vtx[3].Set(-0.5, -0.5, 0.5); _vtx[4].Set(-0.5, 0.5, -0.5); _vtx[5].Set( 0.5, 0.5, -0.5); _vtx[6].Set( 0.5, -0.5, -0.5); _vtx[7].Set(-0.5, -0.5, -0.5); Matrix4 mtx = Matrix4::FromMatrix3(obb.bb_rotation * Matrix3::ScaleMatrix(obb.bb_scale)); mtx.SetRow(3, obb.bb_position); mtx.Apply(vtx, _vtx, 8); const Color _color(1, 0.5f, 0); if (!color) color = &_color; render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Line3D(render, vtx[0], vtx[1], color, bo); Line3D(render, vtx[1], vtx[2], color, bo); Line3D(render, vtx[2], vtx[3], color, bo); Line3D(render, vtx[3], vtx[0], color, bo); Line3D(render, vtx[4], vtx[5], color, bo); Line3D(render, vtx[5], vtx[6], color, bo); Line3D(render, vtx[6], vtx[7], color, bo); Line3D(render, vtx[7], vtx[4], color, bo); Line3D(render, vtx[0], vtx[4], color, bo); Line3D(render, vtx[1], vtx[5], color, bo); Line3D(render, vtx[2], vtx[6], color, bo); Line3D(render, vtx[3], vtx[7], color, bo); } void DrawFilledOBB(Renderer &render, const OBB &obb, const Color *_color, Material::BlendOperator bo, Material::RenderWord rw) { Vector4 vtx[8], v[4]; vtx[0].Set(-0.5, 0.5, 0.5); vtx[1].Set( 0.5, 0.5, 0.5); vtx[2].Set( 0.5, -0.5, 0.5); vtx[3].Set(-0.5, -0.5, 0.5); vtx[4].Set(-0.5, 0.5, -0.5); vtx[5].Set( 0.5, 0.5, -0.5); vtx[6].Set( 0.5, -0.5, -0.5); vtx[7].Set(-0.5, -0.5, -0.5); Matrix4 mtx = Matrix4::FromMatrix3(obb.bb_rotation * Matrix3::ScaleMatrix(obb.bb_scale)); mtx.SetRow(3, obb.bb_position); render.SetWorldMatrix(mtx); Color color[3]; for (int n = 0; n < 3; ++n) color[n] = _color ? *_color : Color(1, 0.5f, 0); v[0] = vtx[0]; v[1] = vtx[1]; v[2] = vtx[2]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[0]; v[1] = vtx[2]; v[2] = vtx[3]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[4]; v[1] = vtx[5]; v[2] = vtx[1]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[4]; v[1] = vtx[1]; v[2] = vtx[0]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[7]; v[1] = vtx[6]; v[2] = vtx[5]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[7]; v[1] = vtx[5]; v[2] = vtx[4]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[3]; v[1] = vtx[2]; v[2] = vtx[6]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[3]; v[1] = vtx[6]; v[2] = vtx[7]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[2]; v[1] = vtx[1]; v[2] = vtx[5]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[2]; v[1] = vtx[5]; v[2] = vtx[6]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[0]; v[1] = vtx[3]; v[2] = vtx[7]; Triangle3D(render, v, color, NULL, NULL, bo, rw); v[0] = vtx[0]; v[1] = vtx[7]; v[2] = vtx[4]; Triangle3D(render, v, color, NULL, NULL, bo, rw); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DrawCube(Renderer &render, const Vector4 &p, float size, const Color *color, Material::BlendOperator bo) { const Color _color(0, 0.5, 1.f); if (!color) color = &_color; Vector4 dt(size, size, size); Vector4 t = p - dt; Vector4 t2 = p + dt; MinMax mnmx(t, t2); DrawAABB(render, mnmx, color, bo); } void DrawSquare(Renderer &render, const Vector4 &p, float size, Material::BlendOperator bo) { render.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix()); Vector4 a(p), b(p), c(p), d(p); a.x -= size; a.y -= size; b.x += size; b.y -= size; c.x += size; c.y += size; d.x -= size; d.y += size; Color cs(1, 1, 1); Line3D(render, a, b, &cs, bo); Line3D(render, b, c, &cs, bo); Line3D(render, c, d, &cs, bo); Line3D(render, d, a, &cs, bo); } //------------------------------------------------------------------------------ } // RendererToolbox } // GS