Jump to content

  • Log In with Google      Sign In   
  • Create Account


lucky6969b

Member Since 06 Apr 2007
Offline Last Active Private

Topics I've Started

Direct3D Setting the State of Line Widths and Point Sizes

24 August 2014 - 05:02 AM

Hello, In the Direct3D State Machine,

I wonder how can I set the state of a line width and of a point size?

In the following OpenGL Code Snippet,

it tries to reset the line width and point size of the current OpenGL states,

I wonder how I can do the same in Direct3D?

I've looked at ID3DXLine, but I don't think it is where I am looking for.

Thanks

Jack

void DebugDrawDX::end()
{
	/*
	glEnd();
	glLineWidth(1.0f);
	glPointSize(1.0f);
	*/
	
}

Cannot render the navigation mesh

16 August 2014 - 02:14 AM

The following coding cannot render the navigation mesh to the scene.

I suspect there is something wrong with the DrawPrimitive API call.

But I do not have any good references handy currently.

Anyone shed some lights on this?

m_dxDebugFaces is of type CPerfectFace

BTW, I am using both the fixed and dynamic rendering pipelines. Will this work?

Thanks

Jack

#define PERFECTVERTEX_TYPE ( \
	D3DFVF_XYZ | \
	D3DFVF_DIFFUSE \
	)

class CPerfectObject {
public:
	CPerfectObject() { }
	~CPerfectObject() { }

public:
	virtual HRESULT Render() = 0;

public:
	char *m_strName;
};

class CPerfectVertex : public CPerfectObject  {
public:
	CPerfectVertex() { }
	CPerfectVertex(float x, float y, float z,
				D3DCOLOR DiffuseColor);
	~CPerfectVertex() { }

public:
	void Set (float x, float y, float z,
		D3DCOLOR DiffuseColor);

	HRESULT Render() { return S_OK; }

public:
	D3DVECTOR m_Position;
	D3DCOLOR m_DiffuseColor;

};

class CPerfectFace : public CPerfectObject {
public:
	CPerfectFace() { }
	~CPerfectFace() { }

public:
	void SetProps( int Vertex, float x, float y, float z,
		D3DCOLOR DiffuseColor);

	HRESULT Render();

protected:
	std::vector m_Vertices;

};

#include "Renderer.h"
#include "PerfectPrimitive.h"

extern LPDIRECT3DDEVICE9 g_pDevice;

void CPerfectFace::SetProps( int Vertex, float x, float y, float z,
								D3DCOLOR color) {
	
	CPerfectVertex v;
	v.m_Position.x = x;
	v.m_Position.y = y;
	v.m_Position.z = z;

	v.m_DiffuseColor = color;

	m_Vertices.push_back(v);

}

