Sign in to follow this  
giugio

3ds IGAME and skinned meshes

Recommended Posts

Hy. Is possible to use the IGame interface of 3ds 2009 for export skinned meshes? I see that there is few documentation why? Is unstable ? or is a good choise? is fast? I seek for anyone that used it,I cant find the weigth for bones. Thanks.

Share this post


Link to post
Share on other sites
Here's an old slice of code I used for a skinned mesh export plugin for 3DS Max 2008, but it should (hopefully) still work with 2009:


SYM::SYM_MESHSUBSET MaxToSymSubset(IGameNode *Node)
{
//New subset
SYM::SYM_MESHSUBSET Subset;

IGameObject *Object = Node->GetIGameObject();
IGameMesh *Mesh = (IGameMesh*) Object;

//Initialise face data
Mesh->InitializeData();

//Loop through vertices
for (int i = 0; i < Mesh->GetNumberOfVerts(); i++)
{
Point3 Vertex;

//Get current vertex
Mesh->GetVertex(i, Vertex);

//Push back vertex
Subset.Vertices.push_back(SYM::SYM_VECTOR3(Vertex.x, Vertex.y, Vertex.z));
}

//Loop through faces
for (int i = 0; i < Mesh->GetNumberOfFaces(); i++)
{
//Get face
FaceEx *Face = Mesh->GetFace(i);

//Get UV coords
Point2 TexCoord[3];
Mesh->GetTexVertex(Face->texCoord[0], TexCoord[0]);
Mesh->GetTexVertex(Face->texCoord[1], TexCoord[1]);
Mesh->GetTexVertex(Face->texCoord[2], TexCoord[2]);

//New SYM Face
SYM::SYM_FACE SymFace;

//Add indices
SymFace.Indices[0] = Face->vert[0];
SymFace.Indices[1] = Face->vert[1];
SymFace.Indices[2] = Face->vert[2];

//Add UV coords
SymFace.UVCoords[0].u = TexCoord[0].x;
SymFace.UVCoords[0].v = TexCoord[0].y;

SymFace.UVCoords[1].u = TexCoord[1].x;
SymFace.UVCoords[1].v = TexCoord[1].y;

SymFace.UVc.u = TexCoord[2].x;
SymFace.UVc.v = TexCoord[2].y;

//Push back face
Subset.Faces.push_back(SymFace);
}

//Loop through modifiers
for (int i = 0; i < Object->GetNumModifiers(); i++)
{
IGameModifier *Modifier = Object->GetIGameModifier(i);

//Find the skin modifier
if (Modifier->IsSkin())
{
IGameSkin *Skin = (IGameSkin*) Modifier;

//Export skinned verts
for (int v = 0; v < Skin->GetNumOfSkinnedVerts(); v++)
{
int BoneCount = 0;

for (int b = 0; b < Skin->GetNumberOfBones(v); b++)
{
if(b < 4)
{
Subset.Vertices[v].BoneIDs[BoneCount] = Skin->GetBoneID(v, b);
Subset.Vertices[v].Weights[BoneCount] = Skin->GetWeight(v, b);
BoneCount++;
}
else
{
static bool UserWarned = false;

//Bone-to-vertex count exceeded
if(!UserWarned) MessageBox(NULL, "Warning: Max bones per vertex exceeded, skinning data will not be exported correctly", "Symmetry Mesh Exporter", MB_OK);

UserWarned = true;
}
}
}
}
}

//Set name
Subset.Name = std::string(Node->GetName());

//Get material of first face
IGameMaterial *Material;
if(Mesh->GetNumberOfFaces() > 0) Material = Mesh->GetMaterialFromFace(Mesh->GetFace(0));

//Get material name
if(Material)
{
CStr MatFile(Material->GetMaterialName());
MatFile.toLower();
Subset.MaterialName = MatFile.data();
Subset.MaterialName += ".sym.material";
}

return Subset;
}




SYM::SYM_BONE MaxToSymBone(IGameNode *Node)
{
//Retrieve matrix
Matrix3 Matrix = Node->GetWorldTM().ExtractMatrix3();

//Get position
Point3 Position = Matrix.GetTrans();

//Get quaternion
Quat Rotation(Matrix);

//New bone
SYM::SYM_BONE Bone;

//Set position/rotation
Bone.Position = SYM::SYM_VECTOR3(Position.x, Position.y, Position.z);
Bone.Rotation = SYM::SYM_QUATERNION(Rotation.x, Rotation.y, Rotation.z, -Rotation.w);

//Get ID
Bone.ID = Node->GetNodeID();

//Get name
Bone.Name = Node->GetName();

//Get parent bone
if(Node->GetNodeParent())
{
IGameObject *ParentObj = Node->GetNodeParent()->GetIGameObject();
if(ParentObj->GetIGameType() == IGameObject::IGAME_BONE) Bone.ParentID = Node->GetNodeParent()->GetNodeID();
}

//Return bone
return Bone;
}




//Meshes and bones
SYM::SYM_MESH SymMesh;
Tab<IGameNode*> Meshes = SceneInterface->GetIGameNodeByType(IGameObject::IGAME_MESH);
Tab<IGameNode*> Bones = SceneInterface->GetIGameNodeByType(IGameObject::IGAME_BONE);

//Retrieve meshes
for (int i = 0; i < Meshes.Count(); i++)
{
IGameObject *CurrentObject = Meshes[i]->GetIGameObject();
if(CurrentObject->IsRenderable() && CurrentObject->GetIGameType() != IGameObject::IGAME_BONE)
SymMesh.Subsets.push_back(MaxToSymSubset(Meshes[i]));
}

//Retrieve bones
for (int i = 0; i < Bones.Count(); i++)
{
SYM::SYM_BONE Bone = MaxToSymBone(Bones[i]);
if(Bone.ID >= 0) SymMesh.Bones[Bone.ID] = Bone;
}



See if you can pick out anything useful.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this