1 Replies - 316 Views - Last Post: 25 September 2013 - 12:22 PM Rate Topic: -----

#1 Fanie  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 19-August 13

Skinned Mesh problem!

Posted 21 September 2013 - 04:36 AM

Hi Guys.
I rely need some help finding a problem. Iím trying to get a bone animation character to work in my demo. I do get a strange collection of stripes and random polygons when I run my app. Iím using c++ 2008 and DirectX 10 HLSL V4.0

I have this structure set up to store my bone data (e.g. Keyframes,Animations).
//Keyframe container
struct Keyframes
{
Keyframes();
~Keyframes();

float TimePos;
D3DXVECTOR3 Translation;
D3DXVECTOR3 Scale;
D3DXQUATERNION Rotation;
};
//Bone container
//Struktuur vir elke been
struct BoneAnimation
{
float GetStartTime();
float GetEndTime();

D3DXMATRIX InterpolateBone(float t);

std::vector<Keyframes> BoneKeyframes;
};
//Anemation container
//Data struktuur om die Animasie clips te hou.
struct AnimationClip
{
std::string ClipNaam;
float GetClipStartTime();
float GetClipEndTime();

std::vector<D3DXMATRIX> Interpolate(float t);

std::vector<BoneAnimation> BoneAnimation;
};


I do use a model structure to group model data.
struct  Model
{
//A lot of the stuff is just my own way of dealing with the model.  It is not related to my question.  
//I only add this to show the structure.
ID3DX10Mesh* Mesh;//Die mesh container
string sNaam;//Gee 'n naam vir die model om te organiseer
std::vector<int> iTexID;//Die array bevat al die texture ID's.
int iNoSubsets;//Die aantal subsets

///////////////////////////////////////////////////////
//This indicates the number of bones in my model
//////////////////////////////////////////////////////
int iNoBones;//Aantal bones in die model

bool bRender;//Verwys of die spesefieke model gerender moet word

///////////////////////////////////////////////////////
//Model world matrix
///////////////////////////////////////////////////////
D3DXMATRIX mxWorld;//Die model se world matrix wat direk na die shader gaan.  Dit is posisie en skaal en als.
                                       //In die geval van Ďn Skinned mesh word die ingewerk in die root bone se transformasie.
bool IsAnemasie;//Hierdie Waar/Onwaar waarde se of die Model Ďn anemasie model is.

////////////////////////////////////////////////
//This indicates the current time step
////////////////////////////////////////////////
float Tyd;//Hierdie waarde word 0 gemaak sodra Ďn nuwe anemasie reeks begin.  Elke keer wanneer die anemasie
              //plaasvind, word die DeltaTyd(dt) bygetel. Dus Tyd += dt;
///////////////////////////////////////////////////////////
//This indicates the current clip name to be executed
///////////////////////////////////////////////////////////
std::string ClipNaam;//Die huidige naam van anemasie reeks.
///////////////////////////////////////////////////////////
//This is my final transformation array that must go to the shader
///////////////////////////////////////////////////////////
std::vector<D3DXMATRIX> FinaleTransformasies;//Hierdie matriks word na die Shader gestuur om vertex blending
///////////////////////////////////////////////////////////
//An array of the structure AnimationClip
///////////////////////////////////////////////////////////                                                                                //te akomedeer.
std::vector <AnimationClip> Animations;
///////////////////////////////////////////////////////////
//The bone Hierarchy
///////////////////////////////////////////////////////////
std::vector<int> BoneHirargie;//Die i de inskrywing gee sy parent indeks.
///////////////////////////////////////////////////////////
//This array stores the offset transform for each bone
///////////////////////////////////////////////////////////
std::vector<D3DXMATRIX> BoneOffset;//Die ide inskrywing gee die Offset Transform vir die ide been.
///////////////////////////////////////////////////////////
//a function to calculate the final transforms.
///////////////////////////////////////////////////////////
void BerekenFinaleTransformasies(std::string ClipName, float Tyd);//Gee die array met finale transformasies
};