HRESULT CPerfectFace::Render() {
	HRESULT r = 0;

	LPDIRECT3DVERTEXBUFFER9 pVB = 0;

	r = g_pDevice->CreateVertexBuffer( sizeof(CPerfectVertex) * 3, D3DUSAGE_WRITEONLY,
		PERFECTVERTEX_TYPE, D3DPOOL_DEFAULT, &pVB, NULL);

	if  (FAILED(r))
		return E_FAIL;

	BYTE* pData = 0;
	r = pVB->Lock( 0, 0, (void**)&pData, 0 );

	if ( FAILED ( r )) {
		pVB->Release();
		return E_FAIL;
	}

	CopyMemory ( pData, (void*)&m_Vertices, sizeof(CPerfectVertex) * 3);

	pVB->Unlock();

	g_pDevice->SetStreamSource( 0, pVB, 0, sizeof(CPerfectVertex));

	g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_Vertices.size() / 3 );

	pVB->Release();

	return S_OK;

	 
}
bool NavMesher::buildDebugMesh(rcPolyMeshDetail* dmesh)
{
 
    if(dmesh->nmeshes == 0)
    {
        MessageBox(0,"getMeshDataFromPolyMeshDetail(): dmesh->nmeshes == 0\n", 0,0);
        return false;
    }
    D3DVERTEXELEMENT9 vertexElements[] =
    {
        {0, 0,  D3DDECLTYPE_FLOAT3,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},       
        {0, 12, D3DDECLTYPE_FLOAT1,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
        D3DDECL_END()
    };

    if(FAILED(D3DXCreateMesh(dmesh->ntris, dmesh->nverts, D3DXMESH_MANAGED, vertexElements, m_d3d9device, &m_dxDebugMesh)))
    {
        MessageBox(0, "Failed to create dx mesh!", 0, 0);
        return false;
    }
 
    HRESULT hr = E_FAIL;
    DWORD numFaces = m_dxDebugMesh->GetNumFaces();
    DWORD* meshAdj = new DWORD[numFaces * 3];
    hr = m_dxDebugMesh->GenerateAdjacency(0.001f, meshAdj);
    if (FAILED(hr))
    {
        MessageBox(NULL, "Failed to build debug mesh", "Debug Navmesh build failed", NULL);
        return false;
    }

    const D3DXVECTOR3 outlineColor(0.0f, 0.0f, 0.0f);
    const D3DXVECTOR3 innerColor(0.85f, 0.85f, 0.85f);

    struct MeshVertex
    {
        D3DXVECTOR3 p;
        //D3DXVECTOR3 n;
        //D3DXVECTOR2 t;
        D3DCOLOR c;
    };
    WORD* pInd;
    MeshVertex* pVert;
    m_dxDebugMesh->LockVertexBuffer(0, (LPVOID*)&pVert);
    m_dxDebugMesh->LockIndexBuffer(0, (LPVOID*)&pInd);

    for (DWORD i = 0; i < numFaces; ++i)
    {
        D3DCOLOR color = 0x0000FF;
        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+0]].p.x ,pVert[pInd[i*3+0]].p.y,
            pVert[pInd[i*3+0]].p.z, color);

        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+1]].p.x ,pVert[pInd[i*3+1]].p.y,
            pVert[pInd[i*3+1]].p.z, color);

        m_dxDebugFaces.SetProps(i, pVert[pInd[i*3+2]].p.x ,pVert[pInd[i*3+2]].p.y,
            pVert[pInd[i*3+2]].p.z, color);
        
    }

    m_dxDebugMesh->UnlockVertexBuffer();
    m_dxDebugMesh->UnlockIndexBuffer();

    return true;
}

void NavMesher::RenderDebugMesh()
{
    m_dxDebugFaces.Render();
}

IK interpolation instability

11 August 2014 - 06:55 AM

Hi there,

I am implementing a custom IK animation subsystem. If I hardcode the hand end-effector to translate

a couple of units and apply the IK, the character seems to be very stable.

But When I add them as animation set, the animation is extremely unstable.

Here is the module I am using...

Here when UpdateArmIK returns true, that means the animation has completed, the outer class will not continue to

update the IK.

Any one sheds some lights on this?

Thanks a lot

Jack

