3D model file format

Hi everyone!
I need to start getting some real 3D models into my game soon and get rid of my stupid test graphics soon, and I found myself in a sea of different file formats. I just need something basic.

  • Support for, well, a 3D mesh.
  • Texturing of course.
  • No need for normals as I don’t have lighting (yet) (so it would still be a plus)
  • Support for skeleton animation (which I haven’t learned yet :P) bones would be awesome as I’ll have to animate my units eventually
  • Somewhat easily exportable from 3D software (but I can’t do 3D modelling very well myself…)
  • At least some available free 3D models in this format, so I can test it without having to make my own models.
    I have nothing against writing my own reader/parser for the format, as long as I have the required information to do it. xd Out of pure interest, what format does the Source engine use? I recon there are an infinite number of 3D models for Garry’s Mod and other games based on it so it would be fun to play with them. xD

maybe you can borrow some code from the jme3, it has a blend file loader (files generated by blender). many systems support collada. you could write a converter that uses an existing library to convert the data into your own binary format. Maybe Assimp could be useful for this (afaik it has no direct java integration, but a swig interface). Assimp itself can import many formats and can even export them as collada files.

anim8or .an8 format is a good one. anim8or is free, and has skeletal animation. I’ve already created a fairly simple java parser. i can give you that if you want.

Thanks for the replies!

I’ll look into both the JME3 loader and Assimp! Thanks!

Sounds neat! I’ll do some research on the format and see if it’s easy to parse, but code is always welcome! d^_^b

here’s the parser code

an8file.java

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.Scanner;
import java.util.Vector;


public class an8file extends buildable {

	
	
	// creates a string representation of the file
	// nothing special to look at here
	public static an8file build(File file)
	{
		
		Scanner scan = null;
		try {
			scan = new Scanner(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		StringBuilder st = new StringBuilder();
		
		while(scan.hasNext())
		{
			st.append(scan.nextLine()+"\n");
			
		}
		
		return build(st.toString());
		
		
		
	}
	
	//this is where it really gets ugly
	public static an8file build(String file)
	{
		an8file an = new an8file();
	Scanner scan = new Scanner(file);
	// the buildables stack
		Vector buildables= new Vector();
		buildables.add(an);
		
		while(scan.hasNext())
		{
			
		String s = scan.nextLine();
		s.trim();
		if(s.contains("{"))
		{
			chunk c = new chunk();
			
		int bracket= s.indexOf("{");
			
			c.type=s.substring(0, bracket).trim();
		
			buildables.add(c);
			
			((buildable)buildables.get(buildables.size()-2)).subelements.add(c);
			
		// there is an element in with the chunk declaration
			if(bracket<s.length()-1)
			{
				//one-liners are a special case... ugh
				if(s.contains("}"))
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1, s.length()-2));
					
					buildables.remove(buildables.size()-1);
				}
				
				else
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1));
				}
				
			}
			
		}
		else
			if(s.contains("}"))
			{
				
				buildables.remove(buildables.size()-1);
			}
		
			else
			{
				((buildable)buildables.lastElement()).subelements.add(s);
			}
		
		
			
		}
		
		
		
		// STATE MACHINES SUCK!!!
		return an;
	}
	
	
	public String toString()
	{
		String text = "";
		for(int x=0; x<subelements.size();x++ )
		{
			text+= subelements.get(x).toString()+"\n";
		}
		
		return text;
	}
	
	

	
	
	public static void main(String args[])
{

		
	
an8file a = an8file.build(new File("test.an8"));


System.out.println(((chunk)((chunk)a.subelements.get(0)).subelements.get(0)).subelements.get(0));


try {
	a.save(new File("test2.an8"));
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

}

	public void save(File file) throws FileNotFoundException {


		PrintStream ps = new PrintStream(new FileOutputStream(file));
		
		ps.print(toString());
		
	}
	
	
	

}

buildable.java

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.Scanner;
import java.util.Vector;


public class an8file extends buildable {

	
	
