Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR...

80
Karakter-animáció fizikai alapon Szécsi László

Transcript of Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR...

Page 1: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Karakter-animáció fizikai alapon

Szécsi László

Page 2: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

xmlParser.h upgrade

NxQuat readNxQuat(XMLCSTR name);

std::string readString(XMLCSTR name);

double readDouble(XMLCSTR name, double defaultValue=0.0 );

Page 3: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

xmlParser.cpp upgradestd::string XMLNode::readString(XMLCSTR name){

XMLCSTR wideString = getAttribute(name);if(wideString == NULL)

return "Not specified in XML.";unsigned int nChars = 0;nChars = WideCharToMultiByte(CP_ACP, 0, wideString, -1, NULL, 0, false, false);char* mbString = new char[nChars];WideCharToMultiByte(CP_ACP, 0, wideString, -1, mbString, nChars, false, false);std::string& ret = std::string(mbString);delete [] mbString;return ret;

}

Page 4: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

xmlParser.cpp upgradeNxQuat XMLNode::readNxQuat(XMLCSTR name){

NxQuat v;v.id();size_t nameLength = wcslen(name);XMLSTR nameWithChannel = new XMLCHAR[nameLength+3];wcscpy(nameWithChannel, name);wcscat(nameWithChannel, L".x");v.x = readDouble(nameWithChannel, v.x);nameWithChannel[nameLength] = L'\0';wcscat(nameWithChannel, L".y");v.y = readDouble(nameWithChannel, v.y);nameWithChannel[nameLength] = L'\0';wcscat(nameWithChannel, L".z");v.z = readDouble(nameWithChannel, v.z);nameWithChannel[nameLength] = L'\0';wcscat(nameWithChannel, L".w");v.w = readDouble(nameWithChannel, v.w);nameWithChannel[nameLength] = L'\0';delete nameWithChannel;v.normalize();return v;

}

Page 5: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Directoryclass CharacterModel;typedef std::map<const std::wstring,

CharacterModel*>CharacterModelDirectory;

class CharacterBone;typedef std::map<const std::wstring, CharacterBone*>

CharacterBoneDirectory;typedef std::vector<CharacterBone*>

CharacterBoneList;

typedef std::vector<NxActor*> PhysicsActorList;typedef std::vector<NxJoint*> PhysicsJointList;

Page 6: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Letöltendő média fileok

orc^CharacterModel.xml

orc^NXU.xml

orc.x