#include "InverseKinematics.h"
#include "../skinnedMesh.h"
#include "../CMinMax.h"
#include "../Objects/Operator.h"
#include <d3dx9anim.h>
 

 
InverseKinematics::InverseKinematics(Operator* op)
{
    m_pOp = op;
    m_time = 0.0f;     
 
    // Hand IK bones
     m_pShoulderBone = (Bone*)D3DXFrameFind(m_pOp->GetFrameRoot(), "Bip01_L_UpperArm");    
    m_pElbowBone = (Bone*)D3DXFrameFind(m_pOp->GetFrameRoot(), "Bip01_L_Forearm");
    m_pHandBone = (Bone*)D3DXFrameFind(m_pOp->GetFrameRoot(), "Bip01_L_Hand");    

    CreateAnimationSet("Searching");           
}

 
bool InverseKinematics::UpdateArmIK(float dt)
{
    // Exit if bones are missing
    if(m_pShoulderBone == NULL || m_pElbowBone == NULL || m_pHandBone == NULL)
        return true;
 
    //Update Animation time
    m_time += dt;    
    
    /*D3DXVECTOR3 pos = D3DXVECTOR3(m_pHandBone->CombinedTransformationMatrix._41,m_pHandBone->CombinedTransformationMatrix._42,
        m_pHandBone->CombinedTransformationMatrix._43) + D3DXVECTOR3(0.0f, 3.0f, 3.0f);
        D3DXVECTOR3 target(pos.x, pos.y, pos.z);*/
        
    if (m_time <= m_pAnimSet->GetPeriod()) {    
        D3DXVECTOR3 sca, pos;
        D3DXQUATERNION rot;
        m_pAnimSet->GetSRT(m_time, 0, &sca, &rot, &pos);

        D3DXVECTOR3 target(pos.x, pos.y, pos.z);
    
 
        ApplyArmIK(D3DXVECTOR3(0, 0, -1), target);
        return false;
    } else {
        return true;
    }
       
    
}


 
// Two joints IK useful for arm and legs.
void InverseKinematics::ApplyArmIK(D3DXVECTOR3 &hingeAxis, D3DXVECTOR3 &target)
{
    // The two joints algorithm works in two steps first we bend the middle(joint) bone so that the distance from
    // start bone to target position will be correct.
    // We blindly assume that the user given hingeAxis always will be perpendicular to both start and joint vectors.
    // - This will always be hold for elbows and knees for a human character.
    // After that we use the "look-at-IK" algorithm to turn the start bone so that we grab the target
    // Setup some vectors and positions
    D3DXVECTOR3 startPosition = D3DXVECTOR3(m_pShoulderBone->CombinedTransformationMatrix._41, m_pShoulderBone->CombinedTransformationMatrix._42, m_pShoulderBone->CombinedTransformationMatrix._43);
    D3DXVECTOR3 jointPosition = D3DXVECTOR3(m_pElbowBone->CombinedTransformationMatrix._41, m_pElbowBone->CombinedTransformationMatrix._42, m_pElbowBone->CombinedTransformationMatrix._43);
    D3DXVECTOR3 endPosition = D3DXVECTOR3(m_pHandBone->CombinedTransformationMatrix._41, m_pHandBone->CombinedTransformationMatrix._42, m_pHandBone->CombinedTransformationMatrix._43);

    
    

    D3DXVECTOR3 startToTarget = target - startPosition;
    D3DXVECTOR3 startToJoint = jointPosition - startPosition;
    D3DXVECTOR3 jointToEnd = endPosition - jointPosition;
    
    float distStartToTarget = D3DXVec3Length(&startToTarget);
    float distStartToJoint = D3DXVec3Length(&startToJoint);
    float distJointToEnd = D3DXVec3Length(&jointToEnd);

    // Calculate joint bone rotation
    // Calcualte current angle and wanted angle
    float wantedJointAngle = 0.0f;
    
    if(distStartToTarget >= distStartToJoint + distJointToEnd)
    {
        // Target out of reach
        wantedJointAngle = D3DXToRadian(180.0f);
    }
    else
    {
        //Calculate wanted joint angle (Using the Law of Cosines)
        float cosAngle = (distStartToJoint * distStartToJoint + distJointToEnd * distJointToEnd - distStartToTarget * distStartToTarget) / (2.0f * distStartToJoint * distJointToEnd);
        wantedJointAngle = acosf(cosAngle);
    }

    //Normalize vectors
    D3DXVECTOR3 nmlStartToJoint = startToJoint;
    D3DXVECTOR3 nmlJointToEnd = jointToEnd;
    D3DXVec3Normalize(&nmlStartToJoint, &nmlStartToJoint);
    D3DXVec3Normalize(&nmlJointToEnd, &nmlJointToEnd);

    //Calculate the current joint angle
    float currentJointAngle = acosf(D3DXVec3Dot(&(-nmlStartToJoint), &nmlJointToEnd));

    //Calculate rotation matrix
    float diffJointAngle = wantedJointAngle - currentJointAngle;
    D3DXMATRIX rotation;
    D3DXMatrixRotationAxis(&rotation, &hingeAxis, diffJointAngle);

    //Apply elbow transformation
    m_pElbowBone->TransformationMatrix = rotation * m_pElbowBone->TransformationMatrix;

    // Calcuate new end position
    // Calculate this in world position and transform it later to start bones local space
    D3DXMATRIX tempMatrix = m_pElbowBone->CombinedTransformationMatrix;
    tempMatrix._41 = 0.0f;
    tempMatrix._42 = 0.0f;
    tempMatrix._43 = 0.0f;
    tempMatrix._44 = 1.0f;

    D3DXVECTOR3 worldHingeAxis;
    D3DXVECTOR3 newJointToEnd;
    D3DXVec3TransformCoord(&worldHingeAxis, &hingeAxis, &tempMatrix);
    D3DXMatrixRotationAxis(&rotation, &worldHingeAxis, diffJointAngle);
    D3DXVec3TransformCoord(&newJointToEnd, &jointToEnd, &rotation);

    D3DXVECTOR3 newEndPosition;
    D3DXVec3Add(&newEndPosition, &newJointToEnd, &jointPosition);

    // Calculate start bone rotation
    D3DXMATRIX mtxToLocal;
    D3DXMatrixInverse(&mtxToLocal, NULL, &m_pShoulderBone->CombinedTransformationMatrix);

    D3DXVECTOR3 localNewEnd;
    D3DXVECTOR3 localTarget;
    D3DXVec3TransformCoord(&localNewEnd, &newEndPosition, &mtxToLocal);
    D3DXVec3TransformCoord(&localTarget, &target, &mtxToLocal);
    D3DXVec3Normalize(&localNewEnd, &localNewEnd);
    D3DXVec3Normalize(&localTarget, &localTarget);

    D3DXVECTOR3 localAxis;
    D3DXVec3Cross(&localAxis, &localNewEnd, &localTarget);
    if(D3DXVec3Length(&localAxis) == 0.0f)
        return;

    D3DXVec3Normalize(&localAxis, &localAxis);
    float localAngle = acosf(D3DXVec3Dot(&localNewEnd, &localTarget));

    // Apply the rotation that makes the bone turn
    D3DXMatrixRotationAxis(&rotation, &localAxis, localAngle);
    m_pShoulderBone->CombinedTransformationMatrix = rotation * m_pShoulderBone->CombinedTransformationMatrix;
    m_pShoulderBone->TransformationMatrix = rotation * m_pShoulderBone->TransformationMatrix;

    // Update matrices of child bones.
    if(m_pShoulderBone->pFrameFirstChild)
        //m_pSkinnedMesh->UpdateMatrices((Bone*)m_pShoulderBone->pFrameFirstChild,
            //                           &m_pShoulderBone->CombinedTransformationMatrix);
            m_pOp->UpdateFrame((Bone*)m_pShoulderBone->pFrameFirstChild,
                            &m_pShoulderBone->CombinedTransformationMatrix);
}