	// creates a string representation of the file
	// nothing special to look at here
	public static an8file build(File file)
	{
		
		Scanner scan = null;
		try {
			scan = new Scanner(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		StringBuilder st = new StringBuilder();
		
		while(scan.hasNext())
		{
			st.append(scan.nextLine()+"\n");
			
		}
		
		return build(st.toString());
		
		
		
	}
	
	//this is where it really gets ugly
	public static an8file build(String file)
	{
		an8file an = new an8file();
	Scanner scan = new Scanner(file);
	// the buildables stack
		Vector buildables= new Vector();
		buildables.add(an);
		
		while(scan.hasNext())
		{
			
		String s = scan.nextLine();
		s.trim();
		if(s.contains("{"))
		{
			chunk c = new chunk();
			
		int bracket= s.indexOf("{");
			
			c.type=s.substring(0, bracket).trim();
		
			buildables.add(c);
			
			((buildable)buildables.get(buildables.size()-2)).subelements.add(c);
			
		// there is an element in with the chunk declaration
			if(bracket<s.length()-1)
			{
				//one-liners are a special case... ugh
				if(s.contains("}"))
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1, s.length()-2));
					
					buildables.remove(buildables.size()-1);
				}
				
				else
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1));
				}
				
			}
			
		}
		else
			if(s.contains("}"))
			{
				
				buildables.remove(buildables.size()-1);
			}
		
			else
			{
				((buildable)buildables.lastElement()).subelements.add(s);
			}
		
		
			
		}
		
		
		
		// STATE MACHINES SUCK!!!
		return an;
	}
	
	
	public String toString()
	{
		String text = "";
		for(int x=0; x<subelements.size();x++ )
		{
			text+= subelements.get(x).toString()+"\n";
		}
		
		return text;
	}
	
	

	
	
	public static void main(String args[])
{

		
	
an8file a = an8file.build(new File("test.an8"));


System.out.println(((chunk)((chunk)a.subelements.get(0)).subelements.get(0)).subelements.get(0));


try {
	a.save(new File("test2.an8"));
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

}

	public void save(File file) throws FileNotFoundException {


		PrintStream ps = new PrintStream(new FileOutputStream(file));
		
		ps.print(toString());
		
	}
	
	
	

}

chunk.java

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.Scanner;
import java.util.Vector;


public class an8file extends buildable {

	
	
	// creates a string representation of the file
	// nothing special to look at here
	public static an8file build(File file)
	{
		
		Scanner scan = null;
		try {
			scan = new Scanner(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		StringBuilder st = new StringBuilder();
		
		while(scan.hasNext())
		{
			st.append(scan.nextLine()+"\n");
			
		}
		
		return build(st.toString());
		
		
		
	}
	
	//this is where it really gets ugly
	public static an8file build(String file)
	{
		an8file an = new an8file();
	Scanner scan = new Scanner(file);
	// the buildables stack
		Vector buildables= new Vector();
		buildables.add(an);
		
		while(scan.hasNext())
		{
			
		String s = scan.nextLine();
		s.trim();
		if(s.contains("{"))
		{
			chunk c = new chunk();
			
		int bracket= s.indexOf("{");
			
			c.type=s.substring(0, bracket).trim();
		
			buildables.add(c);
			
			((buildable)buildables.get(buildables.size()-2)).subelements.add(c);
			
		// there is an element in with the chunk declaration
			if(bracket<s.length()-1)
			{
				//one-liners are a special case... ugh
				if(s.contains("}"))
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1, s.length()-2));
					
					buildables.remove(buildables.size()-1);
				}
				
				else
				{
					((buildable)buildables.lastElement()).subelements.add(s.substring(bracket+1));
				}
				
			}
			
		}
		else
			if(s.contains("}"))
			{
				
				buildables.remove(buildables.size()-1);
			}
		
			else
			{
				((buildable)buildables.lastElement()).subelements.add(s);
			}
		
		
			
		}
		
		
		
		// STATE MACHINES SUCK!!!
		return an;
	}
	
	
	public String toString()
	{
		String text = "";
		for(int x=0; x<subelements.size();x++ )
		{
			text+= subelements.get(x).toString()+"\n";
		}
		
		return text;
	}
	
	

	
	
	public static void main(String args[])
{

		
	
an8file a = an8file.build(new File("test.an8"));


System.out.println(((chunk)((chunk)a.subelements.get(0)).subelements.get(0)).subelements.get(0));


try {
	a.save(new File("test2.an8"));
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

}

	public void save(File file) throws FileNotFoundException {


		PrintStream ps = new PrintStream(new FileOutputStream(file));
		
		ps.print(toString());
		
	}
	
	
	

}

you’ll still have to look up the format, but this will deal with the nested objects. everything is stored within the subelements vectors. check if it’s a string or a chunk.

You could just serialize your objects ::slight_smile:

… I don’t have any objects to serialize. To even make them I would need to be able to load 3D data in the first place.

And if he wanted to change the way his objects looked he’d have to deserialize them, edit, then reserialize.