www.iit.bme.hu/~szecsi/GraphGame/*.*

www.iit.bme.hu/~szecsi/GraphGame/NXU.ZIP

Page 7: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU

kibontani a forráskönyvtárba

minden egy NXU nevű alkönyvtárban van

solution explorer: add new filter "NXU"

job klikk az NXU folderen: add existing item

összes hozzáadás

.cpp-k kiválasztása

jobb klikk, properties, not using precompiled headers

Page 8: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterBone

letöltendő kód:

www.iit.bme.hu/~szecsi/GraphGame/

AnimationFiles.zip

add existing item:

CharacterBone.h

CharacterBone.cpp

Page 9: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel

add existing item:

CharacterModel.h

CharacterModel.cpp

Page 10: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore

CharacterModelDirectory characterModelDirectory;

void loadCharacterModels(XMLNode& xMainNode);

Page 11: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore.cpp

#include "CharacterModel.h"

Page 12: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore.cppvoid EngineCore::loadCharacterModels(XMLNode& xMainNode){

int iCharacterModel = 0;XMLNode characterModelNode;while( !(characterModelNode =

xMainNode.getChildNode(L"CharacterModel",iCharacterModel)).isEmpty() ) {

const wchar_t* name = characterModelNode|L"name"; const wchar_t* file = characterModelNode|L"file"; if(file) {

XMLNode modelNode = XMLNode::openFileHelper(file); if(name && !modelNode.isEmpty())

characterModelDirectory[name] = new CharacterModel(modelNode, this);

} iCharacterModel++;}

}

Page 13: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore::loadLevel

loadPhysicsModels(xMainNode);

loadCharacterModels(xMainNode);

Page 14: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore::releaseManagedResources

{CharacterModelDirectory::iterator i =characterModelDirectory.begin();

while(i !=characterModelDirectory.end()){

delete i->second;i++;

}}

Page 15: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

DualQuaternion

add existing item:

DualQuaternion.h

DualQuaternion.cpp

Page 16: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter

add existing item:

PhysicsCharacter.h

PhysicsCharacter.cpp

Page 17: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore

void loadPhysicsCharacters(XMLNode& groupNode, NodeGroup* group);

Page 18: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore.cpp

#include "PhysicsCharacter.h"

Page 19: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore::loadGroup

loadPhysicsEntities(groupNode, group);

loadPhysicsCharacters(groupNode, group);

Page 20: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore.cpp

void EngineCore::loadPhysicsCharacters(XMLNode& groupNode, NodeGroup* group)

{int iPhysicsCharacter = 0;XMLNode physicsCharacterNode;while( !(physicsCharacterNode = groupNode.getChildNode(L"PhysicsCharacter", iPhysicsCharacter)).isEmpty() ){

// ide jön a következő diaiPhysicsCharacter++;

}}

Page 21: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

előző beleconst wchar_t* shadedMeshName =

physicsCharacterNode|L"shadedMesh";ShadedMeshDirectory::iterator iShadedMesh =

shadedMeshDirectory.find(shadedMeshName);const wchar_t* characterModelName =

physicsCharacterNode|L"characterModel";CharacterModelDirectory::iterator iCharacterModel =

characterModelDirectory.find(characterModelName);if(iShadedMesh != shadedMeshDirectory.end() &&

iCharacterModel != characterModelDirectory.end()) {

D3DXVECTOR3 position =physicsCharacterNode.readVector(L"position");

PhysicsCharacter* physicsCharacter =new PhysicsCharacter(

iShadedMesh->second, iCharacterModel->second,nxScene, position);

group->add(physicsCharacter);const wchar_t* entityName = physicsCharacterNode|L"name";if(entityName)

entityDirectory[entityName] = physicsCharacter;}

Page 22: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

XML

<Mesh name="orc" xFileName="media\\orc.x" skinned="true" autoShadedMesh="false"/>

<ShadedMesh name="orc" mesh="orc" >

<Role name="basic">

<Material technique="skinning">

</Material>

</Role>

</ShadedMesh>

<CharacterModel name="orc" file="media\\orc^CharacterModel.xml" />

Page 23: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

EngineCore::loadMeshes

if(xFileName != NULL){

HRESULT hr = E_FAIL;

if(meshNode|L"skinned")

hr = D3DCreateSkinnedMeshFromX(

device, xFileName, &mesh);

else

hr = D3DXLoadMeshFromX(

xFileName, D3DXMESH_MANAGED, device, NULL, &materialBuffer, NULL, (DWORD*)&nSubmeshes, &mesh);

Page 24: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

SkinnedMesh

Add existing item:

SkinnedMesh.h

SkinnedMesh.cpp

EngineCore.h:

#include "SkinnedMesh.h"

Page 25: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

jöhet a vertex blending

új file: skinning.fx

engineCore.fx:

#include "skinning.fx"

PhysicsCharacter:

csont trafók beállítása

Page 26: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter::renderDualQuaternion boneTransforms[128];for(int iBone=0; iBone<128; iBone++) {

NxMat34& dePose = characterModel->getRiggingBonePoseInverse(boneActors[iBone]);

NxMat34 actorPose = physicsActorList.at(boneActors[iBone])->getGlobalPose();

NxMat34 pose = actorPose * dePose ;NxVec3 p = pose.t;NxQuat q(pose.M);

boneTransforms[iBone].set(D3DXQUATERNION(q.w, q.x, q.y, q.z),D3DXVECTOR3(p.x, p.y, p.z));

}HRESULT hr = context.effect->SetValue("bones",

(void*)boneTransforms, sizeof(boneTransforms));

shadedMesh->render(context);}

Page 27: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

skinning.fx

struct Bone

{

float4 orientation;

float4 dualTranslation;

};

Bone bones[100];

Page 28: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

skinning.fx

struct SkinningInput

{

float4 pos : POSITION;

float3 normal : NORMAL;

float2 tex : TEXCOORD0;

float4 blendWeights : BLENDWEIGHT;

float4 blendIndices : BLENDINDICES;

};

Page 29: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

skinning.fx

struct SkinningOutput

{

float4 pos : POSITION;

float3 normal : TEXCOORD2;

float2 tex : TEXCOORD0;

float4 worldPos : TEXCOORD1;

float4 color : TEXCOORD3;

};

Page 30: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader eleje

SkinningOutput

vsSkinning(SkinningInput input) {

SkinningOutput output =

(SkinningOutput)0;

float4 blendIndices = D3DCOLORtoUBYTE4(

input.blendIndices);

input.blendWeights.w = 1 –

dot(input.blendWeights.xyz,

float3(1, 1, 1));

Page 31: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader: bone trafók

float2x4 qe0 = float2x4(bones[blendIndices.x].orientation, bones[blendIndices.x].dualTranslation);

float2x4 qe1 = float2x4(bones[blendIndices.y].orientation, bones[blendIndices.y].dualTranslation);

float2x4 qe2 = float2x4(bones[blendIndices.z].orientation, bones[blendIndices.z].dualTranslation);

float2x4 qe3 = float2x4(bones[blendIndices.w].orientation, bones[blendIndices.w].dualTranslation);

Page 32: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader: podality

float3 podality = float3(

dot(qe0[0], qe1[0]),

dot(qe0[0], qe2[0]),

dot(qe0[0], qe3[0]));

input.blendWeights.yzw *=

(podality >= 0)?1:-1;

Page 33: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader: trafó keverés

float2x4 qe =

input.blendWeights.x * qe0;

qe += input.blendWeights.y * qe1;

qe += input.blendWeights.z * qe2;

qe += input.blendWeights.w * qe3;

float len = length(qe[0]);

qe /= len;

Page 34: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader: trafó végrehajtás

float3 blendedPos =

input.pos.xyz + 2 * cross(qe[0].yzw,

cross(qe[0].yzw, input.pos.xyz) +

qe[0].x * input.pos.xyz);

float3 trans =

2.0*(qe[0].x*qe[1].yzw - qe[1].x*qe[0].yzw + cross(qe[0].yzw, qe[1].yzw));

blendedPos += trans;

Page 35: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

vertex shader vége

output.pos = mul(float4(blendedPos, 1), modelViewProjMatrix);

output.normal = input.normal.xyz + 2.0*cross(qe[0].yzw, cross(qe[0].yzw, input.normal.xyz) + qe[0].x*input.normal.xyz);

output.tex = input.tex;

output.color = blendIndices * 0.01;

return output;

}

Page 36: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

pixel shader

float4 psSkinning(SkinningOutput input) : COLOR0

{

return abs(input.normal.y);

}

Page 37: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

technique

technique skinning

{

pass ExamplePass

{

VertexShader = compile vs_3_0 vsSkinning();

PixelShader = compile ps_3_0 psSkinning();

}

}

Page 38: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

próba

ragdoll ork, gerincénél felfüggesztve

orc^NXU.xml:

<NxActorDesc id="Actor_0" userProperties="" hasBody="true" name="CenterOfMassRigidBody">

… <NX_BF_KINEMATIC>false</NX_BF_KINEMATIC>

próba: összeeső ragdoll ork

Page 39: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

animáció

orc^CharacterAnimation.xml

Page 40: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel

class CharacterAnimation;

class CharacterModel{

CharacterAnimation*characterAnimation;

public:

unsigned int getBoneCount();

const std::wstring& getBoneNameByBoneIndex(unsigned int iBone);

CharacterAnimation*

getCharacterAnimation();

Page 41: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel.cpp

const std::wstring& CharacterModel::

getBoneNameByBoneIndex(

unsigned int iBone)

{

return characterBoneList.at(iBone)

->getName();

}

Page 42: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel.cpp

unsigned int CharacterModel::getParentIndexByBoneIndex(unsigned int boneIndex)

{if(boneIndex >=

characterBoneList.size())return 0;

return getBoneIndexByBoneName(characterBoneList.at(boneIndex)->getParent()->getName());

}

Page 43: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel.cpp

CharacterAnimation* CharacterModel::getCharacterAnimation()

{

return characterAnimation;

}

unsigned int CharacterModel::getBoneCount()

{

return characterBoneList.size();

}

Page 44: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterAnimation

add existing item:

CharacterAnimation.h

CharacterAnimation.cpp

Page 45: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Átszervezés

Rigging-pose-os dolgokat rakjuk át az animation-be

(már benne van csak a CharacterModel-ből szedjük ki)

Page 46: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

törlés a CharacterModel-ből

bool initialized;

std::vector<NxMat34> riggingBonePoseInverses;

void setInitialized();

bool isInitialized();

NxMat34& getRiggingBonePoseInverse(unsigned int iBone);

void addRiggingBonePoseInverse(NxMat34& dePose);

Page 47: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel::CharacterModel

Animáció betöltése#include "CharacterAnimation.h"CharacterModel::CharacterModel(XMLNode& modelNode){

actorsAndJointsCollection = NULL;loadSerializedScene(modelNode);

const wchar_t* animFile = modelNode|L"characterAnimation";if(animFile){

XMLNode& animNode =XMLNode::openFileHelper(animFile, L"CharacterAnimation");

characterAnimation = new CharacterAnimation(animNode, this);

}else

characterAnimation = NULL;}

Page 48: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterAnimation (már megvan)

unsigned char boneActors[128];

unsigned char jointBones[128];

Page 49: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Directory.h

class Clip;

typedef std::map<

const std::wstring, Clip*, CompareStringsW> ClipDirectory;

Page 50: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Clip, Key

add existing item

Clip.h, Clip.cpp, Key.h, Key.cpp

Animation: Clip gyűjtemény

Clip: Key gyűjtemény

Key: bone orientációk gyűjteménye

Page 51: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Clip

void getKeyTimes(unsigned int iKey, double& keyTime, double& nextKeyTime);

void getNextKey(unsigned int& iKey, double& keyTime, double& nextKeyTime);

NxQuat slerpBoneOrientation(unsigned int iKey,

unsigned int iBone, double a);

Page 52: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Key

NxQuat getBoneOrientation(unsigned int iJoint);

Page 53: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

AnimationState

add existing:

CharacterAnimationState.h

CharacterAnimationPlayer.h

CharacterAnimationPlayer.cpp

Page 54: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterAnimationState

virtual void advance(double dt)=0;

virtual NxQuat getJointOrientation(unsigned int iJoint)=0;

Page 55: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterAnimationPlayer

iterátor-szerűség egy animáció felett

hol tartunk épp most

egy bone orientációját lekérhetjük

Page 56: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterAnimationPlayer

class CharacterAnimationPlayer :

public CharacterAnimationState {

ClipDirectory::iterator currentClip;

unsigned int iKey;

double keyTime;

double nextKeyTime;

double time;

Page 57: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter

na ezt most nagyon át kell írni

(vagy kivenni az új verziót a zip fileból)

Page 58: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

ez nem kell (Animation-ben van):

unsigned char boneActors[128];

Page 59: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

CharacterModel* characterModel;

helyett

CharacterAnimation* characterAnimation;

CharacterAnimationState* characterAnimationState;

Page 60: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

ActorBinder módosítás

friend class ActorBinder;class ActorBinder : public NXU_userNotify{

PhysicsCharacter* owner;CharacterModel* characterModel;

public:void NXU_notifyActor (NxActor

*actor, const char *userProperties);void NXU_notifyJoint (NxJoint

*joint, const char *userProperties); ActorBinder(PhysicsCharacter* owner,

CharacterModel* characterModel);};

Page 61: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter::PhysicsCharacter

törölni:

this->characterModel =

characterModel;

for(int y=0; y<128; y++)

boneActors[y] = 0xff;

berakni:

characterAnimation = characterModel

->getCharacterAnimation();

Page 62: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

characterModel->instantiate(nxScene, &pose, ActorBinder(this, characterModel));

PhysicsCharacter::ActorBinder:: ActorBinder(PhysicsCharacter* owner, CharacterModel* characterModel) {this->owner = owner;this->characterModel = characterModel;

}

Page 63: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Jointok betöltése

PhysicsCharacter-ben tároljuk

PhysicsJointList physicsJointList;

Page 64: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyActor eleje

void PhysicsCharacter::ActorBinder::

NXU_notifyActor (NxActor *actor,

const char *userProperties) {

if(actor->isDynamic() && !actor-> readBodyFlag(NX_BF_KINEMATIC)) {

NxVec3 zero;

zero.zero();

actor->setAngularVelocity(zero);

actor->setLinearVelocity(zero);

}

Page 65: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyActor végeowner->physicsActorList.push_back(actor);if(!owner->characterAnimation->isInitialized()) {

NxMat34 dePose;actor->getGlobalPose().getInverse(dePose);owner->characterAnimation

->addRiggingActorPoseInverse(dePose);const char* actorName = actor->getName();unsigned int nChars = 0;nChars = MultiByteToWideChar(CP_ACP, 0, actorName, -1, NULL, 0);wchar_t* wcString = new wchar_t[nChars];MultiByteToWideChar(CP_ACP, 0, actorName, -1, wcString, nChars);wcString[nChars-10] = L'\0'; // cut "RigidBody" postfixowner->characterAnimation->setBoneActor(

characterModel->getBoneIndexByBoneName(wcString), owner->physicsActorList.size() - 1);

delete wcString;}

}

Page 66: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint eleje

void PhysicsCharacter::ActorBinder

::NXU_notifyJoint (

NxJoint *joint,

const char *userProperties)

{

Page 67: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint folytif(!owner->characterAnimation->isInitialized()){

NxActor* actor0; NxActor* actor1;joint->getActors(&actor0, &actor1);const char* jointName = actor1->getName();unsigned int nChars = 0;nChars = MultiByteToWideChar(CP_ACP, 0, jointName, -1, NULL, 0);wchar_t* wcString = new wchar_t[nChars];

MultiByteToWideChar(CP_ACP, 0, jointName, -1, wcString, nChars);wcString[nChars-10] = L'\0'; // cut "RigidBody" postfix

unsigned int boneIndex = characterModel->getBoneIndexByBoneName(wcString);

owner->characterAnimation->setJointBone(owner->physicsJointList.size(), boneIndex);

delete wcString;}

Page 68: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint folyt

NxD6Joint* j =

(NxD6Joint*)joint->isD6Joint();

if(j)

{

NxD6JointDesc desc;

j->saveToDesc(desc);

Page 69: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint folytif(desc.swing1Motion == NX_D6JOINT_MOTION_LIMITED ||

desc.swing2Motion == NX_D6JOINT_MOTION_LIMITED ||desc.twistMotion == NX_D6JOINT_MOTION_LIMITED ||desc.swing1Motion == NX_D6JOINT_MOTION_FREE ||desc.swing2Motion == NX_D6JOINT_MOTION_FREE ||desc.twistMotion == NX_D6JOINT_MOTION_FREE){

desc.swing1Motion = NX_D6JOINT_MOTION_FREE;desc.swing2Motion = NX_D6JOINT_MOTION_FREE;desc.twistMotion = NX_D6JOINT_MOTION_FREE;

Page 70: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint folyt

desc.swingDrive.driveType = NX_D6JOINT_DRIVE_POSITION;

desc.twistDrive.driveType = NX_D6JOINT_DRIVE_POSITION;

desc.swingDrive.spring = 10000.0;desc.swingDrive.forceLimit = FLT_MAX;desc.swingDrive.damping = 10.0f;desc.twistDrive.spring = 10000.0;desc.twistDrive.forceLimit = FLT_MAX;desc.twistDrive.damping = 10.0f;

Page 71: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

NXU_notifyJoint vége

}

j->loadFromDesc(desc);

}

owner->

physicsJointList.push_back(joint);

}

Page 72: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter::PhysicsCharacter

törölni:for(int y=0; y<127; y++){

int referred = y;while(boneActors[referred] == 0xff)

referred = characterModel->getParentIndexByBoneIndex(referred);

boneActors[y] = boneActors[referred];}

berakni:characterAnimation

->setInitialized(characterModel);characterAnimationState = new CharacterAnimationPlayer(

characterAnimation);

Page 73: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

~PhysicsCharacter

PhysicsCharacter::~PhysicsCharacter()

{

delete characterAnimationState;

}

Page 74: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

render

for(int iBone=0; iBone<128; iBone++){

unsigned int iActor;

NxMat34& dePose = characterAnimation

->getRiggingActorPoseInverse(

iBone, iActor);

NxMat34 actorPose = physicsActorList.at(iActor)

->getGlobalPose();

NxMat34 pose = actorPose * dePose ;

Page 75: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

PhysicsCharacter::animatevoid PhysicsCharacter::animate(double dt){

characterAnimationState->advance(dt);PhysicsJointList::iterator pi =

physicsJointList.begin();unsigned int iJoint=0;while(pi != physicsJointList.end()) {

NxQuat xq;NxD6Joint* j = (*pi)->isD6Joint();if(j) {

xq = characterAnimationState->getJointOrientation(iJoint);

j->setDriveOrientation( xq );}pi++;iJoint++;

}}

Page 76: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Próba

valami furcsa

gond:

a fizikai modell nem pont ugyanott van, mint a vertexek!

Page 77: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Hibakeresés

PhysicsCharacter::render-be

NxMat34 pose =

/* actorPose * */ dePose;

NxVec3 p = pose.t;

NxQuat q(pose.M);

Page 78: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Hibakeresés

skinning.fx-be

VS:

input.blendWeights = float4(1, 0, 0, 0); // merev skinning

output.color = length(blendedPos) / 4.0;

PS:

return input.color;

Page 79: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Próba

eredmény: kis helyre becsomagolva minden

és az origó nem a közepén van!

Page 80: Karakter-animáció fizikai alapon Szécsi László. xmlParser.h upgrade NxQuat readNxQuat(XMLCSTR name); std::string readString(XMLCSTR name); double readDouble(XMLCSTR.

Gyorsjavítás

vsSkinning(SkinningInput input)

{

input.pos.z -= 2;

és csináljunk vissza mindent:

- actorPose * dePose;

- vertex blending

- pixel shader színezés