Jump to content

Milkshape GMF Export plugin


klepto2
 Share

Recommended Posts

File Name: Milkshape GMF Export plugin

File Submitter: klepto2

File Submitted: 29 Nov 2009

File Updated: 29 Nov 2009

File Category: Tools and Utilities

 

A small GMF Export plugin for static meshes.

 

It auto collapses surfaces with identical materials into one surface and

it autogenerates standard materials if wanted.

 

Installation:

 

Copy both files of the package in your Milkshape root folder and

restart Milkshape.

 

Click here to download this file

  • Upvote 1
  • Intel® Core™ i7-8550U @ 1.80 Ghz 
  • 16GB RAM 
  • INTEL UHD Graphics 620
  • Windows 10 Pro 64-Bit-Version
Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Does this include MS' animation with joints etc?

Just asking because I need that so bad... :)

Using Leadwerks Professional Edition (Beta), mainly using C++.

Windows 10 / Linux Mint, Visual Studio 2017. GPU: NVidia GeForce GTX970, CPU: Intel i7 7700K @ 4.20 GHz

Previously known as Evayr.

Link to comment
Share on other sites

I was working on one that supported animation, but I couldn't get the triangles to export properly.

 

I will release my code if anyone wants it.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

TylerH, getting access to your source would be great.

 

Evayr: Unfortunatly this version doesn't support animations. I have a version where animations are exported correctly,

but the bone orientation is wrong. I haven't worked out how to fix it, also Josh mentioned that this may be a bug within the

GMFSDK. Maybe with the source of TylerH I will be able to solve the problem.

  • Intel® Core™ i7-8550U @ 1.80 Ghz 
  • 16GB RAM 
  • INTEL UHD Graphics 620
  • Windows 10 Pro 64-Bit-Version
Link to comment
Share on other sites

Here is the code:

 

Bones / Animation is the large commented out section. Not sure what state I left this in, but it worked, ish. Major problems, but it didn't crash.

 

#include "stdafx.h"
#include "msPlugInImpl.h"
#include "msLib.h"

#include "gmfsdk.h"



BOOL APIENTRY DllMain( HANDLE hModule, 
	DWORD ul_reason_for_call, 
	LPVOID lpReserved
				 )
{
switch (ul_reason_for_call)
{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
}
return TRUE;
}



cMsPlugIn*
CreatePlugIn ()
{
return new cPlugIn ();
}



cPlugIn::cPlugIn ()
{
strcpy (szTitle, "Leadwerks GMF...");
}



cPlugIn::~cPlugIn ()
{
}



int
cPlugIn::GetType ()
{
return cMsPlugIn::eTypeExport;
}



const char*
cPlugIn::GetTitle ()
{
return szTitle;
}