// Create keyframes for applyarmik

void InverseKinematics::CreateAnimationSet(std::string name) {
    
    D3DXKEY_VECTOR3 keyTranslation[2];
    keyTranslation[0].Time = 0.0f;
    keyTranslation[0].Value = D3DXVECTOR3(m_pHandBone->CombinedTransformationMatrix._41,
        m_pHandBone->CombinedTransformationMatrix._42,
        m_pHandBone->CombinedTransformationMatrix._43);

    keyTranslation[1].Time = 2000.0f;
    keyTranslation[1].Value = keyTranslation[0].Value + D3DXVECTOR3(0.0, 3.0f, 0.0f);


    /*D3DXKEY_QUATERNION keyRotation[2];
    keyRotation[0].Time=0.0f;
    keyRotation[0].Value=D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f);
    keyRotation[1].Time=1.0f;
    keyRotation[1].Value=D3DXQUATERNION(1.0f, 0.0f, 0.0f, 0.0f);*/
    D3DXCreateKeyframedAnimationSet(name.c_str(),500, D3DXPLAY_ONCE, 1, 0, NULL, &m_pAnimSet);
        
    //m_pAnimSet->RegisterAnimationSRTKeys("Animation1", 0, 2, 2, NULL, keyRotation, keyTranslation, 0);
    m_pAnimSet->RegisterAnimationSRTKeys("Animation1", 0, 0, 2, NULL, NULL, keyTranslation, 0);

}

Do I have to copy the frames over if I do IK?

10 August 2014 - 11:58 PM

Let me first describe my situation. I have an IK solver, which updates the upper arm of the agent. But it finishes updating, the character goes back to the original pose (T-pose). I don't like that to happen, I want the character to stay in that pose after the IK finishes, now I am trying to resolve it, I think the problem lies in that the frame root belongs to the master copy of the mesh, I clone the animation controller for each instance but just making a shallow copy of the skinned mesh. If I also clone the frames over, I don't think it will happen any more. But my question is if I have thousands of such characters, will it consume a lot of computer resources? Could anyone please help me find out the solution?

 

Update:

Could anyone explain how to work this out?

If the animation set has a tick of 500 per second?

And the keyframes lie at 0, 625, 1250, 1875, 2500

And the m_pAnimSet->GetPeriod() returns 5.0f, why does it work out like that?

 

Thanks

Jack


Where can I find example code of a Direct3D 9 Renderer?

07 August 2014 - 03:19 AM

Are there any good Direct3D 9 renderer modules that you may introduce to me?

One of our friendly forum members has shown me how to render a Navigation mesh...

But I have never touched the topic on how to implement a renderer (for component based

game engine design), I need to render lines for the seams between tiles.

,therefore I need the feature of supporting adjacency info....

Especially speaking, I need the code for rendering quads with materials (colored faces), without textures....

Thanks

Jack


PARTNERS