CTransform get(CObject* pObject) const { assert(pObject != nullptr); auto it = mTransforms.find(pObject); if(it == mTransforms.end()) return CTransform(); return it->second; }
void CModelFile::draw() { currentMaterialSet().setAmbient(m_ambient); CTransform model = CTransform(m_rotation) * CTransformFromScaleVector(m_scale); model.m_origin = m_position; CModelData::drawIbos(false, currentMaterialSet(), model); CModelData::drawIbos(true, currentMaterialSet(), model); }
CTransform CTransform::Scale(const CVector3& scalingVec) { CMatrix4x4 S(scalingVec.x, 0.0, 0.0, 0.0, 0.0, scalingVec.y, 0.0, 0.0, 0.0, 0.0, scalingVec.z, 0.0, 0.0, 0.0, 0.0, 1.0); CMatrix4x4 invS(1.0 / scalingVec.x, 0.0, 0.0, 0.0, 0.0, 1.0 / scalingVec.y, 0.0, 0.0, 0.0, 0.0, 1.0 / scalingVec.z, 0.0, 0.0, 0.0, 0.0, 1.0); return CTransform(S, invS); }
CTransform CTransform::Translate(const CVector3& translationVec) { CMatrix4x4 T(1.0, 0.0, 0.0, translationVec.x, 0.0, 1.0, 0.0, translationVec.y, 0.0, 0.0, 1.0, translationVec.z, 0.0, 0.0, 0.0, 1.0); CMatrix4x4 invT(1.0, 0.0, 0.0, -translationVec.x, 0.0, 1.0, 0.0, -translationVec.y, 0.0, 0.0, 1.0, -translationVec.z, 0.0, 0.0, 0.0, 1.0); return CTransform(T, invT); }
CTransform CTransform::RotateZ(const F& angle) { F sinx = sin(CMath::Deg2Rad(angle)); F cosx = cos(CMath::Deg2Rad(angle)); CMatrix4x4 RZ(cosx, -sinx, 0.0, 0.0, sinx, cosx, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); CMatrix4x4 invRZ(RZ); invRZ.Transpose(); return CTransform(RZ, invRZ); }
CTransform CTransform::RotateY(const F& angle) { F sinx = sin(CMath::Deg2Rad(angle)); F cosx = cos(CMath::Deg2Rad(angle)); CMatrix4x4 RY(cosx, 0.0, sinx, 0.0, 0.0, 1.0, 0.0, 0.0, -sinx, 0.0, cosx, 0.0, 0.0, 0.0, 0.0, 1.0); CMatrix4x4 invRY(RY); invRY.Transpose(); return CTransform(RY, invRY); }
CTransform CTransform::RotateX(const F& angle) { F sinx = sin(CMath::Deg2Rad(angle)); F cosx = cos(CMath::Deg2Rad(angle)); CMatrix4x4 RX(1.0, 0.0, 0.0, 0.0, 0.0, cosx, -sinx, 0.0, 0.0, sinx, cosx, 0.0, 0.0, 0.0, 0.0, 1.0); CMatrix4x4 invRX(RX); invRX.Transpose(); return CTransform(RX, invRX); }
CMapArea* CMapAreaReader::read() { CMapArea* ret = nullptr; try { atUint32 magic = base::readUint32(); if (magic != 0xDEADD00D) THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Not a valid MAPA file got 0x%.8X", magic); CMapArea::Version version = (CMapArea::Version)base::readUint32(); if (version != CMapArea::Version::MetroidPrime1 && version != CMapArea::Version::MetroidPrime2 && version != CMapArea::Version::MetroidPrime3) THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Only Metroid Prime 1-3 Minimaps are supported got version %i", (atUint32)version); ret = new CMapArea; CMaterial material; atUint32 materialFlags = 0; materialFlags |= 0x8; materialFlags |= 0x80; material.setMaterialFlags(materialFlags); atUint32 vertexAttributes = 0; vertexAttributes |= 3; material.setVertexAttributes(vertexAttributes); material.setBlendMode(EBlendMode::Zero, EBlendMode::One); STEVStage tevStage; tevStage.ColorInFlags = 0xE | (0xF << 5) | (0xF << 10) | (0xF << 15); tevStage.AlphaInFlags = 0x6 | (0x7 << 5) | (0x7 << 10) | (0x7 << 15); tevStage.ColorOpFlags = 0; tevStage.AlphaOpFlags = 0; tevStage.KonstColorIn = 0x0C; tevStage.KonstAlphaIn = 0x1C; material.addTevStage(tevStage, 0); ret->m_materialID = CMaterialCache::instance()->addMaterial(material); ret->m_unknown1 = base::readUint32(); ret->m_unknown2 = base::readUint32(); ret->m_boundingBox.readBoundingBox(*this); if (version != CMapArea::Version::MetroidPrime1) { base::readUint32(); base::readUint32(); base::readUint32(); if (version == CMapArea::Version::MetroidPrime3) base::readUint32(); } atUint32 poiCount = base::readUint32(); atUint32 vertexCount = base::readUint32(); atUint32 detailCount = base::readUint32(); atUint64 headerSize = base::position(); if (version == CMapArea::Version::MetroidPrime3) { atUint32 stringLength = base::readUint32(); base::readUint32(); headerSize = base::position(); if (stringLength > 0) base::readString(stringLength); } for (atUint32 i = 0; i < poiCount; i++) { SPointOfInterest pointOfInterest; if (version == CMapArea::Version::MetroidPrime3) pointOfInterest.unknown1 = readUint32(); pointOfInterest.type = base::readUint32(); pointOfInterest.unknown2 = base::readUint32(); if (version != CMapArea::Version::MetroidPrime3) { pointOfInterest.unknown3 = base::readUint16(); pointOfInterest.id = base::readUint16(); } else { pointOfInterest.unknown4.readRGBA(*this); } base::seek(4); // padding; CMatrix3f transformBasis; CVector3f transformOrigin; for (atUint32 i = 0; i < 3; i++) { transformBasis[i].x = base::readFloat(); transformBasis[i].y = base::readFloat(); transformBasis[i].z = base::readFloat(); transformOrigin[i] = base::readFloat(); } pointOfInterest.transform = CTransform(transformBasis.transposed(), transformOrigin); base::seek(4*4); // padding; ret->m_pointsOfInterest.push_back(pointOfInterest); } for (atUint32 i = 0; i < vertexCount; ++i) { CVector3f vec(*this); ret->m_vertices.push_back(vec); } for (atUint32 i = 0; i < detailCount; i++) { SMapAreaDetail detail; detail.boundingBox.readBoundingBox(*this); atUint32 primDataStart = base::readUint32(); atUint32 primDataEnd = base::readUint32(); atUint64 oldPos = base::position(); base::seek(primDataStart + headerSize, Athena::SeekOrigin::Begin); atUint32 primitiveCount = base::readUint32(); for (atUint32 j = 0; j < primitiveCount; j++) { SMapAreaPrimitive primitive; atUint32 type = base::readUint32(); switch((EPrimitive)type) { case EPrimitive::Quads: primitive.type = GL_QUADS; break; case EPrimitive::Triangles: primitive.type = GL_TRIANGLES; break; case EPrimitive::TriangleStrip: primitive.type = GL_TRIANGLE_STRIP; break; case EPrimitive::TriangleFan: primitive.type = GL_TRIANGLE_FAN; break; case EPrimitive::Lines: primitive.type = GL_LINES; break; case EPrimitive::LineStrip: primitive.type = GL_LINE_STRIP; break; case EPrimitive::Points: primitive.type = GL_POINTS; break; } atUint32 indexCount = base::readUint32(); for (atUint32 k = 0; k < indexCount; ++k) { atUint16 idx = (atUint16)base::readUByte(); primitive.indices.push_back(idx); } if (type != 0) { //primitive.indices.push_back(0xFFFF); detail.primitives.push_back(primitive); } base::seek((base::position() + 3) & ~3, Athena::SeekOrigin::Begin); } base::seek(primDataEnd + headerSize, Athena::SeekOrigin::Begin); atUint32 borderCount = base::readUint32(); for (atUint32 j = 0; j < borderCount; j++) { SMapBorder border; atUint32 borderIndexCount = base::readUint32(); for (atUint32 k = 0; k < borderIndexCount; ++k) { atInt16 idx =(atInt16)base::readUByte(); border.indices.push_back(idx); } //border.indices.push_back(0xFFFF); detail.borders.push_back(border); base::seek((base::position() + 3) & ~3, Athena::SeekOrigin::Begin); } ret->m_details.push_back(detail); base::seek(oldPos, Athena::SeekOrigin::Begin); } } catch(...) { delete ret; ret = nullptr; throw; } return ret; }
/// Step forward the simulation void Box2DSystem::update(const Time& deltaTime) { mSimulation->Step(deltaTime.seconds(), 8, 8); // Compute stuff with the world ComponentManager* colliderBoxManager = mWorld->getComponentManager<CColliderBox>(); ComponentManager* transformManager = mWorld->getComponentManager<CTransform>(); for (std::size_t i = 0; i < colliderBoxManager->getInstanceCount(); ++i) { CColliderBox* boxCollider = (CColliderBox*)colliderBoxManager->getInstance(i); CTransform* transform = (CTransform*)transformManager->getComponentFromEntity(colliderBoxManager->getInstanceEntity(i)); if (!transform) { mWorld->createComponent(CTransform(), colliderBoxManager->getInstanceEntity(i)); transform = (CTransform*)transformManager->getComponentFromEntity(colliderBoxManager->getInstanceEntity(i)); } if (!boxCollider->userData) { b2BodyDef groundBodyDef2; groundBodyDef2.type = boxCollider->_isDynamic ? b2_dynamicBody : b2_staticBody; groundBodyDef2.position = b2Vec2(transform->getPosition().x, transform->getPosition().y); b2Body* groundBody2 = mSimulation->CreateBody(&groundBodyDef2); b2PolygonShape groundShape2; groundShape2.SetAsBox(10.f, 10.f); groundBody2->CreateFixture(&groundShape2, 1.f); groundBody2->SetUserData(boxCollider); boxCollider->userData = groundBody2; } else { b2Body* boxColliderBody = (b2Body*)boxCollider->userData; transform->position.x = boxColliderBody->GetPosition().x; transform->position.y = boxColliderBody->GetPosition().y; transform->rotation = Quaternion::fromMatrix(mat4::rotatez(boxColliderBody->GetAngle())); } } // Now let's go through the actors to find stuff in them for (std::size_t i = 0; i < mWorld->actors.size(); ++i) { Actor* actor = mWorld->actors[i]; SCColliderBox* box = dynamic_cast<SCColliderBox*>(actor->getRootComponent()); if (box) { if (!box->userData) { b2BodyDef groundBodyDef2; groundBodyDef2.type = box->_isDynamic ? b2_dynamicBody : b2_staticBody; groundBodyDef2.position = b2Vec2(actor->getActorLocation().x, actor->getActorLocation().y); b2Body* groundBody2 = mSimulation->CreateBody(&groundBodyDef2); b2PolygonShape groundShape2; groundShape2.SetAsBox(10.f, 10.f); groundBody2->CreateFixture(&groundShape2, 1.f); groundBody2->SetUserData(box); box->userData = groundBody2; box->rigidBody = new RigidBodyBox2D(groundBody2); } // Apply manual forces b2Body* boxColliderBody = (b2Body*)box->userData; CTransform transform = box->t; transform.position.x = boxColliderBody->GetPosition().x; transform.position.y = boxColliderBody->GetPosition().y; transform.rotation = Quaternion::fromMatrix(mat4::rotatez(boxColliderBody->GetAngle())); // Push the new physics transform back to the actor actor->setTransform(transform); } } }