#include "sprite.hpp" #include "std.hpp" extern float stats3d[]; static float null[] = {0, 0, 0}; static float tex_coords0[2][2] = {{0, 0}, {0, 0}}; static float tex_coords1[2][2] = {{1, 0}, {1, 0}}; static float tex_coords2[2][2] = {{1, 1}, {1, 1}}; static float tex_coords3[2][2] = {{0, 1}, {0, 1}}; extern gxRuntime* gx_runtime; extern gxGraphics* gx_graphics; static gxMesh* mesh; static int mesh_size; static vector mesh_indices; static int allocIndex() { if (!mesh_indices.size()) { if (mesh_size) gx_graphics->freeMesh(mesh); for (int k = 0; k < 256; ++k) { mesh_indices.push_back(mesh_size++); } mesh = gx_graphics->createMesh(mesh_size * 4, mesh_size * 2, 0); } int n = mesh_indices.back(); mesh_indices.pop_back(); return n; } static void freeIndex(int n) { mesh_indices.push_back(n); if (mesh_indices.size() != mesh_size) return; gx_graphics->freeMesh(mesh); mesh_indices.clear(); mesh_size = 0; } Sprite::Sprite() : view_mode(VIEW_MODE_FREE), xhandle(0), yhandle(0), rot(0), xscale(1), yscale(1), captured(false) { setRenderSpace(RENDER_SPACE_WORLD); mesh_index = allocIndex(); } Sprite::Sprite(const Sprite& t) : Model(t), view_mode(t.view_mode), xhandle(t.xhandle), yhandle(t.yhandle), rot(t.rot), xscale(t.xscale), yscale(t.yscale), captured(false) { mesh_index = allocIndex(); } Sprite::~Sprite() { freeIndex(mesh_index); } void Sprite::setRotation(float angle) { rot = angle; } void Sprite::setScale(float x, float y) { xscale = x; yscale = y; } void Sprite::setHandle(float x, float y) { xhandle = x; yhandle = y; } void Sprite::setViewmode(int mode) { view_mode = mode; } void Sprite::capture() { Model::capture(); r_rot = rot; r_xscale = xscale; r_yscale = yscale; captured = true; } bool Sprite::beginRender(float tween) { Model::beginRender(tween); if (tween == 1 || !captured) { r_rot = rot; r_xscale = xscale; r_yscale = yscale; } else { r_rot = (rot - r_rot) * tween + r_rot; r_xscale = (xscale - r_xscale) * tween + r_xscale; r_yscale = (yscale - r_yscale) * tween + r_yscale; } return true; } bool Sprite::render(const RenderContext& rc) { Transform t = getRenderTform(); if (view_mode == VIEW_MODE_FREE) { t.m = rc.getCameraTform().m; } else if (view_mode == VIEW_MODE_UPRIGHT) { t.m.k = rc.getCameraTform().m.k; t.m.orthogonalize(); } else if (view_mode == VIEW_MODE_UPRIGHT2) { t.m = yawMatrix(matrixYaw(rc.getCameraTform().m)) * t.m; } t.m = t.m * rollMatrix(r_rot) * scaleMatrix(r_xscale, r_yscale, 1); static Vector verts[4]; verts[0] = t * Vector(-1 - xhandle, 1 - yhandle, 0); verts[1] = t * Vector(1 - xhandle, 1 - yhandle, 0); verts[2] = t * Vector(1 - xhandle, -1 - yhandle, 0); verts[3] = t * Vector(-1 - xhandle, -1 - yhandle, 0); if (!rc.getWorldFrustum().cull(verts, 4)) return false; mesh->lock(false); int fv = mesh_index * 4, ft = mesh_index * 2; mesh->setVertex(fv + 0, &verts[0].x, null, tex_coords0); mesh->setVertex(fv + 1, &verts[1].x, null, tex_coords1); mesh->setVertex(fv + 2, &verts[2].x, null, tex_coords2); mesh->setVertex(fv + 3, &verts[3].x, null, tex_coords3); if (rc.isReflected()) { mesh->setTriangle(ft + 0, 0, 2, 1); mesh->setTriangle(ft + 1, 0, 3, 2); } else { mesh->setTriangle(ft + 0, 0, 1, 2); mesh->setTriangle(ft + 1, 0, 2, 3); } mesh->unlock(); enqueue(mesh, fv, 4, ft, 2); return false; }