Sign in to follow this  

3ds IGAME and skinned meshes

This topic is 3118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

This topic is 3118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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