void AssetImporter::assembleAsset( ID3D11Device* d3dDevice, const aiScene* scene, unsigned int meshIndex, aiMatrix4x4 transform, GRAPHICS::RESOURCES::Mesh* meshArr, GRAPHICS::RESOURCES::Material* materialArr, GRAPHICS::Scene& outScene ) { GRAPHICS::RESOURCES::Renderable asset; asset.mesh = meshArr[meshIndex]; asset.material = materialArr[scene->mMeshes[meshIndex]->mMaterialIndex]; asset.transformation = DirectX::XMFLOAT4X4((const float*)(&transform.Transpose())); GRAPHICS::D3D11Utility::createBuffer<DirectX::XMFLOAT4X4>( d3dDevice, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, &asset.transformation, 1, asset.transformationBuffer ); outScene.addStaticRenderable(asset); }
// ------------------------------------------------------------------------------------------------ // Apply the node transformation to a mesh void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat) { // Check whether we need to transform the coordinates at all if (!mat.IsIdentity()) { if (mesh->HasPositions()) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { mesh->mVertices[i] = mat * mesh->mVertices[i]; } } if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) { aiMatrix4x4 mWorldIT = mat; mWorldIT.Inverse().Transpose(); // TODO: implement Inverse() for aiMatrix3x3 aiMatrix3x3 m = aiMatrix3x3(mWorldIT); if (mesh->HasNormals()) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { mesh->mNormals[i] = m * mesh->mNormals[i]; } } if (mesh->HasTangentsAndBitangents()) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { mesh->mTangents[i] = m * mesh->mTangents[i]; mesh->mBitangents[i] = m * mesh->mBitangents[i]; } } } } }
aiMatrix4x4 NCAssimpModel::returnRotation(aiMatrix4x4 incmat) { aiVector3D pos; aiQuaternion quat; aiVector3D scale; incmat.DecomposeNoScaling(quat, pos); aiMatrix4x4 toreturn = aiMatrix4x4(quat.GetMatrix()); return toreturn; }
void GetPosRotScale(const aiMatrix4x4& transform, Vector3& pos, Quaternion& rot, Vector3& scale) { aiVector3D aiPos; aiQuaternion aiRot; aiVector3D aiScale; transform.Decompose(aiScale, aiRot, aiPos); pos = ToVector3(aiPos); rot = ToQuaternion(aiRot); scale = ToVector3(aiScale); }
void SceneImporter::computeTransform( const aiMatrix4x4 &m, Transformation &t ) { aiVector3D position, scaling; aiQuaternion rotation; m.Decompose( scaling, rotation, position ); t.setTranslate( position.x, position.y, position.z ); t.setScale( ( scaling.x + scaling.y + scaling.z ) / 3.0f ); t.setRotate( Quaternion4f( rotation.x, rotation.y, rotation.z, rotation.w ) ); }
aiMatrix4x4 NCAssimpModel::returnScale(aiMatrix4x4 incmat) { aiVector3D pos; aiQuaternion quat; aiVector3D scale; incmat.Decompose(scale, quat, pos); aiMatrix4x4 scalee; aiMatrix4x4::Scaling(scale,scalee); return scalee; }
aiMatrix4x4 NCAssimpModel::returnInverseRotation(aiMatrix4x4 incmat) { aiVector3D pos; aiQuaternion quat; aiVector3D scale; incmat.Decompose(scale, quat, pos); aiMatrix4x4 toreturn = (aiMatrix4x4)quat.GetMatrix(); toreturn.Inverse(); return toreturn; }
aiMatrix4x4 NCAssimpModel::returnTranslation(aiMatrix4x4 incmat) { aiVector3D pos; aiQuaternion quat; aiVector3D scale; incmat.Decompose(scale, quat, pos); aiMatrix4x4 trans; aiMatrix4x4::Translation(pos, trans); return trans; }
void QMesh::draw(aiMatrix4x4 transform) const { glPushMatrix(); aiMatrix4x4 mult; aiMatrix4x4::Translation(aiVector3D(0,-100,0), mult); transform = mult * transform; transform.Transpose(); //Transpose for some reason glMultMatrixf(static_cast<GLfloat*>(transform[0])); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); const GLuint *indices = geom->faces.constData(); glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices + start); glPopMatrix(); }
AnimUtils(const char* filename) { m_pScene = mIp.ReadFile(filename, aiProcess_GenSmoothNormals); if(m_pScene) { mGlobalInvTf = m_pScene->mRootNode->mTransformation; mGlobalInvTf.Inverse(); // only looks at the first mesh and its bones if(m_pScene->mMeshes[0]->HasBones()) { LoadBones(m_pScene->mMeshes[0]); } if(m_pScene->HasAnimations()) { // Only Load the first Animation BuildChannelDict(m_pScene->mAnimations[0]); } } }
std::string outputJsonEntityFile(const std::string &name, const aiMatrix4x4 &matrix, const std::string &mesh, const std::string &material, const std::string &occlusionName) { float deg; aiVector3D s, p, a; aiQuaternion r; matrix.Decompose(s, r, p); convertToAxisAngle(r, a, deg); cJSON *root = cJSON_CreateObject(); cJSON *entity = cJSON_CreateObject(); cJSON_AddItemToObject(root, "entity", entity); cJSON_AddStringToObject(entity, "name", name.c_str()); cJSON *transform = cJSON_CreateObject(); cJSON_AddItemToObject(entity, "transform", transform); cJSON *position = cJSON_CreateArray(); cJSON_AddNumberToArray(position, p.x); cJSON_AddNumberToArray(position, p.y); cJSON_AddNumberToArray(position, p.z); cJSON_AddItemToObject(transform, "position", position); cJSON *orientation = cJSON_CreateArray(); cJSON *axis = cJSON_CreateArray(); cJSON_AddNumberToArray(axis, a.x); cJSON_AddNumberToArray(axis, a.y); cJSON_AddNumberToArray(axis, a.z); cJSON_AddNumberToArray(orientation, deg); cJSON_AddItemToArray(orientation, axis); cJSON_AddItemToObject(transform, "orientation", orientation); cJSON *scale = cJSON_CreateArray(); cJSON_AddNumberToArray(scale, s.x); cJSON_AddNumberToArray(scale, s.y); cJSON_AddNumberToArray(scale, s.z); cJSON_AddItemToObject(transform, "scale", scale); cJSON *components = cJSON_CreateObject(); cJSON_AddItemToObject(entity, "components", components); cJSON *renderable = cJSON_CreateObject(); cJSON_AddItemToObject(components, "renderable", renderable); cJSON_AddStringToObject(renderable, "mesh", mesh.c_str()); cJSON_AddStringToObject(renderable, "material", (material + ".material").c_str()); cJSON *physics = cJSON_CreateObject(); cJSON_AddItemToObject(components, "physics", physics); cJSON_AddStringToObject(physics, "type", "static"); if(!occlusionName.empty()) { cJSON *occlusion = cJSON_CreateObject(); cJSON_AddItemToObject(components, "occlusion", occlusion); cJSON_AddStringToObject(occlusion, "source", occlusionName.c_str()); } std::string filename = outdir + "/Entities/" + name + ".entity"; writeJsonToFile(root, filename); return filename; }
void copyAiAnimation(const aiScene *scene, const aiMesh *sourceMesh, const unsigned int &animationIndex, std::map<std::string, unsigned int> &boneNameToIndex, std::map<std::string, const aiNode *> &nodeNameToPointer, std::map<std::string, aiMatrix4x4> &nodeNameToMatrix, Skeleton &skeleton) { const aiAnimation *sourceAnimation = scene->mAnimations[animationIndex]; const std::string animationName = std::string(sourceAnimation->mName.data); skeleton.animations.insert(std::pair<std::string, Animation>(animationName, Animation())); Animation *animation = &skeleton.animations[animationName]; const size_t nrFrames = getAiNrAnimationFrames(sourceAnimation); animation->name = animationName; animation->frames.assign(nrFrames*skeleton.bones.size(), KeyFrame()); if (sourceAnimation->mNumChannels != skeleton.bones.size()) { std::cerr << "Warning: animation '" << animation->name << "' has an invalid number of channels (" << sourceAnimation->mNumChannels << " for " << skeleton.bones.size() << " bones)!" << std::endl; } //Store inverse of global transformation. aiMatrix4x4 inverseGlobalTransformation = scene->mRootNode->mTransformation; inverseGlobalTransformation.Inverse(); //Process all frames. KeyFrame *frames = &animation->frames[0]; for (size_t frame = 0; frame < nrFrames; ++frame) { //For this frame, first reset all transformations to their originals. for (std::map<std::string, aiMatrix4x4>::iterator i = nodeNameToMatrix.begin(); i != nodeNameToMatrix.end(); ++i) { assert(nodeNameToPointer[i->first]); i->second = nodeNameToPointer[i->first]->mTransformation; } //Then, retrieve all transformations that are stored in the animation data for the corresponding nodes. for (size_t i = 0; i < sourceAnimation->mNumChannels; ++i) { const aiNodeAnim *nodeAnim = sourceAnimation->mChannels[i]; //Get data for this frame. aiVector3D scale(1.0f, 1.0f, 1.0f); aiQuaternion rotate(1.0f, 0.0f, 0.0f, 0.0f); aiVector3D translate(0.0f, 0.0f, 0.0f); if (frame < nodeAnim->mNumScalingKeys) scale = nodeAnim->mScalingKeys[frame].mValue; else if (nodeAnim->mNumScalingKeys > 0) scale = nodeAnim->mScalingKeys[nodeAnim->mNumScalingKeys - 1].mValue; if (frame < nodeAnim->mNumRotationKeys) rotate = nodeAnim->mRotationKeys[frame].mValue; else if (nodeAnim->mNumRotationKeys > 0) rotate = nodeAnim->mRotationKeys[nodeAnim->mNumRotationKeys - 1].mValue; if (frame < nodeAnim->mNumPositionKeys) translate = nodeAnim->mPositionKeys[frame].mValue; else if (nodeAnim->mNumPositionKeys > 0) translate = nodeAnim->mPositionKeys[nodeAnim->mNumPositionKeys - 1].mValue; //Create transformation matrix. if (nodeNameToMatrix.find(nodeAnim->mNodeName.data) == nodeNameToMatrix.end()) { std::cerr << "Warning: animation data for node '" << nodeAnim->mNodeName.data << "' is not available!" << std::endl; throw std::exception(); } aiMatrix4x4 scaleMatrix; aiMatrix4x4 rotationMatrix = aiMatrix4x4(rotate.GetMatrix()); aiMatrix4x4 translationMatrix; aiMatrix4x4::Scaling(scale, scaleMatrix); aiMatrix4x4::Translation(translate, translationMatrix); nodeNameToMatrix[nodeAnim->mNodeName.data] = translationMatrix*rotationMatrix*scaleMatrix; } //Recursively update these transformations. updateAiNodeMatrices(scene->mRootNode, aiMatrix4x4(), nodeNameToMatrix); //Assign the updated transformations to the corresponding bones. for (std::map<std::string, aiMatrix4x4>::const_iterator i = nodeNameToMatrix.begin(); i != nodeNameToMatrix.end(); ++i) { std::map<std::string, unsigned int>::const_iterator boneIterator = boneNameToIndex.find(i->first); if (boneIterator != boneNameToIndex.end()) { const unsigned int boneIndex = boneIterator->second; //const aiMatrix4x4 finalTransformation = inverseGlobalTransformation*i->second*sourceMesh->mBones[boneIndex]->mOffsetMatrix; const aiMatrix4x4 finalTransformation = i->second*sourceMesh->mBones[boneIndex]->mOffsetMatrix; aiVector3D scale(1.0f, 1.0f, 1.0f); aiQuaternion rotate(1.0f, 0.0f, 0.0f, 0.0f); aiVector3D translate(0.0f, 0.0f, 0.0f); finalTransformation.Decompose(scale, rotate, translate); frames[boneIndex] = KeyFrame(vec3(scale.x, scale.y, scale.z), frame, quatconj(vec4(rotate.x, rotate.y, rotate.z, rotate.w)), vec4(translate.x, translate.y, translate.z, 0.0f)); } } //Advance to next frame. frames += skeleton.bones.size(); } #ifndef NDEBUG std::cerr << "Added animation '" << animation->name << "' with " << nrFrames << " frames, resulting in " << animation->frames.size() << " keyframes." << std::endl; #endif }