- Code: Select all
#include <iostream>
#include <irrlicht.h>
#include "SSkinMeshBuffer.h"
#include "CSkinnedMesh.h"
#include "coreutil.h"
static int angles[] = {0, 1, 2, 2, 1, 0, -1, -2, -2, -1, 0};
using namespace irr;
static scene::IAnimatedMesh *get_mesh(void);
int main(int argc, char **argv)
{
scene::IAnimatedMesh* mesh;
scene::IAnimatedMeshSceneNode *node;
IrrlichtDevice *device;
scene::ISceneManager *smgr;
scene::ICameraSceneNode *cam;
scene::IBoneSceneNode *sbone;
if (!(device = createDevice(video::EDT_OPENGL,
core::dimension2d<u32>(800, 600), 32, false)))
{
std::cout << "Unable to create device" << std::endl;
return 1;
}
smgr = device->getSceneManager();
if (!(mesh = get_mesh()))
{
std::cout << "Unable to load mesh" << std::endl;
return 1;
}
if (!(node = smgr->addAnimatedMeshSceneNode(mesh)))
{
std::cout << "Unable to create node" << std::endl;
return 1;
}
node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
node->setDebugDataVisible(scene::EDS_SKELETON);
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
node->setAnimationSpeed(5);
node->setJointMode(scene::EJUOR_CONTROL);
if (!(cam = smgr->addCameraSceneNodeMaya()))
{
std::cout << "Unable to create camera" << std::endl;
return 1;
}
//cam->setPosition(core::vector3df(0, 0, -1000));
cam->setTarget(core::vector3df(0, 0, 0));
while (device->run())
{
int i = (int) node->getFrameNr();
node->animateJoints(); // not needed if you control all joints
sbone = node->getJointNode((u32) 0);
sbone->setRotation(core::vector3df(0, 0, 6.0f*angles[i%11]));
device->getVideoDriver()->beginScene(true, true,
video::SColor(255,128,128,128));
device->getSceneManager()->drawAll();
device->getVideoDriver()->endScene();
}
device->drop();
return 0;
}
static int vertices[] = {
0, 1, 3, 2, // base
0, 4, 6, 2, // lower front
0, 4, 5, 1, // lower left
2, 6, 7, 3, // lower right
1, 5, 7, 3, // lower back
4, 8, 10, 6, // upper front
4, 8, 9, 5, // upper left
6, 10, 11, 7, // upper right
5, 9, 11, 7, // upper back
8, 9, 11, 10 // top
};
static scene::IAnimatedMesh *get_mesh(void)
{
scene::CSkinnedMesh *mesh;
scene::SSkinMeshBuffer *mbuffer;
scene::ISkinnedMesh::SJoint* jnt;
scene::ISkinnedMesh::SWeight wt;
irr::scene::ISkinnedMesh::SPositionKey *k1;
irr::scene::ISkinnedMesh::SRotationKey *k2;
video::S3DVertex vtx;
int i, j, k;
mesh = new scene::CSkinnedMesh();
if (!(mbuffer = mesh->addMeshBuffer()))
return 0;
// need vertices and faces
mbuffer->Vertices_Standard.reallocate(12);
mbuffer->Indices.reallocate(10);
vtx.Normal.X = vtx.Normal.Y = vtx.Normal.Z = 0;
vtx.TCoords.X = vtx.TCoords.Y = 0;
// 12 vertices
for (i = 0; i < 3; ++i)
for (j = 0; j < 2; ++j)
for (k = 0; k < 2; ++k)
{
vtx.Pos.X = j*10.0f;
vtx.Pos.Y = i*10.0f;
vtx.Pos.Z = k*10.0f;
vtx.Color.set(0xff000000 + 0x700000*i + 0xe000*j + 240*k);
mbuffer->Vertices_Standard.push_back(vtx);
}
// 10 faces
for (i = 0; i < 40; i += 4)
{
mbuffer->Indices.push_back(vertices[i + 0]);
mbuffer->Indices.push_back(vertices[i + 1]);
mbuffer->Indices.push_back(vertices[i + 2]);
mbuffer->Indices.push_back(vertices[i + 0]);
mbuffer->Indices.push_back(vertices[i + 2]);
mbuffer->Indices.push_back(vertices[i + 3]);
}
wt.buffer_id = 0;
// 2 bones
jnt = mesh->addJoint(0);
jnt->Name = "Joint0";
//jnt->Animatedposition = core::vector3df(5, 0, 5);
jnt->LocalMatrix.setTranslation(core::vector3df(5, 0, 5));
// weights
for (i = 0; i < 4; ++i)
{
wt.vertex_id = 4 + i;
wt.strength = 0.5f;
jnt->Weights.push_back(wt);
}
// frames
for (i = 0; i < 11; ++i)
{
k1 = mesh->addPositionKey(jnt);
k2 = mesh->addRotationKey(jnt);
k1->frame = k2->frame = (float) i;
k1->position = core::vector3df(5, 0, 5);
k2->rotation = core::quaternion(0, 0, 0.1f*angles[i]);
}
jnt = mesh->addJoint(jnt);
jnt->Name = "Joint1";
//jnt->Animatedposition = core::vector3df(5, 10, 5);
jnt->LocalMatrix.setTranslation(core::vector3df(0, 10, 0));
// weights
for (i = 0; i < 4; ++i)
{
wt.vertex_id = 8 + i;
wt.strength = 1;
jnt->Weights.push_back(wt);
wt.vertex_id = 4 + i;
wt.strength = 0.5f;
jnt->Weights.push_back(wt);
}
// frames
for (i = 0; i < 11; ++i)
{
k1 = mesh->addPositionKey(jnt);
k2 = mesh->addRotationKey(jnt);
k1->frame = k2->frame = (float) i;
k1->position = core::vector3df(0, 10, 0);
k2->rotation = core::quaternion(0, 0, 0.2f*angles[i]);
}
// material
mbuffer->Material.MaterialType = video::EMT_SOLID;
mbuffer->Material.AmbientColor =
video::SColorf(0.2f, 0.2f, 0.2f).toSColor();
mbuffer->Material.DiffuseColor =
video::SColorf(1.0f, 1.0f, 0.0f).toSColor();
// no emissive colour
mbuffer->Material.SpecularColor =
video::SColorf(1.0f, 1.0f, 1.0f).toSColor();
mbuffer->Material.Shininess = 50.0f;
mesh->finalize();
return mesh;
}
I only animate one bone, the other takes the static animation. However, both bones can be animated in this way and the call to 'animateJoints' woud be unnecessary. Once again, te code below 'get_mesh' requires CSkinnedMesh.h. Loading meshes with one of the core loaders gets around this.