int
cPlugIn::Execute (msModel *pModel)
{
if (!pModel)
	return -1;

GMFInitialize();

//
// check, if we have something to export
//
if (msModel_GetMeshCount (pModel) == 0)
{
	::MessageBox (NULL, "The model is empty! Nothing exported!", "Leadwerks GMF Export", MB_OK | MB_ICONWARNING);
	return 0;
}

//
// choose filename
//
OPENFILENAME ofn;
memset (&ofn, 0, sizeof (OPENFILENAME));

char szFile[MS_MAX_PATH];
char szFileTitle[MS_MAX_PATH];
char szDefExt[32] = "gmf";
char szFilter[128] = "GMF Files (*.gmf)\0*.gmf\0All Files (*.*)\0*.*\0\0";
szFile[0] = '\0';
szFileTitle[0] = '\0';

ofn.lStructSize = sizeof (OPENFILENAME);
ofn.lpstrDefExt = szDefExt;
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MS_MAX_PATH;
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = MS_MAX_PATH;
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
ofn.lpstrTitle = "Export GMF";

if (!::GetSaveFileName (&ofn))
	return 0;

TGMFMesh mesh;
TGMFSurface surface;

//Create the root mesh
mesh = GMFMeshCreate(NULL);

msVec3 pPosition, pRotation;

msModel_GetPosition(pModel, pPosition);
msModel_GetRotation(pModel, pRotation);

GMFEntitySetPositionRotationScale(mesh, 
	pPosition[0], 
	pPosition[1], 
	pPosition[2], 
	pRotation[0], 
	pRotation[1], 
	pRotation[2], 
	1, 
	1, 
	1);

int i, j, k, l, m, n;

/*///////////
// BONES //
///////////
TGMFBone bones[128];

// Bones
for (i = 0; i < msModel_GetBoneCount (pModel); i++)
{
	msBone *pBone = msModel_GetBoneAt (pModel, i);

	char szName[64];
	char szParentName[64];

	// Bone Name
	msBone_GetName (pBone, szName, MS_MAX_NAME);
	if (strlen(szName) == 0)
		strcpy(szName, " ");

	// Bone Parent Name
	msBone_GetParentName (pBone, szParentName, MS_MAX_NAME);

	// Bone Position and Rotation
	msVec3 Position, Rotation;
	msBone_GetPosition (pBone, Position);
	msBone_GetRotation (pBone, Rotation);

	// Check for parent bone
	int nParentBoneIndex = msModel_FindBoneByName(pModel, szParentName);
	msBone *pParentBone = msModel_GetBoneAt(pModel, nParentBoneIndex);
	//I has an idea hmmmm its -1 i.e. no parent, hence the >= 0 ah, i thought 0 was root..phail
	// Create Leadwerks Bone (Parented to mesh if a root bone, else parented to parent bone)
	if (nParentBoneIndex >= 0) {
		bones[i] = GMFBoneCreate(bones[nParentBoneIndex]);	
	}
	else {
		bones[i] = GMFBoneCreate(mesh);
	}

	// Set bone position and rotation
	GMFEntitySetPositionRotationScale(bones[i],
		Position[0],
		Position[1],
		Position[2],
		Rotation[0],
		Rotation[1],
		Rotation[2]);

	// Set bone name
	GMFNodeSetProperty(bones[i],"name",szName);
	GMFNodeSetProperty(bones[i],"parentname",szParentName);

	// Iterate all of the bone's position keys
	for (j = 0; j < msBone_GetPositionKeyCount (pBone); j++)
	{
		// Get position key
	msPositionKey *pKey = msBone_GetPositionKeyAt (pBone, j); 

		// Add position key to the bone entity
		GMFEntityAddPositionKey(bones[i], pKey->Position[0], pKey->Position[1], pKey->Position[2], pKey->fTime);
	}

	// Iterate all of bone's rotation keys
	for (j = 0; j < msBone_GetRotationKeyCount (pBone); j++)
	{
		// Get rotation key
	msRotationKey *pKey = msBone_GetRotationKeyAt (pBone, j); 

		// Add rotation key to the bone entity
		GMFEntityAddRotationKey(bones[i], pKey->Rotation[0], pKey->Rotation[1], pKey->Rotation[2], pKey->fTime);
	}
}*/

//////////////
// SURFACES //
//////////////

// Loop through all meshes (a MS3D mesh is a Leadwerks Surface)	
for (i = 0; i < msModel_GetMeshCount (pModel); i++)
{
	// Grab the mesh
	msMesh *pMesh = msModel_GetMeshAt (pModel, i);
	char szName[64];
	msMesh_GetName (pMesh, szName, 64);

	//Add a surface
	surface = GMFMeshAddSurface(mesh);

	// Set the surface name to the mesh name
	//GMFNodeSetProperty(surface,"name",szName);

	// Get material index
	int nMatIndex = msMesh_GetMaterialIndex (pMesh);

	///////////////
	// TRIANGLES //
	///////////////

	// Iterate all triangles in the current mesh/surface
	for (j = 0; j < msMesh_GetTriangleCount (pMesh); j++)
	{
		// Get a triangle per iteration
	msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, j);
	word nIndices[3];
		word nNormalIndices[3];

		// Get vertex indices of the current triangle
	msTriangle_GetVertexIndices (pTriangle, nIndices);

		// Get normal indices of the current triangle
		msTriangle_GetNormalIndices(pTriangle, nNormalIndices);

		// Get 3 vertices + normals per triangle
		msVertex *pVertex;

		msVec3 Vertex;
		msVec3 Normal;
	msVec2 uv;

		//////////////
		// VERTICES //
		//////////////
		unsigned short v1,v2,v3;
		v1 = v2 = v3 = 0;

		// Vertex 1 from the 1st index 
		pVertex = msMesh_GetVertexAt(pMesh, nIndices[0]); // Get vertex

		msMesh_GetVertexNormalAt(pMesh, nNormalIndices[0], Normal);

		msVertex_GetVertex (pVertex, Vertex);
		msVertex_GetTexCoords (pVertex, uv);

		// The surface should be full of vertices, normals, UVs, colors, etc. stuff...
		// Because of this call
		v1 = GMFSurfaceFindVertex(surface,
			Vertex[0],		// X
			Vertex[1],		// Y
			Vertex[2],		// Z
			Normal[0],	// Normal X
			Normal[1],	// Normal Y
			Normal[2],	// Normal Z
			uv[0],				// U0 Texture Coordinate
			uv[1]//,				// V0 Texture Coordinate
			//uv[0],						// U1 Texture Coordinate	
			//uv[1],						// V1 Texture Coordinate
			//255,					// Vertex Color Red
			//255,					// Vertex Color Green
			//255,					// Vertex Color Blue
			//255						// Vertex Color Alpha
			);	

		// Vertex 2 from the 2nd index 
		pVertex = msMesh_GetVertexAt(pMesh, nIndices[1]); // Get vertex

		msMesh_GetVertexNormalAt(pMesh, nNormalIndices[1], Normal);

		msVertex_GetVertex (pVertex, Vertex);
		msVertex_GetTexCoords (pVertex, uv);

		// The surface should be full of vertices, normals, UVs, colors, etc. stuff...
		// Because of this call
		v2 = GMFSurfaceFindVertex(surface,
			Vertex[0],		// X
			Vertex[1],		// Y
			Vertex[2],		// Z
			Normal[0],	// Normal X
			Normal[1],	// Normal Y
			Normal[2],	// Normal Z
			uv[0],				// U0 Texture Coordinate
			uv[1]//,				// V0 Texture Coordinate
			//uv[0],						// U1 Texture Coordinate	
			//uv[1],						// V1 Texture Coordinate
			//255,					// Vertex Color Red
			//255,					// Vertex Color Green
			//255,					// Vertex Color Blue
			//255						// Vertex Color Alpha
			);

		// Vertex 3
		pVertex = msMesh_GetVertexAt(pMesh, nIndices[2]); // Get vertex

		msMesh_GetVertexNormalAt(pMesh, nNormalIndices[2], Normal);

		msVertex_GetVertex (pVertex, Vertex);
		msVertex_GetTexCoords (pVertex, uv);

		// The surface should be full of vertices, normals, UVs, colors, etc. stuff...
		// Because of this call
		v3 = GMFSurfaceFindVertex(surface,
			Vertex[0],		// X
			Vertex[1],		// Y
			Vertex[2],		// Z
			Normal[0],	// Normal X
			Normal[1],	// Normal Y
			Normal[2],	// Normal Z
			uv[0],				// U0 Texture Coordinate
			uv[1]//,				// V0 Texture Coordinate
			//uv[0],						// U1 Texture Coordinate	
			//uv[1],						// V1 Texture Coordinate
			//255,					// Vertex Color Red
			//255,					// Vertex Color Green
			//255,					// Vertex Color Blue
			//255						// Vertex Color Alpha
			);	

		//GMFSurfaceAddTriangle(surface, nIndices[0], nIndices[2], nIndices[1]); 	
		GMFSurfaceAddTriangle(surface, v1, v2, v3); 	
	}

	//////////////
	// MATERIAL //
	//////////////
	//brb fixing a desktop comp.
	msMaterial *pMaterial = msModel_GetMaterialAt(pModel, nMatIndex);
	char szDiffuseTexture[64];
	msMaterial_GetDiffuseTexture(pMaterial, szDiffuseTexture, 64);

	// Set surface material to the mesh material
	GMFNodeSetProperty( surface, "material", szDiffuseTexture );

	/*//////////////////////
	// BONE ATTACHMENTS //
	//////////////////////

	// Vertex Bone Indices / Bone Weights
	for (j = 0; j < msMesh_GetVertexCount (pMesh); j++) // Thanks to Christian for being a beast. 
	{
		// Vertex Ex structure
		msVertexEx *pVertexEx;

		// Grab vertex bone indices and bone weights
		pVertexEx = msMesh_GetVertexExAt(pMesh, j);

		// Loop through the 3 possible bones, attach vertices to the Leadwerks Bones on the surface
		for (k = 0; k < 3; k++)
		{
			int nBoneIndex = pVertexEx->nBoneIndices[k];
			byte nBoneWeight = pVertexEx->nBoneWeights[k];

			if (nBoneIndex >= 0 && bones[nBoneIndex] != NULL && nBoneWeight != -1)
				GMFSurfaceAttachVertex(surface, j, bones[nBoneIndex], (float)nBoneWeight); 
		}
	}*/

	//////////////////////////
	// TANGENTS & BINORMALS //
	//////////////////////////

	// Calculate binormals and tangents for the surface
	GMFSurfaceCalculateBinormalsAndTangents(surface);
}

///////////////
// SAVE FILE //
///////////////

GMFMeshSaveFile(mesh, szFile);

// dont' forget to destroy the model
msModel_Destroy (pModel);

GMFTerminate();

return 0;
}

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...