const Transform2 slerp(const Transform2& a, const Transform2& b, const float t) { GEOMETRY_RUNTIME_ASSERT(a.scaling > 0.0f); GEOMETRY_RUNTIME_ASSERT(b.scaling > 0.0f); return Transform2( mix(a.translation, b.translation, t), slerp(a.rotation, b.rotation, t), Math::mix(a.scaling, b.scaling, t) ); }
const Transform2 transform(const Transform2& a, const Transform2& b) { GEOMETRY_RUNTIME_ASSERT(a.scaling > 0.0f); GEOMETRY_RUNTIME_ASSERT(b.scaling > 0.0f); return Transform2( transform(a.translation, b), a.rotation * b.rotation, a.scaling * b.scaling ); }
const Transform2 transformByInverse(const Transform2& a, const Transform2& b) { GEOMETRY_RUNTIME_ASSERT(a.scaling > 0.0f); GEOMETRY_RUNTIME_ASSERT(b.scaling > 0.0f); return Transform2( transformByInverse(a.translation, b), timesTranspose(a.rotation, b.rotation), a.scaling / b.scaling ); }
const Transform2 inverse(const Transform2& t) { GEOMETRY_RUNTIME_ASSERT(t.scaling > 0.0f); const Matrix2x2 r = transpose(t.rotation); const float s = 1.0f / t.scaling; return Transform2( (-s * t.translation) * r, r, s ); }
const Transform2 transformInverseBy(const Transform2& a, const Transform2& b) { GEOMETRY_RUNTIME_ASSERT(a.scaling > 0.0f); GEOMETRY_RUNTIME_ASSERT(b.scaling > 0.0f); const Matrix2x2 r = transposeTimes(a.rotation, b.rotation); const float s = b.scaling / a.scaling; return Transform2( (-s * a.translation) * r + b.translation, r, s ); }
static void UINT4tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_UINT4);}
static void UINT2tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_UINT2);}
static void UINT2tINT4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_INT4, CR_UINT2);}
static void INT2tREAL8(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL8, CR_INT2);}
static void INT1tREAL4(size_t nrCells, void *buf) { Transform2(nrCells, buf, CR_REAL4, CR_INT1);}
void Configure(unsigned int aId, const TiXmlElement *element) { // tilemap configuration float x = 0.0f, y = 0.0f; element->QueryFloatAttribute("x", &x); element->QueryFloatAttribute("y", &y); float dx = 1.0f, dy = 1.0f; element->QueryFloatAttribute("dx", &dx); element->QueryFloatAttribute("dy", &dy); // tiles struct Tile { unsigned int mSpawn; Transform2 mOffset; }; Tile map[CHAR_MAX-CHAR_MIN+1]; memset(map, 0, sizeof(map)); // position value Vector2 pos(x, y); // get the tilemap template TilemapTemplate &tilemap = Database::tilemaptemplate.Open(aId); // process child elements for (const TiXmlElement *child = element->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) { switch(Hash(child->Value())) { case 0x713a7cc9 /* "tile" */: { const char *name = child->Attribute("name"); if (!name || !name[0]) continue; Tile &tile = map[name[0]-CHAR_MIN]; const char *spawn = child->Attribute("spawn"); tile.mSpawn = Hash(spawn); child->QueryFloatAttribute("x", &tile.mOffset.p.x); child->QueryFloatAttribute("y", &tile.mOffset.p.y); if (child->QueryFloatAttribute("angle", &tile.mOffset.a) == TIXML_SUCCESS) tile.mOffset.a *= float(M_PI) / 180.0f; } break; case 0x440e1d7b /* "row" */: { pos.x = x; const char *text = child->Attribute("data"); if (!text) text = child->GetText(); if (!text) continue; for (const char *t = text; *t; ++t) { Tile &tile = map[*t-CHAR_MIN]; if (tile.mSpawn) { Transform2 transform(tile.mOffset * Transform2(0, pos)); if (aId) tilemap.Add(tile.mSpawn, transform); else Database::Instantiate(tile.mSpawn, 0, 0, transform.a, transform.p); } pos.x += dx; } pos.y += dy; } break; default: break; } } Database::tilemaptemplate.Close(aId); }
template<> inline Transform2 Cast<Transform2, __m128>(__m128 i) { return Transform2(i.m128_f32[2], Vector2(i.m128_f32[0], i.m128_f32[1])); }
const Transform2 Transform2::identity() { return Transform2(Vector2::zero(), Matrix2x2::identity(), 1.0f); }
void Renderable::RenderAll(const AlignedBox2 &aView) { // render matrix float angle; Vector2 position; #ifdef RENDER_STATS // stats int drawn = 0, culled = 0; #endif // render all renderables Renderable *itor = sHead; while (itor) { // get the next iterator // (in case the entry gets deleted) Renderable *next = itor->mNext; // get the entity (HACK) const Entity *entity = Database::entity.Get(itor->mId); if (!entity) { itor = next; continue; } #ifdef RENDER_SIMULATION_POSITIONS // draw line between last and current simulated position glBegin(GL_LINES); glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(entity->GetPrevPosition().x, entity->GetPrevPosition().y); glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(entity->GetPosition().x, entity->GetPosition().y); glEnd(); #endif // get interpolated position position = entity->GetInterpolatedPosition(sim_fraction); // if within the view area... if (position.x + itor->mRadius >= aView.min.x && position.y + itor->mRadius >= aView.min.y && position.x - itor->mRadius <= aView.max.x && position.y - itor->mRadius <= aView.max.y) { // get interpolated angle angle = entity->GetInterpolatedAngle(sim_fraction); // get the renderable template const RenderableTemplate &renderable = Database::renderabletemplate.Get(itor->mId); // elapsed time float t = fmodf((int(sim_turn - itor->mStart) + sim_fraction - itor->mFraction) * sim_step, renderable.mPeriod); // render (itor->mAction)(itor->mId, t, renderable.mTransform ? Transform2(angle, position) : Transform2::Identity()); #ifdef RENDER_STATS ++drawn; #endif } #ifdef RENDER_STATS else { ++culled; } #endif // go to the next iterator itor = next; } #ifdef RENDER_STATS DebugPrint("d=%d/%d\n", drawn, drawn+culled); #endif }