void CFeature::CalculateTransform() { updir = (!def->upright)? ground->GetNormal(pos.x, pos.z): UpVector; frontdir = GetVectorFromHeading(heading); rightdir = (frontdir.cross(updir)).Normalize(); frontdir = (updir.cross(rightdir)).Normalize(); transMatrix = CMatrix44f(pos, -rightdir, updir, frontdir); }
void CFeature::ForcedSpin(const float3& newDir) { float3 updir = UpVector; if (updir == newDir) { //FIXME perhaps save the old right,up,front directions, so we can // reconstruct the old upvector and generate a better assumption for updir updir -= GetVectorFromHeading(heading); } float3 rightdir = newDir.cross(updir).Normalize(); updir = rightdir.cross(newDir); transMatrix = CMatrix44f(pos, -rightdir, updir, newDir); heading = GetHeadingFromVector(newDir.x, newDir.z); }
CMatrix44f CProjectile::GetTransformMatrix(bool offsetPos) const { float3 xdir; float3 ydir; if (math::fabs(dir.y) < 0.95f) { xdir = dir.cross(UpVector); xdir.SafeANormalize(); } else { xdir.x = 1.0f; } ydir = xdir.cross(dir); return (CMatrix44f(drawPos + (dir * radius * 0.9f * offsetPos), -xdir, ydir, dir)); }
void CFeature::CalculateTransform () { float3 frontDir=GetVectorFromHeading(heading); float3 upDir; if (def->upright) upDir = float3(0.0f,1.0f,0.0f); else upDir = ground->GetNormal(pos.x,pos.z); float3 rightDir=frontDir.cross(upDir); rightDir.Normalize(); frontDir=upDir.cross(rightDir); frontDir.Normalize (); transMatrix = CMatrix44f (pos,-rightDir,upDir,frontDir); }
void CFeature::ForcedSpin(const float3& newDir) { /* heading = GetHeadingFromVector(newDir.x, newDir.z); CalculateTransform(); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->DeleteTree(pos); treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } */ float3 updir = UpVector; if (updir == newDir) { //FIXME perhaps save the old right,up,front directions, so we can // reconstruct the old upvector and generate a better assumption for updir updir -= GetVectorFromHeading(heading); } float3 rightdir = newDir.cross(updir).Normalize(); updir = rightdir.cross(newDir); transMatrix = CMatrix44f(pos, -rightdir, updir, newDir); heading = GetHeadingFromVector(newDir.x, newDir.z); }
void CAssParser::LoadPieceTransformations( SAssPiece* piece, const S3DModel* model, const aiNode* pieceNode, const LuaTable& pieceTable ) { aiVector3D aiScaleVec, aiTransVec; aiQuaternion aiRotateQuat; // process transforms pieceNode->mTransformation.Decompose(aiScaleVec, aiRotateQuat, aiTransVec); // metadata-scaling piece->scales = pieceTable.GetFloat3("scale", aiVectorToFloat3(aiScaleVec)); piece->scales.x = pieceTable.GetFloat("scalex", piece->scales.x); piece->scales.y = pieceTable.GetFloat("scaley", piece->scales.y); piece->scales.z = pieceTable.GetFloat("scalez", piece->scales.z); if (piece->scales.x != piece->scales.y || piece->scales.y != piece->scales.z) { // LOG_SL(LOG_SECTION_MODEL, L_WARNING, "Spring doesn't support non-uniform scaling"); piece->scales.y = piece->scales.x; piece->scales.z = piece->scales.x; } // metadata-translation piece->offset = pieceTable.GetFloat3("offset", aiVectorToFloat3(aiTransVec)); piece->offset.x = pieceTable.GetFloat("offsetx", piece->offset.x); piece->offset.y = pieceTable.GetFloat("offsety", piece->offset.y); piece->offset.z = pieceTable.GetFloat("offsetz", piece->offset.z); // metadata-rotation // NOTE: // these rotations are "pre-scripting" but "post-modelling" // together with the (baked) aiRotateQuad they determine the // model's pose *before* any animations execute // // float3 rotAngles = pieceTable.GetFloat3("rotate", aiQuaternionToRadianAngles(aiRotateQuat) * RADTODEG); float3 pieceRotAngles = pieceTable.GetFloat3("rotate", ZeroVector); pieceRotAngles.x = pieceTable.GetFloat("rotatex", pieceRotAngles.x); pieceRotAngles.y = pieceTable.GetFloat("rotatey", pieceRotAngles.y); pieceRotAngles.z = pieceTable.GetFloat("rotatez", pieceRotAngles.z); pieceRotAngles *= DEGTORAD; LOG_SL(LOG_SECTION_PIECE, L_INFO, "(%d:%s) Assimp offset (%f,%f,%f), rotate (%f,%f,%f,%f), scale (%f,%f,%f)", model->numPieces, piece->name.c_str(), aiTransVec.x, aiTransVec.y, aiTransVec.z, aiRotateQuat.w, aiRotateQuat.x, aiRotateQuat.y, aiRotateQuat.z, aiScaleVec.x, aiScaleVec.y, aiScaleVec.z ); LOG_SL(LOG_SECTION_PIECE, L_INFO, "(%d:%s) Relative offset (%f,%f,%f), rotate (%f,%f,%f), scale (%f,%f,%f)", model->numPieces, piece->name.c_str(), piece->offset.x, piece->offset.y, piece->offset.z, pieceRotAngles.x, pieceRotAngles.y, pieceRotAngles.z, piece->scales.x, piece->scales.y, piece->scales.z ); // NOTE: // at least collada (.dae) files generated by Blender represent // a coordinate-system that differs from the "standard" formats // (3DO, S3O, ...) for which existing tools at least have prior // knowledge of Spring's expectations --> let the user override // the ROOT rotational transform and the rotation-axis mapping // used by animation scripts (but re-modelling/re-exporting is // always preferred!) even though AssImp should convert models // to its own system which matches that of Spring // // .dae : x=Rgt, y=-Fwd, z= Up, as=(-1, -1, 1), am=AXIS_XZY (if Z_UP) // .dae : x=Rgt, y=-Fwd, z= Up, as=(-1, -1, 1), am=AXIS_XZY (if Y_UP) [!?] // .blend: ???? piece->bakedRotMatrix = aiMatrixToMatrix(aiMatrix4x4t<float>(aiRotateQuat.GetMatrix())); if (piece == model->GetRootPiece()) { const float3 xaxis = pieceTable.GetFloat3("xaxis", piece->bakedRotMatrix.GetX()); const float3 yaxis = pieceTable.GetFloat3("yaxis", piece->bakedRotMatrix.GetY()); const float3 zaxis = pieceTable.GetFloat3("zaxis", piece->bakedRotMatrix.GetZ()); if (math::fabs(xaxis.SqLength() - yaxis.SqLength()) < 0.01f && math::fabs(yaxis.SqLength() - zaxis.SqLength()) < 0.01f) { piece->bakedRotMatrix = CMatrix44f(ZeroVector, xaxis, yaxis, zaxis); } } piece->rotAxisSigns = pieceTable.GetFloat3("rotAxisSigns", float3(-OnesVector)); piece->axisMapType = AxisMappingType(pieceTable.GetInt("rotAxisMap", AXIS_MAPPING_XYZ)); // construct 'baked' part of the piece-space matrix // AssImp order is translate * rotate * scale * v; // we leave the translation and scale parts out and // put those in <offset> and <scales> --> transform // is just R instead of T * R * S // // note: for all non-AssImp models this is identity! // piece->ComposeRotation(piece->bakedRotMatrix, pieceRotAngles); piece->SetHasIdentityRotation(piece->bakedRotMatrix.IsIdentity() == 0); assert(piece->bakedRotMatrix.IsOrthoNormal() == 0); }
static CMatrix44f ComposeScaleMatrix(const float4 scales) { // note: T is z-bias, scales.z is z-near return (CMatrix44f(FwdVector * 0.5f, RgtVector / scales.x, UpVector / scales.y, FwdVector / scales.w)); }