I do know that my key frame calculations does work because I did a key frame demo to test the code. My question is this: does my final transformation calculations work? How do I set the Final transformation vector to the shader?
Here is the final transform calculation code:
void Model::BerekenFinaleTransformasies(std::string ClipName,float Tyd)
{
	int NumBones = BoneOffset.size();
	std::vector<D3DXMATRIX> toParentTransforms;
	//Find the right animation clip
	for (int i = 0; i < Animations.size();i++)
	{
		if (ClipName == Animations[i].ClipNaam)
		{
//Interpolate
		  toParentTransforms = Animations[i].Interpolate(Tyd);
		  i = Animations.size();
		}
	}

	std::vector<D3DXMATRIX> toRootTransforms(NumBones);
//The to root transform of bone 0 = the to parent transform of bone 0
	toRootTransforms[0] = toParentTransforms[0];
//Get the toRootTransforms of the children
	for (int i = 1; i < NumBones;i++)
	{
     D3DXMATRIX toRoot,toParent, toRootFinale;
	 int BoneIndex = BoneHirargie[i];
	 toRoot = toRootTransforms[BoneIndex];
	 toParent = toParentTransforms[i];
	 toRootFinale = toRoot * toParent;
	 toRootTransforms[i] = toRootFinale;
	}
//Clear my final transforms array and set up
	FinaleTransformasies.clear();
	FinaleTransformasies.resize(NumBones);
//calculate final transforms by Offset and to root of each bone
	for (int i = 0; i < NumBones;i++)
	{
     D3DXMATRIX Offset,toRoot,Final;
	 Offset = BoneOffset[i];
	 toRoot = toRootTransforms[i];
	 Final = Offset * toRoot;
	 FinaleTransformasies[i] = Final;
	}

};



There might be a problem here but I think my main problem lies in the communication between the c++ code and the shader.
Here is my render code. I'm just adding the part where I set the array to the shader:
	for(UINT p=0; p < techniqueDescription.Passes; ++p)
    {
			C_MAIN::SkinnedShader.gWorld->SetMatrix((float*)C_MAIN::SkinnedModel.mxWorld);
			C_MAIN::SkinnedShader.gView->SetMatrix((float*)mxView);
			C_MAIN::SkinnedShader.gProjection->SetMatrix((float*)mxProjection);
			C_MAIN::SkinnedShader.gTexMatrix->SetMatrix((float*)mxTexScale);
//And here is the problem I think.
			C_MAIN::SkinnedShader.gBoneTransforms->SetMatrixArray((float*)     &C_MAIN::SkinnedModel.FinaleTransformasies,0,SkinnedModel.FinaleTransformasies.size());
			for(int d = 0 ; d < SkinnedModel.iNoSubsets;d++)
			{
			S_MATERIAL TempMaterial = GetTexture(C_MAIN::SkinnedModel.iTexID[d]);
			C_MAIN::SkinnedShader.gBumpMapTEX->SetResource(TempMaterial.TextureBumpmap);
			C_MAIN::SkinnedShader.gSpecularTEX->SetResource(TempMaterial.TextureSpecular);
			C_MAIN::SkinnedShader.gDiffuseTEX->SetResource(TempMaterial.TextureDiffuse);
			C_MAIN::SkinnedShader.Technique->GetPassByIndex(p)->Apply(0);
			C_MAIN::SkinnedModel.Mesh->DrawSubset(0);
			}
	   	}


The coresponding shader looks like this:
cbuffer cbPerFrame
{
float3 CameraPos;//Die posisie van die kamera in die toneel
float3 lightPos;//Waar die lig vandaan kom in die toneel.
};

cbuffer cbPerObject
{
	float4x4 gWorld;//World Matrix
	float4x4 gView;//View Matrix
	float4x4 gProjection;//Projection Matrix
	float4x4 gWorldLightWLightV;//Shadow mapping WVP
	float4x4 gTexMatrix;//Texture scaling matrix
	 
	float4 ReflectMtr = float4(0.3f,0.3f,0.3f,1.0f);//Konstante op sy eie.
	
	bool gReflectEnabled;//Is Reflection aan?
	bool gBumpMap;//Is Bump mapping aan?
    bool gShadowMap;//Is shadow mapping aan?
///////////////////////////////////////////////////////////////
//The final transform array
//////////////////////////////////////////////////////////////
    float4x4 gBoneTransforms[96];//Die array van been transformasies.  Hierdie shader maak net voorsienning vir
                             //96 bene.
};


//====================================================================================================
//Die Texture var's.  Dit ontvang die textures vanaf die main c++ code.
//====================================================================================================
Texture2D gDiffuseMap;
Texture2D gSpecularMap;
TextureCube gCubeMap;
Texture2D gBumpMapTEX;
Texture2D gShadowMapTEX;

