Ejemplo n.º 1
0
void buildBoneTree(akSkeleton* skel, btAlignedObjectArray<akMatrix4>& bind, Blender::Bone* bone, UTuint8 parent)
{
	//if(!(bone->flag & BONE_NO_DEFORM) || parent == AK_JOINT_NO_PARENT)
	{
		utHashedString jname = bone->name;
		
		float* bmat = (float*)bone->arm_mat; 
		akMatrix4 mat(akVector4(bmat[4*0+0], bmat[4*0+1], bmat[4*0+2], bmat[4*0+3]),
					  akVector4(bmat[4*1+0], bmat[4*1+1], bmat[4*1+2], bmat[4*1+3]),
					  akVector4(bmat[4*2+0], bmat[4*2+1], bmat[4*2+2], bmat[4*2+3]),
					  akVector4(bmat[4*3+0], bmat[4*3+1], bmat[4*3+2], bmat[4*3+3]));
		
		bind.push_back(mat);
		parent = skel->addJoint(jname, parent);
		if(bone->flag & BONE_NO_SCALE)
			skel->getJoint(parent)->m_inheritScale = false;
	}
	
	Blender::Bone* chi = static_cast<Blender::Bone*>(bone->childbase.first);
	while (chi)
	{
		// recurse
		buildBoneTree(skel, bind, chi, parent);
		chi = chi->next;
	}
}
void akGeometryDeformer::LBSkinningUniformScale(
    const btAlignedObjectArray<akMatrix4>* mpalette,
    const UTsize vtxCount,
    const float*     weights, const UTsize weightsStride,
    const UTuint8*   indices, const UTsize indicesStride,
    const akVector3* vtxSrc,  const UTsize vtxSrcStride,
    akVector3*       vtxDst,  const UTsize vtxDstStride,
    const akVector3* normSrc, const UTsize normSrcStride,
    akVector3*       normDst, const UTsize normDstStride)
{
    const btAlignedObjectArray<akMatrix4>& matrices = *mpalette;

    for(unsigned int i=0; i<vtxCount; i++)
    {
        akMatrix4 mat(matrices[indices[0]] * weights[0]);
        if (weights[1]) mat += matrices[indices[1]] * weights[1];
        if (weights[2]) mat += matrices[indices[2]] * weights[2];
        if (weights[3]) mat += matrices[indices[3]] * weights[3];

        // position
        *vtxDst = (mat * akVector4(*vtxSrc, 1.f)).getXYZ();
        // normal
        *normDst = (mat * akVector4(*normSrc, 0.0f)).getXYZ();
        *normDst = normalize(*normDst);

        akAdvancePointer(normSrc, normSrcStride);
        akAdvancePointer(normDst, normDstStride);
        akAdvancePointer(weights, weightsStride);
        akAdvancePointer(indices, indicesStride);
        akAdvancePointer(vtxSrc, vtxSrcStride);
        akAdvancePointer(vtxDst, vtxDstStride);
    }
}
void akGeometryDeformer::DLBSkinning(
    const btAlignedObjectArray<akMatrix4>* mpalette,
    const btAlignedObjectArray<akDualQuat>* dqpalette,
    const UTsize vtxCount,
    const float*     weights, const UTsize weightsStride,
    const UTuint8*   indices, const UTsize indicesStride,
    const akVector3* vtxSrc,  const UTsize vtxSrcStride,
    akVector3*       vtxDst,  const UTsize vtxDstStride,
    const akVector3* normSrc, const UTsize normSrcStride,
    akVector3*       normDst, const UTsize normDstStride)
{
    const btAlignedObjectArray<akMatrix4>& matrices = *mpalette;
    const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette;

    for(unsigned int i=0; i<vtxCount; i++)
    {
        // position 1st pass for non rigid part of the transformation using matrices
        akMatrix4 mat(matrices[indices[0]] * weights[0]);
        if (weights[1]) mat += matrices[indices[1]] * weights[1];
        if (weights[2]) mat += matrices[indices[2]] * weights[2];
        if (weights[3]) mat += matrices[indices[3]] * weights[3];

        akVector3 tmpPos = (mat * akVector4(*vtxSrc, 1.f)).getXYZ();

        // position 2nd pass for rigid transformation (rotaion & location) using dual quats
        akDualQuat dq = dquats[indices[0]] * weights[0];
        if (weights[1]) dq += dquats[indices[1]] * weights[1];
        if (weights[2]) dq += dquats[indices[2]] * weights[2];
        if (weights[3]) dq += dquats[indices[3]] * weights[3];

        dq /= length(dq.n);

        akVector3 ndxyz(dq.n.getXYZ());
        akVector3 dxyz(dq.d.getXYZ());
        *vtxDst = tmpPos + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos) + dq.n.getW() * tmpPos ) +
                  2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) );

        // normal 1st pass
        inverseTranspose(mat);
        akVector3 tmpNorm = (mat * akVector4(*normSrc, 0.0f)).getXYZ();

        // normal 2nd pass
        *normDst = tmpNorm + 2.0 * cross( ndxyz, cross(ndxyz, tmpNorm) + dq.n.getW() * tmpNorm );
        *normDst = normalize(*normDst);

        akAdvancePointer(normSrc, normSrcStride);
        akAdvancePointer(normDst, normDstStride);
        akAdvancePointer(weights, weightsStride);
        akAdvancePointer(indices, indicesStride);
        akAdvancePointer(vtxSrc, vtxSrcStride);
        akAdvancePointer(vtxDst, vtxDstStride);
    }
}
Ejemplo n.º 4
0
void akBLoader::convertObjectMesh(Blender::Object *bobj)
{
	if(!bobj->data)
		return;

	akEntity* entity = new akEntity();
	m_demo->addEntity(AKB_IDNAME(bobj), entity);
	
	float* bmat = (float*)bobj->obmat; 
	akMatrix4 mat(akVector4(bmat[4*0+0], bmat[4*0+1], bmat[4*0+2], bmat[4*0+3]),
				akVector4(bmat[4*1+0], bmat[4*1+1], bmat[4*1+2], bmat[4*1+3]),
				akVector4(bmat[4*2+0], bmat[4*2+1], bmat[4*2+2], bmat[4*2+3]),
				akVector4(bmat[4*3+0], bmat[4*3+1], bmat[4*3+2], bmat[4*3+3]));
				
				
	akTransformState trans;
	akMathUtils::extractTransform(mat, trans.loc, trans.rot,trans.scale );
	entity->setTransformState(trans);
	
	Blender::Mesh* bmesh =  (Blender::Mesh*)bobj->data;
	
	if (!m_demo->getMesh(AKB_IDNAME(bmesh)))
	{
		akMesh* mesh = new akMesh();
		akMeshLoader meconv(m_demo, mesh, bobj, bmesh);
		meconv.convert(false, true);
		m_demo->addMesh(AKB_IDNAME(bmesh), mesh);
	}
	
	akMesh* mesh = m_demo->getMesh(AKB_IDNAME(bmesh));
	entity->setMesh(mesh);
	
	if(mesh && bobj->parent != 0 && bobj->parent->type == OB_ARMATURE)
	{
	
		Blender::bArmature* bskel = (Blender::bArmature*)bobj->parent->data;
		if(!m_demo->getSkeleton(AKB_IDNAME(bskel)))
			convertSkeleton(bskel);
		
		akSkeleton* skel = m_demo->getSkeleton(AKB_IDNAME(bskel));
		entity->setSkeleton(skel);
		
		if(bskel->deformflag & BLENDER_ARM_DEF_QUATERNION)
			entity->setUseDualQuatSkinning(true);

		mesh->generateBoneWeightsFromVertexGroups(skel, true);
	}
}
Ejemplo n.º 5
0
void akBLoader::convertCameraObject(Blender::Object *bobj)
{
	if(!bobj || !bobj->data)
		return;

	Blender::Camera* bcam =  (Blender::Camera*)bobj->data;
	akCamera* camera = m_demo->getCamera();
	float* bmat = (float*)bobj->obmat; 
	akMatrix4 mat(akVector4(bmat[4*0+0], bmat[4*0+1], bmat[4*0+2], bmat[4*0+3]),
				akVector4(bmat[4*1+0], bmat[4*1+1], bmat[4*1+2], bmat[4*1+3]),
				akVector4(bmat[4*2+0], bmat[4*2+1], bmat[4*2+2], bmat[4*2+3]),
				akVector4(bmat[4*3+0], bmat[4*3+1], bmat[4*3+2], bmat[4*3+3]));
				
	akTransformState trans;
	akMathUtils::extractTransform(mat, trans.loc, trans.rot,trans.scale );
	camera->m_transform = trans;
	camera->m_clipStart = bcam->clipsta;
	camera->m_clipEnd = bcam->clipend;
	camera->m_fov = 360.0f * atanf(16.0f / bcam->lens) / akPi; //TODO fovx to fovy
}
void akGeometryDeformer::DLBAntipodalitySkinningUniformScale(
    const btAlignedObjectArray<akMatrix4>* mpalette,
    const btAlignedObjectArray<akDualQuat>* dqpalette,
    const UTsize vtxCount,
    const float*     weights, const UTsize weightsStride,
    const UTuint8*   indices, const UTsize indicesStride,
    const akVector3* vtxSrc,  const UTsize vtxSrcStride,
    akVector3*       vtxDst,  const UTsize vtxDstStride,
    const akVector3* normSrc, const UTsize normSrcStride,
    akVector3*       normDst, const UTsize normDstStride)
{
    const btAlignedObjectArray<akMatrix4>& matrices = *mpalette;
    const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette;

    for(unsigned int i=0; i<vtxCount; i++)
    {
        // positions 1st pass for non rigid part of the transformation using matrices
        akMatrix4 mat(matrices[indices[0]] * weights[0]);
        if (weights[1]) mat += matrices[indices[1]] * weights[1];
        if (weights[2]) mat += matrices[indices[2]] * weights[2];
        if (weights[3]) mat += matrices[indices[3]] * weights[3];

        akVector3 tmpPos = (mat * akVector4(*vtxSrc, 1.f)).getXYZ();

        akDualQuat dq0 = dquats[indices[0]];
        akDualQuat dq1 = dquats[indices[1]];
        akDualQuat dq2 = dquats[indices[2]];
        akDualQuat dq3 = dquats[indices[3]];

        if( dot(dq0.n, dq1.n) < 0.0) dq1 *= -1.0;
        if( dot(dq0.n, dq2.n) < 0.0) dq2 *= -1.0;
        if( dot(dq0.n, dq3.n) < 0.0) dq3 *= -1.0;

        akDualQuat dq = dq0 * weights[0];
        if (weights[1]) dq += dq1 * weights[1];
        if (weights[2]) dq += dq2 * weights[2];
        if (weights[3]) dq += dq3 * weights[3];

        dq /= length(dq.n);

        akVector3 ndxyz(dq.n.getXYZ());
        akVector3 dxyz(dq.d.getXYZ());

        //position 2nd pass
        *vtxDst = tmpPos + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos) + dq.n.getW() * tmpPos ) +
                  2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) );

        // normal 1rst pass
        akVector3 tmpNor = (mat * akVector4(*normSrc, 1.f)).getXYZ();


        // normal 2nd pass
        *normDst = tmpNor + 2.0 * cross( ndxyz, cross(ndxyz, tmpNor) + dq.n.getW() * tmpNor );
        *normDst = normalize(*normDst);

        akAdvancePointer(normSrc, normSrcStride);
        akAdvancePointer(normDst, normDstStride);
        akAdvancePointer(weights, weightsStride);
        akAdvancePointer(indices, indicesStride);
        akAdvancePointer(vtxSrc, vtxSrcStride);
        akAdvancePointer(vtxDst, vtxDstStride);
    }
}