//====================================================================================================
//Sampler states om die textures te sample.
//====================================================================================================
SamplerState gShadowSampler
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Clamp;
    AddressV = Clamp;
};

SamplerState gTextureLandSample
{
	Filter = MIN_MAG_MIP_LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;

};

//====================================================================================================
//Die input en output structures.
//====================================================================================================
struct VS_INPUT //Ontvang vanaf input layout vir anemasie modelle.
{
float3 Pos : POSITION;
float3 Tangent : TANGENT;
float3 Normal : NORMAL;
float2 Tex : TEXCOORD0;
float3 Weights : WEIGHTS;
uint4 BoneIndices : BONEINDICES;
};

struct PS_INPUT//Na pixel shader
{
float4 PosH : SV_POSITION;
float3 PosW  : POSITION;
float3 TangentW : TANGENT;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD0;
float4 ProjTex : TEXCOORD1;
};

//////////////////////////////////////////////////////////////////////////////////////////////
//              VERTEX SHADER VIR BONE ANIMATION MODELLE
//////////////////////////////////////////////////////////////////////////////////////////////
PS_INPUT VS (VS_INPUT vIn)
{
PS_INPUT psInput;
	// Init die array
	float weights[4] = {0.0f, 0.0f, 0.0f, 0.0f};
	weights[0] = vIn.Weights.x;
	weights[1] = vIn.Weights.y;
	weights[2] = vIn.Weights.z;
	weights[3] = 1.0f - weights[0] - weights[1] - weights[2];

	float3 posL     = float3(0.0f, 0.0f, 0.0f);
	float3 normalL  = float3(0.0f, 0.0f, 0.0f);
	float3 tangentL = float3(0.0f, 0.0f, 0.0f);
	
	for(int i = 0; i < 4; ++i)
	{//Begin loop
	
	    //Bereken die pos van elke hoekpunt met in ag neming van ele been se invloed daarop.

	    posL     += weights[i]*mul(float4(vIn.Pos, 1.0f), gBoneTransforms[vIn.BoneIndices[i]]).xyz;
		normalL  += weights[i]*mul(vIn.Normal,  (float3x3)gBoneTransforms[vIn.BoneIndices[i]]);
		tangentL += weights[i]*mul(vIn.Tangent.xyz, (float3x3)gBoneTransforms[vIn.BoneIndices[i]]);
		
	}//Eindig loop

// Transformasie na world space
    psInput.PosW    = mul(float4(posL, 1.0f), gWorld);
	psInput.NormalW = mul(float4(normalL, 0.0f), gWorld);
	psInput.TangentW = mul(float4(tangentL,0.0f),gWorld);

//Transformasie na Homogenious clip space. Doen die WVP calculation op die GPU
float4 TempPos1 = mul(float4(posL,1.0f),gWorld);
float4 TempPos2 = mul(TempPos1,gView);
psInput.PosH = mul(TempPos2, gProjection);


//Texture scaleing
psInput.Tex  = mul(float4(vIn.Tex, 0.0f, 1.0f), gTexMatrix);
//Projection Texture vir shadow map
psInput.ProjTex = mul(float4(posL, 1.0f), gWorldLightWLightV);


return psInput;
}



I donít know what is going on and why Iím getting weird results. Iíve tested everything and canít get to the answer. If Ďn remove the vertex blending code from the shader and just render the model it works fine. Just, you know, twisted because the offset transforms arenít applied. But you can see the model perfect. As soon as I add the vertex blending code itís a mess up. If I donít set the final bone transform array to the shader I get a blank screen. If I do, I get weird polygons etc. The reason why I think that I might have a shader communication problem is that I had the same problem when I tried to render the model without vertex blending. I also got strange polygons all over the screen because I had a data type mismatch in my Input layout. But that is sorted out now.

I do hope that someone will be able to help.

Is This A Good Question/Topic? 1
  • +

Replies To: Skinned Mesh problem!

#2 Fanie  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 19-August 13

Re: Skinned Mesh problem!

Posted 25 September 2013 - 12:22 PM

Hi there

Ok Iíve solved the problem to my above question. For some reason, I cannot set a dynamic array to the shader. It must be a constant. Or at least that is my theory. Could someone confirm that?
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1