Browse Source

Initial commit.

Ondřej Hruška 7 years ago
commit
f9100f0f0a
100 changed files with 16849 additions and 0 deletions
  1. 36 0
      .classpath
  2. 5 0
      .gitignore
  3. 17 0
      .project
  4. 11 0
      .settings/org.eclipse.jdt.core.prefs
  5. BIN
      lib/OpenAL32.dll
  6. BIN
      lib/OpenAL64.dll
  7. BIN
      lib/jinput-dx8.dll
  8. BIN
      lib/jinput-dx8_64.dll
  9. BIN
      lib/jinput-raw.dll
  10. BIN
      lib/jinput-raw_64.dll
  11. BIN
      lib/jinput.jar
  12. BIN
      lib/jogg-0.0.7.jar
  13. BIN
      lib/jorbis-0.0.15.jar
  14. BIN
      lib/libjinput-linux.so
  15. BIN
      lib/libjinput-linux64.so
  16. BIN
      lib/libjinput-osx.jnilib
  17. BIN
      lib/liblwjgl.jnilib
  18. BIN
      lib/liblwjgl.so
  19. BIN
      lib/liblwjgl64.so
  20. BIN
      lib/libopenal.so
  21. BIN
      lib/libopenal64.so
  22. BIN
      lib/lwjgl-source-2.8.4.zip
  23. BIN
      lib/lwjgl.dll
  24. BIN
      lib/lwjgl.jar
  25. BIN
      lib/lwjgl64.dll
  26. BIN
      lib/lwjgl_util.jar
  27. BIN
      lib/slick-util-src.zip
  28. BIN
      lib/slick-util.jar
  29. 11 0
      res/models/turtle.mtl
  30. 3558 0
      res/models/turtle.obj
  31. BIN
      res/models/turtle.png
  32. BIN
      res/models/turtle.wings
  33. BIN
      res/models/turtle.xcf
  34. 11 0
      res/models/turtle2.mtl
  35. 3558 0
      res/models/turtle2.obj
  36. BIN
      res/models/turtle2.wings
  37. 86 0
      src/com/mykaruga/models/Models.java
  38. 67 0
      src/com/mykaruga/models/wavefront/loader/Face.java
  39. 37 0
      src/com/mykaruga/models/wavefront/loader/LineParserFactory.java
  40. 50 0
      src/com/mykaruga/models/wavefront/loader/Material.java
  41. 33 0
      src/com/mykaruga/models/wavefront/loader/NormalParser.java
  42. 300 0
      src/com/mykaruga/models/wavefront/loader/RenderModel.java
  43. 35 0
      src/com/mykaruga/models/wavefront/loader/TextureCoordinate.java
  44. 45 0
      src/com/mykaruga/models/wavefront/loader/Vertex.java
  45. 15 0
      src/com/mykaruga/models/wavefront/parser/CommentParser.java
  46. 19 0
      src/com/mykaruga/models/wavefront/parser/DefaultParser.java
  47. 19 0
      src/com/mykaruga/models/wavefront/parser/LineParser.java
  48. 41 0
      src/com/mykaruga/models/wavefront/parser/mtl/KdMapParser.java
  49. 35 0
      src/com/mykaruga/models/wavefront/parser/mtl/KdParser.java
  50. 74 0
      src/com/mykaruga/models/wavefront/parser/mtl/MaterialFileParser.java
  51. 27 0
      src/com/mykaruga/models/wavefront/parser/mtl/MaterialParser.java
  52. 24 0
      src/com/mykaruga/models/wavefront/parser/mtl/MtlLineParserFactory.java
  53. 98 0
      src/com/mykaruga/models/wavefront/parser/obj/FaceParser.java
  54. 21 0
      src/com/mykaruga/models/wavefront/parser/obj/FreeFormParser.java
  55. 27 0
      src/com/mykaruga/models/wavefront/parser/obj/MaterialParser.java
  56. 29 0
      src/com/mykaruga/models/wavefront/parser/obj/ObjLineParserFactory.java
  57. 37 0
      src/com/mykaruga/models/wavefront/parser/obj/TextureCooParser.java
  58. 34 0
      src/com/mykaruga/models/wavefront/parser/obj/VertexParser.java
  59. 152 0
      src/com/porcupine/color/HSV.java
  60. 336 0
      src/com/porcupine/color/RGB.java
  61. 729 0
      src/com/porcupine/coord/Coord.java
  62. 159 0
      src/com/porcupine/coord/CoordI.java
  63. 639 0
      src/com/porcupine/coord/Rect.java
  64. 283 0
      src/com/porcupine/coord/Vec.java
  65. 64 0
      src/com/porcupine/ion/AbstractIonList.java
  66. 75 0
      src/com/porcupine/ion/AbstractIonMap.java
  67. 261 0
      src/com/porcupine/ion/Ion.java
  68. 144 0
      src/com/porcupine/ion/IonList.java
  69. 143 0
      src/com/porcupine/ion/IonMap.java
  70. 57 0
      src/com/porcupine/ion/IonMarks.java
  71. 41 0
      src/com/porcupine/ion/Ionizable.java
  72. 16 0
      src/com/porcupine/ion/IonizableOptional.java
  73. 208 0
      src/com/porcupine/ion/StreamUtils.java
  74. 804 0
      src/com/porcupine/math/Calc.java
  75. 91 0
      src/com/porcupine/math/Polar.java
  76. 95 0
      src/com/porcupine/math/PolarDeg.java
  77. 174 0
      src/com/porcupine/math/Range.java
  78. 52 0
      src/com/porcupine/mutable/AbstractMutable.java
  79. 28 0
      src/com/porcupine/mutable/MBoolean.java
  80. 28 0
      src/com/porcupine/mutable/MDouble.java
  81. 29 0
      src/com/porcupine/mutable/MFloat.java
  82. 28 0
      src/com/porcupine/mutable/MInt.java
  83. 28 0
      src/com/porcupine/mutable/MString.java
  84. 132 0
      src/com/porcupine/struct/Struct2.java
  85. 172 0
      src/com/porcupine/struct/Struct3.java
  86. 213 0
      src/com/porcupine/struct/Struct4.java
  87. 256 0
      src/com/porcupine/struct/Struct5.java
  88. 295 0
      src/com/porcupine/struct/Struct6.java
  89. 336 0
      src/com/porcupine/struct/Struct7.java
  90. 377 0
      src/com/porcupine/struct/Struct8.java
  91. 54 0
      src/com/porcupine/time/FpsMeter.java
  92. 130 0
      src/com/porcupine/time/Timer.java
  93. 36 0
      src/com/porcupine/util/FileSuffixFilter.java
  94. 182 0
      src/com/porcupine/util/FileUtils.java
  95. 1062 0
      src/com/porcupine/util/PropertyManager.java
  96. 104 0
      src/com/porcupine/util/StringUtils.java
  97. 51 0
      src/com/porcupine/util/VarargsParser.java
  98. 368 0
      src/net/spritegen/App.java
  99. 57 0
      src/net/spritegen/Constants.java
  100. 0 0
      src/net/spritegen/SetupLoader.java

+ 36 - 0
.classpath View File

@@ -0,0 +1,36 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<classpath>
3
+	<classpathentry kind="src" path="src"/>
4
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
5
+	<classpathentry exported="true" kind="lib" path="lib/jinput.jar">
6
+		<attributes>
7
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
8
+		</attributes>
9
+	</classpathentry>
10
+	<classpathentry exported="true" kind="lib" path="lib/jogg-0.0.7.jar">
11
+		<attributes>
12
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
13
+		</attributes>
14
+	</classpathentry>
15
+	<classpathentry exported="true" kind="lib" path="lib/jorbis-0.0.15.jar">
16
+		<attributes>
17
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
18
+		</attributes>
19
+	</classpathentry>
20
+	<classpathentry exported="true" kind="lib" path="lib/lwjgl_util.jar">
21
+		<attributes>
22
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
23
+		</attributes>
24
+	</classpathentry>
25
+	<classpathentry exported="true" kind="lib" path="lib/lwjgl.jar">
26
+		<attributes>
27
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
28
+		</attributes>
29
+	</classpathentry>
30
+	<classpathentry exported="true" kind="lib" path="lib/slick-util.jar">
31
+		<attributes>
32
+			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="SpriteGen/lib"/>
33
+		</attributes>
34
+	</classpathentry>
35
+	<classpathentry kind="output" path="bin"/>
36
+</classpath>

+ 5 - 0
.gitignore View File

@@ -0,0 +1,5 @@
1
+/bin/
2
+/target/
3
+*.log
4
+.attach_pid*
5
+*~

+ 17 - 0
.project View File

@@ -0,0 +1,17 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<projectDescription>
3
+	<name>SpriteGen</name>
4
+	<comment></comment>
5
+	<projects>
6
+	</projects>
7
+	<buildSpec>
8
+		<buildCommand>
9
+			<name>org.eclipse.jdt.core.javabuilder</name>
10
+			<arguments>
11
+			</arguments>
12
+		</buildCommand>
13
+	</buildSpec>
14
+	<natures>
15
+		<nature>org.eclipse.jdt.core.javanature</nature>
16
+	</natures>
17
+</projectDescription>

+ 11 - 0
.settings/org.eclipse.jdt.core.prefs View File

@@ -0,0 +1,11 @@
1
+eclipse.preferences.version=1
2
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5
+org.eclipse.jdt.core.compiler.compliance=1.6
6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
8
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11
+org.eclipse.jdt.core.compiler.source=1.6

BIN
lib/OpenAL32.dll View File


BIN
lib/OpenAL64.dll View File


BIN
lib/jinput-dx8.dll View File


BIN
lib/jinput-dx8_64.dll View File


BIN
lib/jinput-raw.dll View File


BIN
lib/jinput-raw_64.dll View File


BIN
lib/jinput.jar View File


BIN
lib/jogg-0.0.7.jar View File


BIN
lib/jorbis-0.0.15.jar View File


BIN
lib/libjinput-linux.so View File


BIN
lib/libjinput-linux64.so View File


BIN
lib/libjinput-osx.jnilib View File


BIN
lib/liblwjgl.jnilib View File


BIN
lib/liblwjgl.so View File


BIN
lib/liblwjgl64.so View File


BIN
lib/libopenal.so View File


BIN
lib/libopenal64.so View File


BIN
lib/lwjgl-source-2.8.4.zip View File


BIN
lib/lwjgl.dll View File


BIN
lib/lwjgl.jar View File


BIN
lib/lwjgl64.dll View File


BIN
lib/lwjgl_util.jar View File


BIN
lib/slick-util-src.zip View File


BIN
lib/slick-util.jar View File


+ 11 - 0
res/models/turtle.mtl View File

@@ -0,0 +1,11 @@
1
+# Exported from Wings 3D 1.4.1
2
+newmtl turtle_auv
3
+Ns 100.0
4
+d 1.0
5
+illum 2
6
+Kd 1.0 1.0 1.0
7
+Ka 1.0 1.0 1.0
8
+Ks 1.0 1.0 1.0
9
+Ke 0.0 0.0 0.0
10
+map_Kd turtle.png
11
+

File diff suppressed because it is too large
+ 3558 - 0
res/models/turtle.obj


BIN
res/models/turtle.png View File


BIN
res/models/turtle.wings View File


BIN
res/models/turtle.xcf View File


+ 11 - 0
res/models/turtle2.mtl View File

@@ -0,0 +1,11 @@
1
+# Exported from Wings 3D 1.4.1
2
+newmtl turtle_auv
3
+Ns 100.0
4
+d 1.0
5
+illum 2
6
+Kd 1.0 1.0 1.0
7
+Ka 1.0 1.0 1.0
8
+Ks 1.0 1.0 1.0
9
+Ke 0.0 0.0 0.0
10
+map_Kd turtle.png
11
+

File diff suppressed because it is too large
+ 3558 - 0
res/models/turtle2.obj


BIN
res/models/turtle2.wings View File


+ 86 - 0
src/com/mykaruga/models/Models.java View File

@@ -0,0 +1,86 @@
1
+package com.mykaruga.models;
2
+
3
+
4
+import static org.lwjgl.opengl.GL11.*;
5
+
6
+import java.io.File;
7
+import java.nio.FloatBuffer;
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import java.util.Random;
11
+
12
+import net.spritegen.App;
13
+import net.spritegen.Constants;
14
+import net.spritegen.textures.TextureManager;
15
+import net.spritegen.util.Utils;
16
+
17
+import com.mykaruga.models.wavefront.loader.RenderModel;
18
+import com.porcupine.math.Calc;
19
+import com.porcupine.math.Calc.Buffers;
20
+
21
+
22
+public class Models {
23
+
24
+	public static RenderModel turtle;
25
+
26
+	
27
+	public static void load() {
28
+		turtle = new RenderModel(App.modelFile.getAbsolutePath());
29
+	}
30
+	
31
+	private static int beginList = -1;
32
+	private static int endList = -1;
33
+
34
+
35
+	public static void renderBegin() {
36
+		if (beginList == -1) {
37
+			beginList = glGenLists(1);
38
+			glNewList(beginList, GL_COMPILE);
39
+			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
40
+
41
+			glEnable(GL_TEXTURE_2D);
42
+			glEnable(GL_COLOR_MATERIAL);
43
+			glEnable(GL_CULL_FACE);
44
+
45
+			float spec = (float) App.cfg.mat_specular;
46
+			float amb = (float) App.cfg.mat_ambient;
47
+			float diff = (float) App.cfg.mat_diffuse;
48
+
49
+			FloatBuffer buff = Calc.Buffers.alloc(4);
50
+
51
+			Calc.Buffers.fill(buff, amb, amb, amb, 1.0f);
52
+			glMaterial(GL_FRONT, GL_AMBIENT, Buffers.mkFillBuff(amb, amb, amb, 1f));
53
+
54
+			buff.clear();
55
+			Calc.Buffers.fill(buff, spec, spec, spec, 1.0f);
56
+			glLight(GL_LIGHT0, GL_SPECULAR, buff);
57
+			glMaterial(GL_FRONT, GL_SPECULAR, Buffers.mkFillBuff(spec, spec, spec, 1f));
58
+
59
+			buff.clear();
60
+			Calc.Buffers.fill(buff, diff, diff, diff, 1.0f);
61
+			glLight(GL_LIGHT0, GL_DIFFUSE, buff);
62
+			glMaterial(GL_FRONT, GL_DIFFUSE, Buffers.mkFillBuff(diff, diff, diff, 1f));
63
+			glMaterialf(GL_FRONT, GL_SHININESS, 8);
64
+
65
+			glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
66
+
67
+			glColor4d(1, 1, 1, 1);
68
+			glEndList();
69
+		}
70
+		glCallList(beginList);
71
+	}
72
+
73
+	public static void renderEnd() {
74
+		if (endList == -1) {
75
+			endList = glGenLists(1);
76
+			glNewList(endList, GL_COMPILE);
77
+			glDisable(GL_COLOR_MATERIAL);
78
+			glDisable(GL_CULL_FACE);
79
+			TextureManager.unbind();
80
+			glDisable(GL_TEXTURE_2D);
81
+			glEndList();
82
+		}
83
+		glCallList(endList);
84
+	}
85
+
86
+}

+ 67 - 0
src/com/mykaruga/models/wavefront/loader/Face.java View File

@@ -0,0 +1,67 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+
5
+public class Face {
6
+
7
+	public static final int GL_TRIANGLES = 3;
8
+	public static final int GL_QUADS = 4;
9
+
10
+	private Vertex[] vertices;
11
+	private Vertex[] normals;
12
+	private TextureCoordinate[] textures;
13
+	private Material material;
14
+
15
+	private int type;
16
+
17
+	public Face copy() {
18
+		Face f = new Face();
19
+		f.setVertices(vertices);
20
+		f.setNormals(normals);
21
+		f.setTextures(textures);
22
+		f.setMaterial(material);
23
+		return f;
24
+	}
25
+
26
+	public Vertex[] getVertices() {
27
+		return vertices;
28
+	}
29
+
30
+	public void setVertices(Vertex[] vertices) {
31
+		this.vertices = vertices;
32
+	}
33
+
34
+	public int getType() {
35
+		return type;
36
+	}
37
+
38
+	public void setType(int type) {
39
+		this.type = type;
40
+	}
41
+
42
+	public Vertex[] getNormals() {
43
+		return normals;
44
+	}
45
+
46
+	public void setNormals(Vertex[] normals) {
47
+		this.normals = normals;
48
+	}
49
+
50
+	public TextureCoordinate[] getTextures() {
51
+		return textures;
52
+	}
53
+
54
+	public void setTextures(TextureCoordinate[] textures) {
55
+		this.textures = textures;
56
+	}
57
+
58
+	public Material getMaterial() {
59
+		return material;
60
+	}
61
+
62
+	public void setMaterial(Material material) {
63
+		this.material = material;
64
+	}
65
+
66
+
67
+}

+ 37 - 0
src/com/mykaruga/models/wavefront/loader/LineParserFactory.java View File

@@ -0,0 +1,37 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+import java.util.Hashtable;
5
+
6
+import com.mykaruga.models.wavefront.parser.DefaultParser;
7
+import com.mykaruga.models.wavefront.parser.LineParser;
8
+
9
+
10
+
11
+
12
+public abstract class LineParserFactory {
13
+
14
+	protected Hashtable<String, LineParser> parsers = new Hashtable<String, LineParser>();
15
+	protected RenderModel object = null;
16
+
17
+
18
+	public LineParser getLineParser(String line) {
19
+		if (line == null) return null;
20
+
21
+		line = line.replaceAll("  ", " ");
22
+		line = line.replaceAll("	", "");
23
+		String[] lineWords = line.split(" ");
24
+
25
+		if (lineWords.length < 1) return new DefaultParser();
26
+
27
+		String lineType = lineWords[0];
28
+
29
+		LineParser parser = parsers.get(lineType);
30
+		if (parser == null) {
31
+			parser = new DefaultParser();
32
+		}
33
+
34
+		parser.setWords(lineWords);
35
+		return parser;
36
+	}
37
+}

+ 50 - 0
src/com/mykaruga/models/wavefront/loader/Material.java View File

@@ -0,0 +1,50 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+import org.newdawn.slick.opengl.Texture;
5
+
6
+
7
+public class Material {
8
+
9
+	private Texture texture;
10
+	private Vertex Kd;
11
+	private String name;
12
+
13
+	public Material(String name) {
14
+		this.name = name;
15
+	}
16
+
17
+	public Material(Material other) {
18
+		//this.texture = other.texture;
19
+		this.Kd = other.Kd;
20
+		this.name = other.name;
21
+	}
22
+
23
+	public Texture getTexture() {
24
+		return texture;
25
+	}
26
+
27
+	public Material setTexture(Texture texture) {
28
+		this.texture = texture;
29
+		return this;
30
+	}
31
+
32
+	public Vertex getKd() {
33
+		return Kd;
34
+	}
35
+
36
+	public void setKa(Vertex kd) {
37
+		Kd = kd;
38
+	}
39
+
40
+	@Override
41
+	public String toString() {
42
+		return "MAT." + name;
43
+	}
44
+
45
+	public String getName() {
46
+		return name;
47
+	}
48
+
49
+
50
+}

+ 33 - 0
src/com/mykaruga/models/wavefront/loader/NormalParser.java View File

@@ -0,0 +1,33 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+import com.mykaruga.models.wavefront.parser.LineParser;
5
+
6
+
7
+public class NormalParser extends LineParser {
8
+
9
+	Vertex vertex = null;
10
+
11
+	public NormalParser() {}
12
+
13
+	@Override
14
+	public void parse() {
15
+		vertex = new Vertex();
16
+
17
+		try {
18
+			vertex.setX(Float.parseFloat(words[1]));
19
+			vertex.setY(Float.parseFloat(words[2]));
20
+			vertex.setZ(Float.parseFloat(words[3]));
21
+		} catch (Exception e) {
22
+			throw new RuntimeException("NormalParser Error");
23
+		}
24
+
25
+	}
26
+
27
+	@Override
28
+	public void incoporateResults(RenderModel wavefrontObject) {
29
+		wavefrontObject.getNormals().add(vertex);
30
+
31
+	}
32
+
33
+}

+ 300 - 0
src/com/mykaruga/models/wavefront/loader/RenderModel.java View File

@@ -0,0 +1,300 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+import java.io.BufferedReader;
5
+import java.io.File;
6
+import java.io.FileInputStream;
7
+import java.io.InputStream;
8
+import java.io.InputStreamReader;
9
+import java.util.ArrayList;
10
+import java.util.Hashtable;
11
+import java.util.Map.Entry;
12
+
13
+import net.spritegen.textures.TextureManager;
14
+import net.spritegen.util.Log;
15
+
16
+import org.lwjgl.opengl.GL11;
17
+import org.newdawn.slick.opengl.Texture;
18
+import org.newdawn.slick.util.ResourceLoader;
19
+
20
+import com.mykaruga.models.wavefront.parser.LineParser;
21
+import com.mykaruga.models.wavefront.parser.obj.ObjLineParserFactory;
22
+
23
+
24
+
25
+/**
26
+ * OBJ 3D object loaded and pre-rendered.
27
+ * 
28
+ * @author Fabien Sanglard
29
+ */
30
+public class RenderModel {
31
+
32
+	private static final boolean DEBUG = true;
33
+
34
+	public String replTexture = null;
35
+
36
+	private ArrayList<Vertex> vertices = new ArrayList<Vertex>();
37
+	private ArrayList<Vertex> normals = new ArrayList<Vertex>();
38
+	private ArrayList<TextureCoordinate> textures = new ArrayList<TextureCoordinate>();
39
+	private ArrayList<Face> faces = new ArrayList<Face>();
40
+
41
+	private ObjLineParserFactory parserFactory;
42
+	private Hashtable<String, Material> materials = new Hashtable<String, Material>();
43
+
44
+	// This variable is used for both parsing and rendition
45
+	private Material currentMaterial;
46
+
47
+	private String contextfolder = "";
48
+
49
+	public double radius = 0;
50
+
51
+	/**
52
+	 * Load object with alternate texture.
53
+	 * 
54
+	 * @param fileName
55
+	 * @param textureName
56
+	 */
57
+	public RenderModel(String fileName, String textureName) {
58
+		this.replTexture = textureName;
59
+
60
+		int lastSlashIndex = fileName.lastIndexOf('/');
61
+		if (lastSlashIndex != -1) this.contextfolder = fileName.substring(0, lastSlashIndex + 1);
62
+
63
+		lastSlashIndex = fileName.lastIndexOf('\\');
64
+		if (lastSlashIndex != -1) this.contextfolder = fileName.substring(0, lastSlashIndex + 1);
65
+
66
+		parse(fileName);
67
+
68
+		calculateRadius();
69
+
70
+	}
71
+
72
+//	/**
73
+//	 * Load object with alternate texture.
74
+//	 * 
75
+//	 * @param fileName
76
+//	 * @param textureName
77
+//	 */
78
+//	public RenderModel(RenderModel other, String textureName) {
79
+//		this.vertices = other.vertices;
80
+//		this.normals = other.normals;
81
+//		this.textures = other.textures;
82
+//		this.contextfolder = other.contextfolder;
83
+//		this.radius = other.radius;
84
+//
85
+//		String pathToTextureBinary = getContextfolder() + textureName;
86
+//		Texture texture = TextureManager.load(pathToTextureBinary);
87
+//		for (Entry<String, Material> e : other.materials.entrySet()) {
88
+//			materials.put(e.getKey(), new Material(e.getValue()).setTexture(texture));
89
+//		}
90
+//		for (Face f : other.faces) {
91
+//			Face f2;
92
+//			faces.add(f2 = f.copy());
93
+//			f2.setMaterial(materials.get(f2.getMaterial().getName()));
94
+//		}
95
+//
96
+//	}
97
+
98
+	public RenderModel(String fileName) {
99
+		int lastSlashIndex = fileName.lastIndexOf('/');
100
+		if (lastSlashIndex != -1) this.contextfolder = fileName.substring(0, lastSlashIndex + 1);
101
+
102
+		lastSlashIndex = fileName.lastIndexOf('\\');
103
+		if (lastSlashIndex != -1) this.contextfolder = fileName.substring(0, lastSlashIndex + 1);
104
+
105
+		parse(fileName);
106
+
107
+		calculateRadius();
108
+	}
109
+
110
+
111
+
112
+	private void calculateRadius() {
113
+		double currentNorm = 0;
114
+		for (Vertex vertex : vertices) {
115
+			currentNorm = vertex.norm();
116
+			if (currentNorm > radius) radius = currentNorm;
117
+		}
118
+
119
+	}
120
+
121
+
122
+	public String getContextfolder() {
123
+		return contextfolder;
124
+	}
125
+
126
+
127
+	public void parse(String fileName) {
128
+		parserFactory = new ObjLineParserFactory(this);
129
+
130
+
131
+		InputStream fileInput = ResourceLoader.getResourceAsStream(fileName);
132
+		if (fileInput == null) {
133
+			// Could not find the file in the jar.
134
+			try {
135
+				File file = new File(fileName);
136
+				if (file.exists()) fileInput = new FileInputStream(file);
137
+			} catch (Exception e2) {
138
+				e2.printStackTrace();
139
+			}
140
+		}
141
+
142
+
143
+		BufferedReader in = null;
144
+
145
+		try {
146
+			in = new BufferedReader(new InputStreamReader(fileInput));
147
+
148
+			String currentLine = null;
149
+			while ((currentLine = in.readLine()) != null)
150
+				parseLine(currentLine);
151
+
152
+			in.close();
153
+
154
+		} catch (Exception e) {
155
+			Log.e("Error reading file " + fileName, e);
156
+			throw new RuntimeException(e);
157
+		}
158
+
159
+
160
+//
161
+//		Log.finest("Loaded OBJ from file " + fileName);
162
+//		Log.finest(getVertices().size() + " vertices.");
163
+//		Log.finest(getNormals().size() + " normals.");
164
+//		Log.finest(getTextures().size() + " textures coordinates.");
165
+//		Log.finest(getFaces().size() + " faces.");
166
+	}
167
+
168
+	private int lineCounter = 0;
169
+
170
+	private void parseLine(String currentLine) {
171
+		if ("".equals(currentLine)) return;
172
+
173
+		LineParser parser = parserFactory.getLineParser(currentLine);
174
+		try {
175
+			parser.parse();
176
+			parser.incoporateResults(this);
177
+		} catch (Throwable t) {
178
+			Log.e("ERROR at line " + lineCounter + " : " + currentLine, t);
179
+			System.exit(1);
180
+		}
181
+		lineCounter++;
182
+	}
183
+
184
+	public int displayListId = 0;
185
+
186
+	public void render() {
187
+
188
+
189
+		if (displayListId != 0) {
190
+			GL11.glCallList(displayListId);
191
+			return;
192
+		}
193
+
194
+		displayListId = GL11.glGenLists(1);
195
+
196
+		GL11.glNewList(displayListId, GL11.GL_COMPILE);
197
+
198
+		Face face = null;
199
+		Material material = new Material("__non_existant");
200
+
201
+		for (int i = 0; i < getFaces().size(); i++) {
202
+			face = getFaces().get(i);
203
+
204
+			if (!material.equals(face.getMaterial())) {
205
+				// Set texture and setColor
206
+				material = face.getMaterial();
207
+				if (material == null) {
208
+					Log.w("No material in model!");
209
+				} else if (material.getTexture() != null) {
210
+					GL11.glBindTexture(GL11.GL_TEXTURE_2D, material.getTexture().getTextureID());
211
+				} else
212
+					GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
213
+
214
+				if (material != null && material.getKd() != null)
215
+					GL11.glColor3f(material.getKd().getX(), material.getKd().getY(), material.getKd().getZ());
216
+			}
217
+
218
+			if (face.getType() == Face.GL_TRIANGLES) {
219
+				GL11.glBegin(GL11.GL_TRIANGLES);
220
+			} else if (face.getType() == Face.GL_QUADS) {
221
+				GL11.glBegin(GL11.GL_QUADS);
222
+			} else {
223
+				GL11.glBegin(GL11.GL_POLYGON);
224
+			}
225
+
226
+			Vertex vertex = null;
227
+			Vertex normal = null;
228
+			TextureCoordinate textureCoo = null;
229
+			for (int j = 0; j < face.getVertices().length; j++) {
230
+				vertex = face.getVertices()[j];
231
+				if (j < face.getNormals().length && face.getNormals()[j] != null) {
232
+					normal = face.getNormals()[j];
233
+					GL11.glNormal3f(normal.getX(), normal.getY(), normal.getZ());
234
+				}
235
+
236
+				if (j < face.getTextures().length && face.getTextures()[j] != null) {
237
+					textureCoo = face.getTextures()[j];
238
+					GL11.glTexCoord2f(textureCoo.getU(), textureCoo.getV());
239
+					//GL11.glTexCoord2f(textureCoo.getV(),textureCoo.getU());
240
+				}
241
+
242
+				GL11.glVertex3f(vertex.getX(), vertex.getY(), vertex.getZ());
243
+			}
244
+			GL11.glEnd();
245
+		}
246
+		GL11.glEndList();
247
+	}
248
+
249
+	public void setMaterials(Hashtable<String, Material> materials) {
250
+		this.materials = materials;
251
+	}
252
+
253
+	public void setTextures(ArrayList<TextureCoordinate> textures) {
254
+		this.textures = textures;
255
+	}
256
+
257
+	public ArrayList<TextureCoordinate> getTextures() {
258
+		return textures;
259
+	}
260
+
261
+	public void setVertices(ArrayList<Vertex> vertices) {
262
+		this.vertices = vertices;
263
+	}
264
+
265
+	public ArrayList<Vertex> getVertices() {
266
+		return vertices;
267
+	}
268
+
269
+	public void setFaces(ArrayList<Face> faces) {
270
+		this.faces = faces;
271
+	}
272
+
273
+	public ArrayList<Face> getFaces() {
274
+		return faces;
275
+	}
276
+
277
+	public void setNormals(ArrayList<Vertex> normals) {
278
+		this.normals = normals;
279
+	}
280
+
281
+	public ArrayList<Vertex> getNormals() {
282
+		return normals;
283
+	}
284
+
285
+	public Hashtable<String, Material> getMaterials() {
286
+
287
+		return this.materials;
288
+	}
289
+
290
+	public Material getCurrentMaterial() {
291
+		return currentMaterial;
292
+	}
293
+
294
+	public void setCurrentMaterial(Material currentMaterial) {
295
+		this.currentMaterial = currentMaterial;
296
+	}
297
+
298
+
299
+
300
+}

+ 35 - 0
src/com/mykaruga/models/wavefront/loader/TextureCoordinate.java View File

@@ -0,0 +1,35 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+public class TextureCoordinate {
5
+
6
+	private float u;
7
+	private float v;
8
+	private float w;
9
+
10
+	public float getU() {
11
+		return u;
12
+	}
13
+
14
+	public void setU(float u) {
15
+		this.u = u;
16
+	}
17
+
18
+	public float getV() {
19
+		return v;
20
+	}
21
+
22
+	public void setV(float v) {
23
+		this.v = v;
24
+	}
25
+
26
+	public float getW() {
27
+		return w;
28
+	}
29
+
30
+	public void setW(float w) {
31
+		this.w = w;
32
+	}
33
+
34
+
35
+}

+ 45 - 0
src/com/mykaruga/models/wavefront/loader/Vertex.java View File

@@ -0,0 +1,45 @@
1
+package com.mykaruga.models.wavefront.loader;
2
+
3
+
4
+public class Vertex {
5
+
6
+	private float x;
7
+	private float y;
8
+	private float z;
9
+
10
+	public Vertex(float x, float y, float z) {
11
+		this.x = x;
12
+		this.y = y;
13
+		this.z = z;
14
+	}
15
+
16
+	public Vertex() {}
17
+
18
+	public float getX() {
19
+		return x;
20
+	}
21
+
22
+	public void setX(float x) {
23
+		this.x = x;
24
+	}
25
+
26
+	public float getY() {
27
+		return y;
28
+	}
29
+
30
+	public void setY(float y) {
31
+		this.y = y;
32
+	}
33
+
34
+	public float getZ() {
35
+		return z;
36
+	}
37
+
38
+	public void setZ(float z) {
39
+		this.z = z;
40
+	}
41
+
42
+	public double norm() {
43
+		return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
44
+	}
45
+}

+ 15 - 0
src/com/mykaruga/models/wavefront/parser/CommentParser.java View File

@@ -0,0 +1,15 @@
1
+package com.mykaruga.models.wavefront.parser;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+
6
+
7
+public class CommentParser extends LineParser {
8
+
9
+	@Override
10
+	public void incoporateResults(RenderModel wavefrontObject) {}
11
+
12
+	@Override
13
+	public void parse() {}
14
+
15
+}

+ 19 - 0
src/com/mykaruga/models/wavefront/parser/DefaultParser.java View File

@@ -0,0 +1,19 @@
1
+package com.mykaruga.models.wavefront.parser;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+
6
+
7
+public class DefaultParser extends LineParser {
8
+
9
+	public DefaultParser() {}
10
+
11
+	@Override
12
+	public void parse() {
13
+
14
+	}
15
+
16
+	@Override
17
+	public void incoporateResults(RenderModel wavefrontObject) {}
18
+
19
+}

+ 19 - 0
src/com/mykaruga/models/wavefront/parser/LineParser.java View File

@@ -0,0 +1,19 @@
1
+package com.mykaruga.models.wavefront.parser;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+
6
+
7
+public abstract class LineParser {
8
+
9
+	protected String[] words = null;
10
+
11
+	public void setWords(String[] words) {
12
+		this.words = words;
13
+	}
14
+
15
+	public abstract void parse();
16
+
17
+	public abstract void incoporateResults(RenderModel wavefrontObject);
18
+
19
+}

+ 41 - 0
src/com/mykaruga/models/wavefront/parser/mtl/KdMapParser.java View File

@@ -0,0 +1,41 @@
1
+package com.mykaruga.models.wavefront.parser.mtl;
2
+
3
+
4
+import net.spritegen.textures.TextureManager;
5
+
6
+import org.newdawn.slick.opengl.Texture;
7
+
8
+import com.mykaruga.models.wavefront.loader.Material;
9
+import com.mykaruga.models.wavefront.loader.RenderModel;
10
+import com.mykaruga.models.wavefront.parser.LineParser;
11
+
12
+
13
+public class KdMapParser extends LineParser {
14
+
15
+	private Texture texture = null;
16
+	private RenderModel object = null;
17
+	private String textureFileName = null;
18
+
19
+	public KdMapParser(RenderModel object) {
20
+		this.object = object;
21
+	}
22
+
23
+	@Override
24
+	public void incoporateResults(RenderModel wavefrontObject) {
25
+
26
+		if (texture != null) {
27
+			Material currentMaterial = wavefrontObject.getCurrentMaterial();
28
+			currentMaterial.setTexture(texture);
29
+		}
30
+	}
31
+
32
+	@Override
33
+	public void parse() {
34
+		String textureFileName = words[words.length - 1];
35
+		String pathToTextureBinary = object.getContextfolder() + (object.replTexture == null ? textureFileName : object.replTexture);
36
+
37
+		// load texture, if already loaded, use the same instance.
38
+		texture = TextureManager.load(pathToTextureBinary);
39
+	}
40
+
41
+}

+ 35 - 0
src/com/mykaruga/models/wavefront/parser/mtl/KdParser.java View File

@@ -0,0 +1,35 @@
1
+package com.mykaruga.models.wavefront.parser.mtl;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.Material;
5
+import com.mykaruga.models.wavefront.loader.RenderModel;
6
+import com.mykaruga.models.wavefront.loader.Vertex;
7
+import com.mykaruga.models.wavefront.parser.LineParser;
8
+
9
+
10
+
11
+public class KdParser extends LineParser {
12
+
13
+	Vertex kd = null;
14
+
15
+	@Override
16
+	public void incoporateResults(RenderModel wavefrontObject) {
17
+		Material currentMaterial = wavefrontObject.getCurrentMaterial();
18
+		currentMaterial.setKa(kd);
19
+
20
+	}
21
+
22
+	@Override
23
+	public void parse() {
24
+		kd = new Vertex();
25
+
26
+		try {
27
+			kd.setX(Float.parseFloat(words[1]));
28
+			kd.setY(Float.parseFloat(words[2]));
29
+			kd.setZ(Float.parseFloat(words[3]));
30
+		} catch (Exception e) {
31
+			throw new RuntimeException("VertexParser Error");
32
+		}
33
+	}
34
+
35
+}

+ 74 - 0
src/com/mykaruga/models/wavefront/parser/mtl/MaterialFileParser.java View File

@@ -0,0 +1,74 @@
1
+package com.mykaruga.models.wavefront.parser.mtl;
2
+
3
+
4
+import java.io.BufferedReader;
5
+import java.io.File;
6
+import java.io.FileInputStream;
7
+import java.io.InputStream;
8
+import java.io.InputStreamReader;
9
+import java.util.Hashtable;
10
+
11
+
12
+import org.newdawn.slick.util.ResourceLoader;
13
+
14
+import com.mykaruga.models.wavefront.loader.Material;
15
+import com.mykaruga.models.wavefront.loader.RenderModel;
16
+import com.mykaruga.models.wavefront.parser.LineParser;
17
+
18
+
19
+
20
+public class MaterialFileParser extends LineParser {
21
+
22
+	Hashtable<String, Material> materials = new Hashtable<String, Material>();
23
+	private RenderModel object;
24
+	private MtlLineParserFactory parserFactory = null;
25
+
26
+	public MaterialFileParser(RenderModel object) {
27
+		this.object = object;
28
+		this.parserFactory = new MtlLineParserFactory(object);
29
+	}
30
+
31
+	@Override
32
+	public void incoporateResults(RenderModel wavefrontObject) {
33
+		// Material are directly added by the parser, no need to do anything here...
34
+	}
35
+
36
+	@Override
37
+	public void parse() {
38
+		String filename = words[1];
39
+
40
+		String pathToMTL = object.getContextfolder() + filename;
41
+
42
+		InputStream fileInput = ResourceLoader.getResourceAsStream(pathToMTL);
43
+		if (fileInput == null) {
44
+			// Could not find the file in the jar.
45
+			try {
46
+				File file = new File(pathToMTL);
47
+				if (file.exists()) fileInput = new FileInputStream(file);
48
+			} catch (Exception e2) {
49
+				e2.printStackTrace();
50
+			}
51
+		}
52
+
53
+		try {
54
+			BufferedReader in = new BufferedReader(new InputStreamReader(fileInput));
55
+
56
+			String currentLine = null;
57
+			while ((currentLine = in.readLine()) != null) {
58
+
59
+				LineParser parser = parserFactory.getLineParser(currentLine);
60
+				parser.parse();
61
+				parser.incoporateResults(object);
62
+			}
63
+
64
+			if (in != null) in.close();
65
+
66
+		} catch (Exception e) {
67
+			e.printStackTrace();
68
+			throw new RuntimeException("Error parsing " + pathToMTL);
69
+		}
70
+
71
+	}
72
+
73
+
74
+}

+ 27 - 0
src/com/mykaruga/models/wavefront/parser/mtl/MaterialParser.java View File

@@ -0,0 +1,27 @@
1
+package com.mykaruga.models.wavefront.parser.mtl;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.Material;
5
+import com.mykaruga.models.wavefront.loader.RenderModel;
6
+import com.mykaruga.models.wavefront.parser.LineParser;
7
+
8
+
9
+
10
+public class MaterialParser extends LineParser {
11
+
12
+	String materialName = "";
13
+
14
+	@Override
15
+	public void incoporateResults(RenderModel wavefrontObject) {
16
+		Material newMaterial = new Material(materialName);
17
+
18
+		wavefrontObject.getMaterials().put(materialName, newMaterial);
19
+		wavefrontObject.setCurrentMaterial(newMaterial);
20
+	}
21
+
22
+	@Override
23
+	public void parse() {
24
+		materialName = words[1];
25
+	}
26
+
27
+}

+ 24 - 0
src/com/mykaruga/models/wavefront/parser/mtl/MtlLineParserFactory.java View File

@@ -0,0 +1,24 @@
1
+package com.mykaruga.models.wavefront.parser.mtl;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.LineParserFactory;
5
+import com.mykaruga.models.wavefront.loader.RenderModel;
6
+import com.mykaruga.models.wavefront.parser.CommentParser;
7
+
8
+
9
+
10
+public class MtlLineParserFactory extends LineParserFactory {
11
+
12
+
13
+
14
+	public MtlLineParserFactory(RenderModel object) {
15
+		this.object = object;
16
+		parsers.put("newmtl", new MaterialParser());
17
+		parsers.put("Kd", new KdParser());
18
+		parsers.put("map_Kd", new KdMapParser(object));
19
+		parsers.put("#", new CommentParser());
20
+	}
21
+
22
+
23
+
24
+}

+ 98 - 0
src/com/mykaruga/models/wavefront/parser/obj/FaceParser.java View File

@@ -0,0 +1,98 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.Face;
5
+import com.mykaruga.models.wavefront.loader.RenderModel;
6
+import com.mykaruga.models.wavefront.loader.TextureCoordinate;
7
+import com.mykaruga.models.wavefront.loader.Vertex;
8
+import com.mykaruga.models.wavefront.parser.LineParser;
9
+
10
+
11
+
12
+public class FaceParser extends LineParser {
13
+
14
+	private Face face;
15
+	private Vertex[] vertices;
16
+	private Vertex[] normals;
17
+	private TextureCoordinate[] textures;
18
+	private RenderModel object = null;
19
+
20
+	public FaceParser(RenderModel object) {
21
+		this.object = object;
22
+	}
23
+
24
+	@Override
25
+	public void parse() {
26
+		face = new Face();
27
+		normals = new Vertex[words.length - 1];
28
+		textures = new TextureCoordinate[words.length - 1];
29
+		switch (words.length) {
30
+			case 4:
31
+				parseTriangles();
32
+				break;
33
+			case 5:
34
+				parseQuad();
35
+				break;
36
+			default:
37
+				parsePolygon();
38
+		}
39
+
40
+
41
+	}
42
+
43
+	private void parseTriangles() {
44
+		face.setType(Face.GL_TRIANGLES);
45
+		parseLine(3);
46
+	}
47
+
48
+	private void parsePolygon() {
49
+		face.setType(words.length - 1);
50
+		parseLine(words.length - 1);
51
+	}
52
+
53
+	private void parseLine(int vertexCount) {
54
+		String[] rawFaces = null;
55
+		int currentValue;
56
+		vertices = new Vertex[vertexCount];
57
+		for (int i = 1; i <= vertexCount; i++) {
58
+			rawFaces = words[i].split("/");
59
+
60
+			// v
61
+			currentValue = Integer.parseInt(rawFaces[0]);
62
+			vertices[i - 1] = object.getVertices().get(currentValue - 1);	// -1 because references starts at 1
63
+
64
+			if (rawFaces.length == 1) continue;
65
+
66
+			if (!"".equals(rawFaces[1]) && rawFaces.length == 3) {
67
+				currentValue = Integer.parseInt(rawFaces[1]);
68
+				if (currentValue <= object.getTextures().size())  // This is to compensate the fact that if no texture is in the obj file, sometimes '1' is put instead of 'blank' (we find coord1/1/coord3 instead of coord1//coord3 or coord1/coord3)
69
+					textures[i - 1] = object.getTextures().get(currentValue - 1); // -1 because references starts at 1
70
+			}
71
+
72
+
73
+			currentValue = Integer.parseInt(rawFaces[rawFaces.length - 1]);
74
+
75
+			normals[i - 1] = object.getNormals().get(currentValue - 1); 	// -1 because references starts at 1
76
+		}
77
+	}
78
+
79
+	private void parseQuad() {
80
+		face.setType(Face.GL_QUADS);
81
+		parseLine(4);
82
+	}
83
+
84
+	@Override
85
+	public void incoporateResults(RenderModel wavefrontObject) {
86
+
87
+		face.setNormals(this.normals);
88
+		face.setVertices(this.vertices);
89
+		face.setTextures(this.textures);
90
+		if (wavefrontObject.getCurrentMaterial() != null) {
91
+			face.setMaterial(wavefrontObject.getCurrentMaterial());
92
+		}
93
+		wavefrontObject.getFaces().add(face);
94
+
95
+	}
96
+
97
+	static int faceC = 0;
98
+}

+ 21 - 0
src/com/mykaruga/models/wavefront/parser/obj/FreeFormParser.java View File

@@ -0,0 +1,21 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+import com.mykaruga.models.wavefront.parser.LineParser;
6
+
7
+
8
+
9
+public class FreeFormParser extends LineParser {
10
+
11
+	public FreeFormParser() {}
12
+
13
+	@Override
14
+	public void parse() {
15
+
16
+	}
17
+
18
+	@Override
19
+	public void incoporateResults(RenderModel wavefrontObject) {}
20
+
21
+}

+ 27 - 0
src/com/mykaruga/models/wavefront/parser/obj/MaterialParser.java View File

@@ -0,0 +1,27 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.Material;
5
+import com.mykaruga.models.wavefront.loader.RenderModel;
6
+import com.mykaruga.models.wavefront.parser.LineParser;
7
+
8
+
9
+
10
+public class MaterialParser extends LineParser {
11
+	String materialName = "";
12
+
13
+	@Override
14
+	public void parse() {
15
+		materialName = words[1];
16
+	}
17
+
18
+	@Override
19
+	public void incoporateResults(RenderModel wavefrontObject) {
20
+		Material newMaterial = wavefrontObject.getMaterials().get(materialName);
21
+		wavefrontObject.setCurrentMaterial(newMaterial);
22
+
23
+	}
24
+
25
+
26
+
27
+}

+ 29 - 0
src/com/mykaruga/models/wavefront/parser/obj/ObjLineParserFactory.java View File

@@ -0,0 +1,29 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.LineParserFactory;
5
+import com.mykaruga.models.wavefront.loader.NormalParser;
6
+import com.mykaruga.models.wavefront.loader.RenderModel;
7
+import com.mykaruga.models.wavefront.parser.CommentParser;
8
+import com.mykaruga.models.wavefront.parser.mtl.MaterialFileParser;
9
+
10
+
11
+
12
+public class ObjLineParserFactory extends LineParserFactory {
13
+
14
+
15
+
16
+	public ObjLineParserFactory(RenderModel object) {
17
+		this.object = object;
18
+		parsers.put("v", new VertexParser());
19
+		parsers.put("vn", new NormalParser());
20
+		parsers.put("vp", new FreeFormParser());
21
+		parsers.put("vt", new TextureCooParser());
22
+		parsers.put("f", new FaceParser(object));
23
+		parsers.put("#", new CommentParser());
24
+		parsers.put("mtllib", new MaterialFileParser(object));
25
+		parsers.put("usemtl", new MaterialParser());
26
+	}
27
+
28
+
29
+}

+ 37 - 0
src/com/mykaruga/models/wavefront/parser/obj/TextureCooParser.java View File

@@ -0,0 +1,37 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+import com.mykaruga.models.wavefront.loader.TextureCoordinate;
6
+import com.mykaruga.models.wavefront.parser.LineParser;
7
+
8
+
9
+
10
+public class TextureCooParser extends LineParser {
11
+
12
+	private TextureCoordinate coordinate = null;
13
+
14
+	public TextureCooParser() {}
15
+
16
+	@Override
17
+	public void parse() {
18
+		coordinate = new TextureCoordinate();
19
+		try {
20
+			if (words.length >= 2) coordinate.setU(Float.parseFloat(words[1]));
21
+
22
+			if (words.length >= 3) coordinate.setV(1 - Float.parseFloat(words[2]));		// OBJ origin is at upper left, OpenGL origin is	 at lower left.
23
+
24
+			if (words.length >= 4) coordinate.setW(Float.parseFloat(words[3]));
25
+
26
+		} catch (Exception e) {
27
+			throw new RuntimeException("TextureParser Error");
28
+		}
29
+	}
30
+
31
+	@Override
32
+	public void incoporateResults(RenderModel wavefrontObject) {
33
+		wavefrontObject.getTextures().add(coordinate);
34
+
35
+	}
36
+
37
+}

+ 34 - 0
src/com/mykaruga/models/wavefront/parser/obj/VertexParser.java View File

@@ -0,0 +1,34 @@
1
+package com.mykaruga.models.wavefront.parser.obj;
2
+
3
+
4
+import com.mykaruga.models.wavefront.loader.RenderModel;
5
+import com.mykaruga.models.wavefront.loader.Vertex;
6
+import com.mykaruga.models.wavefront.parser.LineParser;
7
+
8
+
9
+
10
+public class VertexParser extends LineParser {
11
+
12
+	Vertex vertex = null;
13
+
14
+	public VertexParser() {}
15
+
16
+	@Override
17
+	public void parse() {
18
+		vertex = new Vertex();
19
+
20
+		try {
21
+			vertex.setX(Float.parseFloat(words[1]));
22
+			vertex.setY(Float.parseFloat(words[2]));
23
+			vertex.setZ(Float.parseFloat(words[3]));
24
+		} catch (Exception e) {
25
+			throw new RuntimeException("VertexParser Error");
26
+		}
27
+	}
28
+
29
+	@Override
30
+	public void incoporateResults(RenderModel wavefrontObject) {
31
+		wavefrontObject.getVertices().add(vertex);
32
+	}
33
+
34
+}

+ 152 - 0
src/com/porcupine/color/HSV.java View File

@@ -0,0 +1,152 @@
1
+package com.porcupine.color;
2
+
3
+
4
+import java.awt.Color;
5
+
6
+import com.porcupine.math.Calc;
7
+
8
+
9
+/**
10
+ * HSV color
11
+ * 
12
+ * @author MightyPork
13
+ */
14
+public class HSV {
15
+
16
+	/** H */
17
+	public double h;
18
+	/** S */
19
+	public double s;
20
+	/** V */
21
+	public double v;
22
+
23
+	/**
24
+	 * Create black color 0,0,0
25
+	 */
26
+	public HSV() {}
27
+
28
+	/**
29
+	 * Color from HSV 0-1
30
+	 * 
31
+	 * @param h
32
+	 * @param s
33
+	 * @param v
34
+	 */
35
+	public HSV(Number h, Number s, Number v) {
36
+		this.h = h.doubleValue();
37
+		this.s = s.doubleValue();
38
+		this.v = v.doubleValue();
39
+		norm();
40
+	}
41
+
42
+	/**
43
+	 * @return hue 0-1
44
+	 */
45
+	public double h() {
46
+		return h;
47
+	}
48
+
49
+	/**
50
+	 * @return saturation 0-1
51
+	 */
52
+	public double s() {
53
+		return s;
54
+	}
55
+
56
+	/**
57
+	 * @return value/brightness 0-1
58
+	 */
59
+	public double v() {
60
+		return v;
61
+	}
62
+
63
+	/**
64
+	 * Set color to other color
65
+	 * 
66
+	 * @param copied copied color
67
+	 * @return this
68
+	 */
69
+	public HSV setTo(HSV copied) {
70
+
71
+		h = copied.h;
72
+		s = copied.s;
73
+		v = copied.v;
74
+
75
+		norm();
76
+		return this;
77
+	}
78
+
79
+	/**
80
+	 * Set to H,S,V 0-1
81
+	 * 
82
+	 * @param h hue
83
+	 * @param s saturation
84
+	 * @param v value
85
+	 * @return this
86
+	 */
87
+	public HSV setTo(Number h, Number s, Number v) {
88
+		this.h = h.doubleValue();
89
+		this.s = s.doubleValue();
90
+		this.v = v.doubleValue();
91
+		norm();
92
+		return this;
93
+	}
94
+
95
+	/**
96
+	 * Fix numbers out of range 0-1
97
+	 */
98
+	public void norm() {
99
+		h = Calc.clampd(h, 0, 1);
100
+		s = Calc.clampd(s, 0, 1);
101
+		v = Calc.clampd(v, 0, 1);
102
+	}
103
+
104
+	/**
105
+	 * Convert to RGB
106
+	 * 
107
+	 * @return RGB representation
108
+	 */
109
+	public RGB toRGB() {
110
+		norm();
111
+
112
+		int rgb = Color.HSBtoRGB((float) h, (float) s, (float) v);
113
+
114
+		return RGB.fromHex(rgb);
115
+	}
116
+
117
+	/**
118
+	 * Make from RGB
119
+	 * 
120
+	 * @param color RGB
121
+	 * @return HSV
122
+	 */
123
+	public static HSV fromRGB(RGB color) {
124
+		return color.toHSV();
125
+	}
126
+
127
+	@Override
128
+	public String toString() {
129
+		return "HSV[" + h + ";" + s + ";" + v + "]";
130
+	}
131
+
132
+	@Override
133
+	public boolean equals(Object obj) {
134
+		if (obj == null) return false;
135
+		if (!(obj instanceof HSV)) return false;
136
+		return ((HSV) obj).h == h && ((HSV) obj).s == s && ((HSV) obj).v == v;
137
+	}
138
+
139
+	@Override
140
+	public int hashCode() {
141
+		return Double.valueOf(h).hashCode() ^ Double.valueOf(s).hashCode() ^ Double.valueOf(v).hashCode();
142
+	}
143
+
144
+	/**
145
+	 * Get a copy
146
+	 * 
147
+	 * @return copy
148
+	 */
149
+	public HSV copy() {
150
+		return new HSV().setTo(this);
151
+	}
152
+}

+ 336 - 0
src/com/porcupine/color/RGB.java View File

@@ -0,0 +1,336 @@
1
+package com.porcupine.color;
2
+
3
+
4
+import java.awt.Color;
5
+
6
+import com.porcupine.math.Calc;
7
+
8
+
9
+/**
10
+ * RGB color
11
+ * 
12
+ * @author MightyPork
13
+ */
14
+public class RGB {
15
+
16
+	/** White */
17
+	public static final RGB WHITE = new RGB(1, 1, 1);
18
+	/** Black */
19
+	public static final RGB BLACK = new RGB(0, 0, 0);
20
+	/** Red */
21
+	public static final RGB RED = new RGB(1, 0, 0);
22
+	/** Lime green */
23
+	public static final RGB GREEN = new RGB(0, 1, 0);
24
+	/** Blue */
25
+	public static final RGB BLUE = new RGB(0, 0, 1);
26
+	/** Yellow */
27
+	public static final RGB YELLOW = new RGB(1, 1, 0);
28
+	/** Purple */
29
+	public static final RGB PURPLE = new RGB(1, 0, 1);
30
+	/** Cyan */
31
+	public static final RGB CYAN = new RGB(0, 1, 1);
32
+	/** orange */
33
+	public static final RGB ORANGE = new RGB(1, 0.6, 0);
34
+	/** no color (alpha=0) */
35
+	public static final RGB TRANSPARENT = new RGB(0, 0, 0, 0);
36
+
37
+	/** R */
38
+	public double r;
39
+	/** G */
40
+	public double g;
41
+	/** B */
42
+	public double b;
43
+	/** ALPHA */
44
+	public double a = 1;
45
+
46
+	/**
47
+	 * Create black color 0,0,0
48
+	 */
49
+	public RGB() {}
50
+
51
+	/**
52
+	 * Get copy with custom alpha
53
+	 * 
54
+	 * @param alpha alpha to set
55
+	 * @return copy w/ alpha
56
+	 */
57
+	public RGB setAlpha(double alpha) {
58
+		return copy().setAlpha_ip(alpha);
59
+	}
60
+
61
+	/**
62
+	 * set alpha IP
63
+	 * 
64
+	 * @param alpha alpha to set
65
+	 * @return this
66
+	 */
67
+	public RGB setAlpha_ip(double alpha) {
68
+		a = alpha;
69
+		norm();
70
+		return this;
71
+	}
72
+
73
+	/**
74
+	 * Get copy.
75
+	 * 
76
+	 * @return copy
77
+	 */
78
+	public RGB copy() {
79
+		return new RGB(r, g, b, a);
80
+	}
81
+
82
+	/**
83
+	 * Get copy with alpha multiplied by custom value
84
+	 * 
85
+	 * @param alpha alpha to set
86
+	 * @return copy w/ alpha
87
+	 */
88
+	public RGB mulAlpha(double alpha) {
89
+		return copy().mulAlpha_ip(alpha);
90
+	}
91
+
92
+	/**
93
+	 * Multiply alpha by given number
94
+	 * 
95
+	 * @param alpha alpha multiplier
96
+	 * @return this
97
+	 */
98
+	public RGB mulAlpha_ip(double alpha) {
99
+		a *= alpha;
100
+		norm();
101
+		return this;
102
+	}
103
+
104
+	/**
105
+	 * Color from RGB 0-1
106
+	 * 
107
+	 * @param r red
108
+	 * @param g green
109
+	 * @param b blue
110
+	 */
111
+	public RGB(Number r, Number g, Number b) {
112
+		this.r = r.doubleValue();
113
+		this.g = g.doubleValue();
114
+		this.b = b.doubleValue();
115
+		norm();
116
+	}
117
+
118
+	/**
119
+	 * Color from RGB 0-1
120
+	 * 
121
+	 * @param r red
122
+	 * @param g green
123
+	 * @param b blue
124
+	 * @param a alpha
125
+	 */
126
+	public RGB(Number r, Number g, Number b, Number a) {
127
+		this.r = r.doubleValue();
128
+		this.g = g.doubleValue();
129
+		this.b = b.doubleValue();
130
+		this.a = a.doubleValue();
131
+		norm();
132
+	}
133
+
134
+	/**
135
+	 * Color from hex 0xRRGGBB
136
+	 * 
137
+	 * @param hex hex integer
138
+	 */
139
+	public RGB(int hex) {
140
+		setTo(RGB.fromHex(hex));
141
+		norm();
142
+	}
143
+
144
+	/**
145
+	 * Color from hex 0xRRGGBB
146
+	 * 
147
+	 * @param hex hex integer
148
+	 * @param alpha alpha color
149
+	 */
150
+	public RGB(int hex, double alpha) {
151
+		setTo(RGB.fromHex(hex));
152
+		a = alpha;
153
+		norm();
154
+	}
155
+
156
+	/**
157
+	 * Color from other RGB and alpha channel
158
+	 * 
159
+	 * @param color other RGB color
160
+	 * @param alpha new alpha channel
161
+	 */
162
+	public RGB(RGB color, double alpha) {
163
+		setTo(color);
164
+		setAlpha_ip(alpha);
165
+	}
166
+
167
+	/**
168
+	 * @return red channel 0-1
169
+	 */
170
+	public double r() {
171
+		return r;
172
+	}
173
+
174
+	/**
175
+	 * @return green channel 0-1
176
+	 */
177
+	public double g() {
178
+		return g;
179
+	}
180
+
181
+	/**
182
+	 * @return blue channel 0-1
183
+	 */
184
+	public double b() {
185
+		return b;
186
+	}
187
+
188
+	/**
189
+	 * @return alpha 0-1
190
+	 */
191
+	public double a() {
192
+		return a;
193
+	}
194
+
195
+	/**
196
+	 * Set color to other color
197
+	 * 
198
+	 * @param copied copied color
199
+	 * @return this
200
+	 */
201
+	public RGB setTo(RGB copied) {
202
+
203
+		r = copied.r;
204
+		g = copied.g;
205
+		b = copied.b;
206
+		a = copied.a;
207
+
208
+		norm();
209
+		return this;
210
+	}
211
+
212
+	/**
213
+	 * Set to represent hex color
214
+	 * 
215
+	 * @param hex hex integer RRGGBB
216
+	 * @return this
217
+	 */
218
+	public RGB setTo(int hex) {
219
+		setTo(RGB.fromHex(hex));
220
+		norm();
221
+		return this;
222
+	}
223
+
224
+	/**
225
+	 * Set to R,G,B 0-1
226
+	 * 
227
+	 * @param r red
228
+	 * @param g green
229
+	 * @param b blue
230
+	 * @param a alpha
231
+	 * @return this
232
+	 */
233
+	public RGB setTo(Number r, Number g, Number b, Number a) {
234
+		this.r = r.doubleValue();
235
+		this.g = g.doubleValue();
236
+		this.b = b.doubleValue();
237
+		this.a = a.doubleValue();
238
+		norm();
239
+		return this;
240
+	}
241
+
242
+	/**
243
+	 * Set to R,G,B 0-1
244
+	 * 
245
+	 * @param r red
246
+	 * @param g green
247
+	 * @param b blue
248
+	 * @return this
249
+	 */
250
+	public RGB setTo(Number r, Number g, Number b) {
251
+		this.r = r.doubleValue();
252
+		this.g = g.doubleValue();
253
+		this.b = b.doubleValue();
254
+		this.a = 1;
255
+		norm();
256
+		return this;
257
+	}
258
+
259
+	/**
260
+	 * Fix numbers out of range 0-1
261
+	 * 
262
+	 * @return this
263
+	 */
264
+	public RGB norm() {
265
+		r = Calc.clampd(r, 0, 1);
266
+		g = Calc.clampd(g, 0, 1);
267
+		b = Calc.clampd(b, 0, 1);
268
+		a = Calc.clampd(a, 0, 1);
269
+		return this;
270
+	}
271
+
272
+	/**
273
+	 * Get hex value 0xRRGGBB
274
+	 * 
275
+	 * @return hex value RRGGBB
276
+	 */
277
+	public int getHex() {
278
+		int ri = (int) Math.round(r * 255);
279
+		int gi = (int) Math.round(g * 255);
280
+		int bi = (int) Math.round(b * 255);
281
+		return (ri << 16) | (gi << 8) | bi;
282
+	}
283
+
284
+	/**
285
+	 * Convert to HSV
286
+	 * 
287
+	 * @return HSV representation
288
+	 */
289
+	public HSV toHSV() {
290
+		float[] hsv = { 0, 0, 0 };
291
+		Color.RGBtoHSB((int) (r * 255), (int) (g * 255), (int) (b * 255), hsv);
292
+		return new HSV(hsv[0], hsv[1], hsv[2]);
293
+	}
294
+
295
+	/**
296
+	 * Create color from hex 0xRRGGBB
297
+	 * 
298
+	 * @param hex hex RRGGBB
299
+	 * @return the new color
300
+	 */
301
+	public static RGB fromHex(int hex) {
302
+		int bi = hex & 0xff;
303
+		int gi = (hex >> 8) & 0xff;
304
+		int ri = (hex >> 16) & 0xff;
305
+		return new RGB(ri / 255D, gi / 255D, bi / 255D);
306
+	}
307
+
308
+
309
+	/**
310
+	 * Make from HSV
311
+	 * 
312
+	 * @param color HSV color
313
+	 * @return RGB
314
+	 */
315
+	public static RGB fromHSV(HSV color) {
316
+		return color.toRGB();
317
+	}
318
+
319
+	@Override
320
+	public String toString() {
321
+		return "RGB[" + r + ";" + g + ";" + b + ";" + a + "]";
322
+	}
323
+
324
+	@Override
325
+	public boolean equals(Object obj) {
326
+		if (obj == null) return false;
327
+		if (!(obj instanceof RGB)) return false;
328
+		return ((RGB) obj).r == r && ((RGB) obj).g == g && ((RGB) obj).b == b && ((RGB) obj).a == a;
329
+	}
330
+
331
+	@Override
332
+	public int hashCode() {
333
+		return Double.valueOf(r).hashCode() ^ Double.valueOf(g).hashCode() ^ Double.valueOf(b).hashCode() ^ Double.valueOf(a).hashCode();
334
+	}
335
+
336
+}

+ 729 - 0
src/com/porcupine/coord/Coord.java View File

@@ -0,0 +1,729 @@
1
+package com.porcupine.coord;
2
+
3
+
4
+import java.util.Random;
5
+
6
+import com.porcupine.math.Calc;
7
+
8
+
9
+/**
10
+ * Coordinate class, object with three or two double coordinates.<br>
11
+ * 
12
+ * @author MightyPork
13
+ */
14
+public class Coord {
15
+	/** Zero Coord */
16
+	public static final Coord ZERO = new Coord(0, 0);
17
+	/** Coord [1;1;1] */
18
+	public static final Coord ONE = new Coord(1, 1, 1);
19
+
20
+	/** RNG */
21
+	protected static Random rand = new Random();
22
+	/** X coordinate */
23
+	public double x = 0;
24
+
25
+	/** Y coordinate */
26
+	public double y = 0;
27
+
28
+	/** Z coordinate */
29
+	public double z = 0;
30
+
31
+	/**
32
+	 * Create zero coord
33
+	 */
34
+	public Coord() {}
35
+
36
+	/**
37
+	 * Create 2D coord
38
+	 * 
39
+	 * @param x x coordinate
40
+	 * @param y y coordinate
41
+	 */
42
+	public Coord(Number x, Number y) {
43
+		setTo(x, y);
44
+	}
45
+
46
+	/**
47
+	 * Create 3D coord
48
+	 * 
49
+	 * @param x x coordinate
50
+	 * @param y y coordinate
51
+	 * @param z z coordinate
52
+	 */
53
+	public Coord(Number x, Number y, Number z) {
54
+		setTo(x, y, z);
55
+	}
56
+
57
+	/**
58
+	 * Create coord as a copy of another
59
+	 * 
60
+	 * @param copied copied coord
61
+	 */
62
+	public Coord(Coord copied) {
63
+		this.x = copied.x;
64
+		this.y = copied.y;
65
+		this.z = copied.z;
66
+	}
67
+
68
+	/**
69
+	 * Convert X and Y coordinates of this coord to a new CoordI.
70
+	 * 
71
+	 * @return the new CoordI
72
+	 */
73
+	public CoordI toCoordI() {
74
+		return new CoordI((int) Math.round(x), (int) Math.round(y));
75
+	}
76
+
77
+	/**
78
+	 * Generate random coord (gaussian)
79
+	 * 
80
+	 * @param max max distance from 0
81
+	 * @return new coord
82
+	 */
83
+	public static Coord random(double max) {
84
+		return new Coord(Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2), Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2),
85
+				Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2));
86
+	}
87
+
88
+	/**
89
+	 * Generate random coord (min-max)
90
+	 * 
91
+	 * @param min min offset
92
+	 * @param max max offset
93
+	 * @return new coord
94
+	 */
95
+	public static Coord random(double min, double max) {
96
+		return new Coord((rand.nextBoolean() ? -1 : 1) * (min + rand.nextDouble() * (max - min)), (rand.nextBoolean() ? -1 : 1)
97
+				* (min + rand.nextDouble() * (max - min)), (rand.nextBoolean() ? -1 : 1) * (min + rand.nextDouble() * (max - min)));
98
+	}
99
+
100
+	/**
101
+	 * offset randomly in place
102
+	 * 
103
+	 * @param max max +- offset
104
+	 * @return this
105
+	 */
106
+	public Coord random_offset_ip(double max) {
107
+		return add(random(max));
108
+	}
109
+
110
+	/**
111
+	 * offset randomly in place
112
+	 * 
113
+	 * @param min min offset
114
+	 * @param max max offset
115
+	 * @return this
116
+	 */
117
+	public Coord random_offset_ip(double min, double max) {
118
+		add(random(min, max));
119
+		return this;
120
+	}
121
+
122
+	/**
123
+	 * Set to max values of this and other coord
124
+	 * 
125
+	 * @param other other coord
126
+	 */
127
+	public void setMax(Coord other) {
128
+		x = Math.max(x, other.x);
129
+		y = Math.max(y, other.y);
130
+		z = Math.max(z, other.z);
131
+	}
132
+
133
+	/**
134
+	 * Set to min values of this and other coord
135
+	 * 
136
+	 * @param other other coord
137
+	 */
138
+	public void setMin(Coord other) {
139
+		x = Math.min(x, other.x);
140
+		y = Math.min(y, other.y);
141
+		z = Math.min(z, other.z);
142
+	}
143
+
144
+	/**
145
+	 * offset randomly
146
+	 * 
147
+	 * @param max max +- offset
148
+	 * @return offset coord
149
+	 */
150
+	public Coord random_offset(double max) {
151
+		Coord r = random(1);
152
+		Vec v = new Vec(r);
153
+		v.norm_ip(0.00001 + rand.nextDouble() * max);
154
+		return copy().add_ip(v);
155
+	}
156
+
157
+	/**
158
+	 * offset randomly
159
+	 * 
160
+	 * @param min min offset
161
+	 * @param max max offset
162
+	 * @return offset coord
163
+	 */
164
+	public Coord random_offset(double min, double max) {
165
+		return copy().add_ip(random(min, max));
166
+	}
167
+
168
+	/**
169
+	 * @return X as double
170
+	 */
171
+	public double x() {
172
+		return x;
173
+	}
174
+
175
+	/**
176
+	 * @return Y as double
177
+	 */
178
+	public double y() {
179
+		return y;
180
+	}
181
+
182
+	/**
183
+	 * @return Z as double
184
+	 */
185
+	public double z() {
186
+		return z;
187
+	}
188
+
189
+	/**
190
+	 * @return X as double
191
+	 */
192
+	public double xd() {
193
+		return x;
194
+	}
195
+
196
+	/**
197
+	 * @return Y as double
198
+	 */
199
+	public double yd() {
200
+		return y;
201
+	}
202
+
203
+	/**
204
+	 * @return Z as double
205
+	 */
206
+	public double zd() {
207
+		return z;
208
+	}
209
+
210
+	/**
211
+	 * @return X as double
212
+	 */
213
+	public float xf() {
214
+		return (float) x;
215
+	}
216
+
217
+	/**
218
+	 * @return Y as double
219
+	 */
220
+	public float yf() {
221
+		return (float) y;
222
+	}
223
+
224
+	/**
225
+	 * @return Z as double
226
+	 */
227
+	public float zf() {
228
+		return (float) z;
229
+	}
230
+
231
+
232
+	/**
233
+	 * @return X as double
234
+	 */
235
+	public int xi() {
236
+		return (int) Math.round(x);
237
+	}
238
+
239
+	/**
240
+	 * @return Y as double
241
+	 */
242
+	public int yi() {
243
+		return (int) Math.round(y);
244
+	}
245
+
246
+	/**
247
+	 * @return Z as double
248
+	 */
249
+	public int zi() {
250
+		return (int) Math.round(z);
251
+	}
252
+
253
+	/**
254
+	 * Set 3D coordinates to
255
+	 * 
256
+	 * @param x x coordinate
257
+	 * @param y y coordinate
258
+	 * @param z z coordinate
259
+	 * @return this
260
+	 */
261
+	public Coord setTo(Number x, Number y, Number z) {
262
+		this.x = x.doubleValue();
263
+		this.y = y.doubleValue();
264
+		this.z = z.doubleValue();
265
+		return this;
266
+	}
267
+
268
+	/**
269
+	 * Set 2D coordinates to
270
+	 * 
271
+	 * @param x x coordinate
272
+	 * @param y y coordinate
273
+	 * @return this
274
+	 */
275
+	public Coord setTo(Number x, Number y) {
276
+		setTo(x, y, 0);
277
+		return this;
278
+	}
279
+
280
+	/**
281
+	 * Set coordinates to match other coord
282
+	 * 
283
+	 * @param copied coord whose coordinates are used
284
+	 * @return this
285
+	 */
286
+	public Coord setTo(Coord copied) {
287
+		setTo(copied.x, copied.y, copied.z);
288
+		return this;
289
+	}
290
+
291
+	/**
292
+	 * Set X coordinate in place
293
+	 * 
294
+	 * @param x x coordinate
295
+	 * @return this
296
+	 */
297
+	public Coord setX_ip(Number x) {
298
+		this.x = x.doubleValue();
299
+		return this;
300
+	}
301
+
302
+	/**
303
+	 * Set Y coordinate in place
304
+	 * 
305
+	 * @param y y coordinate
306
+	 * @return this
307
+	 */
308
+	public Coord setY_ip(Number y) {
309
+		this.y = y.doubleValue();
310
+		return this;
311
+	}
312
+
313
+	/**
314
+	 * Set Z coordinate in place
315
+	 * 
316
+	 * @param z z coordinate
317
+	 * @return this
318
+	 */
319
+	public Coord setZ_ip(Number z) {
320
+		this.z = z.doubleValue();
321
+		return this;
322
+	}
323
+
324
+	/**
325
+	 * Set X coordinate in a copy
326
+	 * 
327
+	 * @param x x coordinate
328
+	 * @return copy with set coordinate
329
+	 */
330
+	public Coord setX(Number x) {
331
+		return copy().setX_ip(x);
332
+	}
333
+
334
+	/**
335
+	 * Set Y coordinate in a copy
336
+	 * 
337
+	 * @param y y coordinate
338
+	 * @return copy with set coordinate
339
+	 */
340
+	public Coord setY(Number y) {
341
+		return copy().setY_ip(y);
342
+	}
343
+
344
+	/**
345
+	 * Set Z coordinate in a copy
346
+	 * 
347
+	 * @param z z coordinate
348
+	 * @return copy with set coordinate
349
+	 */
350
+	public Coord setZ(Number z) {
351
+		return copy().setZ_ip(z);
352
+	}
353
+
354
+
355
+
356
+	/**
357
+	 * Get a copy subtracted by 3D coordinate
358
+	 * 
359
+	 * @param x x offset
360
+	 * @param y y offset
361
+	 * @param z z offset
362
+	 * @return the offset copy
363
+	 */
364
+	public Coord sub(Number x, Number y, Number z) {
365
+		return copy().sub_ip(x, y, z);
366
+	}
367
+
368
+	/**
369
+	 * Get a copy subtracted by 2D coordinate
370
+	 * 
371
+	 * @param x x offset
372
+	 * @param y y offset
373
+	 * @return the offset copy
374
+	 */
375
+	public Coord sub(Number x, Number y) {
376
+		return copy().sub_ip(x, y);
377
+	}
378
+
379
+	/**
380
+	 * Get a copy subtracted by vector
381
+	 * 
382
+	 * @param vec offset
383
+	 * @return the offset copy
384
+	 */
385
+	public Coord sub(Coord vec) {
386
+		return copy().sub_ip(vec);
387
+	}
388
+
389
+	/**
390
+	 * Offset by 3D coordinate in place
391
+	 * 
392
+	 * @param x x offset
393
+	 * @param y y offset
394
+	 * @param z z offset
395
+	 * @return this
396
+	 */
397
+	public Coord sub_ip(Number x, Number y, Number z) {
398
+		this.x -= x.doubleValue();
399
+		this.y -= y.doubleValue();
400
+		this.z -= z.doubleValue();
401
+		return this;
402
+	}
403
+
404
+	/**
405
+	 * Offset by 2D coordinate in place
406
+	 * 
407
+	 * @param x x offset
408
+	 * @param y y offset
409
+	 * @return this
410
+	 */
411
+	public Coord sub_ip(Number x, Number y) {
412
+		this.x -= x.doubleValue();
413
+		this.y -= y.doubleValue();
414
+		return this;
415
+	}
416
+
417
+	/**
418
+	 * Offset by vector in place
419
+	 * 
420
+	 * @param vec offset
421
+	 * @return this
422
+	 */
423
+	public Coord sub_ip(Coord vec) {
424
+		this.x -= vec.x;
425
+		this.y -= vec.y;
426
+		this.z -= vec.z;
427
+		return this;
428
+	}
429
+
430
+	/**
431
+	 * Get a copy offset by 3D coordinate
432
+	 * 
433
+	 * @param x x offset
434
+	 * @param y y offset
435
+	 * @param z z offset
436
+	 * @return the offset copy
437
+	 */
438
+	public Coord add(Number x, Number y, Number z) {
439
+		return copy().add_ip(x, y, z);
440
+	}
441
+
442
+	/**
443
+	 * Get a copy offset by 2D coordinate
444
+	 * 
445
+	 * @param x x offset
446
+	 * @param y y offset
447
+	 * @return the offset copy
448
+	 */
449
+	public Coord add(Number x, Number y) {
450
+		return copy().add_ip(x, y);
451
+	}
452
+
453
+	/**
454
+	 * Get a copy offset by vector
455
+	 * 
456
+	 * @param vec offset
457
+	 * @return the offset copy
458
+	 */
459
+	public Coord add(Coord vec) {
460
+		return copy().add_ip(vec);
461
+	}
462
+
463
+	/**
464
+	 * Offset by 3D coordinate in place
465
+	 * 
466
+	 * @param x x offset
467
+	 * @param y y offset
468
+	 * @param z z offset
469
+	 * @return this
470
+	 */
471
+	public Coord add_ip(Number x, Number y, Number z) {
472
+		this.x += x.doubleValue();
473
+		this.y += y.doubleValue();
474
+		this.z += z.doubleValue();
475
+		return this;
476
+	}
477
+
478
+	/**
479
+	 * Offset by 2D coordinate in place
480
+	 * 
481
+	 * @param x x offset
482
+	 * @param y y offset
483
+	 * @return this
484
+	 */
485
+	public Coord add_ip(Number x, Number y) {
486
+		this.x += x.doubleValue();
487
+		this.y += y.doubleValue();
488
+		return this;
489
+	}
490
+
491
+	/**
492
+	 * Offset by vector in place
493
+	 * 
494
+	 * @param vec offset
495
+	 * @return this
496
+	 */
497
+	public Coord add_ip(Coord vec) {
498
+		this.x += vec.x;
499
+		this.y += vec.y;
500
+		this.z += vec.z;
501
+		return this;
502
+	}
503
+
504
+	/**
505
+	 * @return copy of this vector
506
+	 */
507
+	public Coord copy() {
508
+		return new Coord(x, y, z);
509
+	}
510
+
511
+
512
+	/**
513
+	 * Get distance to other point
514
+	 * 
515
+	 * @param point other point
516
+	 * @return distance in units
517
+	 */
518
+	public double distTo(Coord point) {
519
+		return Math.sqrt((point.x - x) * (point.x - x) + (point.y - y) * (point.y - y) + (point.z - z) * (point.z - z));
520
+	}
521
+
522
+	/**
523
+	 * Create vector from this point to other point
524
+	 * 
525
+	 * @param point second point
526
+	 * @return vector
527
+	 */
528
+	public Vec vecTo(Coord point) {
529
+		return (Vec) (new Vec(point)).add(new Vec(this).neg());
530
+	}
531
+
532
+	/**
533
+	 * Get distance to other point
534
+	 * 
535
+	 * @param a point a
536
+	 * @param b point b
537
+	 * @return distance in units
538
+	 */
539
+	public static double dist(Coord a, Coord b) {
540
+		return a.distTo(b);
541
+	}
542
+
543
+	/**
544
+	 * Get middle of line to other point
545
+	 * 
546
+	 * @param other other point
547
+	 * @return middle
548
+	 */
549
+	public Coord midTo(Coord other) {
550
+		return add(vecTo(other).scale(0.5));
551
+	}
552
+
553
+	private Coord last;
554
+	private Vec offs;
555
+
556
+	/**
557
+	 * Store current value as LAST
558
+	 */
559
+	public void pushLast() {
560
+		if (last == null) last = new Coord();
561
+		if (offs == null) offs = new Vec();
562
+		last.setTo(this);
563
+	}
564
+
565
+	/**
566
+	 * Apply coordinates change for delta time
567
+	 */
568
+	public void update() {
569
+		if (last == null) last = new Coord();
570
+		if (offs == null) offs = new Vec();
571
+		offs = last.vecTo(this);
572
+	}
573
+
574
+	/**
575
+	 * Get coordinate at delta time since LAST
576
+	 * 
577
+	 * @param delta delta time 0-1
578
+	 * @return delta pos
579
+	 */
580
+	public Coord getDelta(double delta) {
581
+		if (last == null) last = new Coord();
582
+		if (offs == null) offs = new Vec();
583
+		return new Coord(this.add(offs.scale(delta)));
584
+	}
585
+
586
+	@Override
587
+	public String toString() {
588
+		return "[ " + x + " ; " + y + " ; " + z + " ]";
589
+	}
590
+
591
+	@Override
592
+	public boolean equals(Object obj) {
593
+		if (obj == null) return false;
594
+		if (!obj.getClass().isAssignableFrom(Vec.class)) return false;
595
+		Vec other = (Vec) obj;
596
+		return x == other.x && y == other.y && z == other.z;
597
+	}
598
+
599
+	@Override
600
+	public int hashCode() {
601
+		return Double.valueOf(x).hashCode() ^ Double.valueOf(y).hashCode() ^ Double.valueOf(z).hashCode();
602
+	}
603
+
604
+	/**
605
+	 * Multiply by number
606
+	 * 
607
+	 * @param d number
608
+	 * @return multiplied copy
609
+	 */
610
+	public Coord mul(double d) {
611
+		return copy().mul_ip(d);
612
+	}
613
+
614
+	/**
615
+	 * Multiply by number in place
616
+	 * 
617
+	 * @param d multiplier
618
+	 * @return this
619
+	 */
620
+	public Coord mul_ip(double d) {
621
+		x *= d;
622
+		y *= d;
623
+		z *= d;
624
+		return this;
625
+	}
626
+
627
+	/**
628
+	 * Multiply coords by number
629
+	 * 
630
+	 * @param xd x multiplier
631
+	 * @param yd y multiplier
632
+	 * @param zd z multiplier
633
+	 * @return multiplied copy
634
+	 */
635
+	public Coord mul(double xd, double yd, double zd) {
636
+		return copy().mul_ip(xd, yd, zd);
637
+	}
638
+
639
+	/**
640
+	 * Multiply coords by number in place
641
+	 * 
642
+	 * @param xd x multiplier
643
+	 * @param yd y multiplier
644
+	 * @param zd z multiplier
645
+	 * @return this
646
+	 */
647
+	public Coord mul_ip(double xd, double yd, double zd) {
648
+		x *= xd;
649
+		y *= yd;
650
+		z *= zd;
651
+		return this;
652
+	}
653
+
654
+	/**
655
+	 * Divide by number in place
656
+	 * 
657
+	 * @param d number to divide by
658
+	 * @return this
659
+	 */
660
+	public Coord div_ip(double d) {
661
+		if (d == 0) return this;
662
+		x /= d;
663
+		y /= d;
664
+		z /= d;
665
+		return this;
666
+	}
667
+
668
+	/**
669
+	 * Get copy divided by number
670
+	 * 
671
+	 * @param d number to divide by
672
+	 * @return divided copy
673
+	 */
674
+	public Coord div(double d) {
675
+		return copy().div_ip(d);
676
+	}
677
+
678
+	/**
679
+	 * Round in place
680
+	 * 
681
+	 * @return this
682
+	 */
683
+	public Coord round_ip() {
684
+		x = Math.round(x);
685
+		y = Math.round(y);
686
+		z = Math.round(z);
687
+		return this;
688
+	}
689
+
690
+
691
+	/**
692
+	 * Get a copy with rounded coords
693
+	 * 
694
+	 * @return rounded copy
695
+	 */
696
+	public Coord round() {
697
+		return copy().round_ip();
698
+	}
699
+
700
+	/**
701
+	 * Check if this rectangle in inside a rectangular zone
702
+	 * 
703
+	 * @param min min coord
704
+	 * @param max max coord
705
+	 * @return is inside
706
+	 */
707
+	public boolean isInRect(Coord min, Coord max) {
708
+		return (x >= min.x && x <= max.x) && (y >= min.y && y <= max.y) && (z >= min.z && z <= max.z);
709
+	}
710
+
711
+	/**
712
+	 * Check if this rectangle in inside a rectangular zone
713
+	 * 
714
+	 * @param rect checked rect.
715
+	 * @return is inside
716
+	 */
717
+	public boolean isInRect(Rect rect) {
718
+		return isInRect(rect.min, rect.max);		
719
+	}
720
+
721
+	/**
722
+	 * Get size
723
+	 * 
724
+	 * @return size
725
+	 */
726
+	public double size() {
727
+		return new Vec(this).size();
728
+	}
729
+}

+ 159 - 0
src/com/porcupine/coord/CoordI.java View File

@@ -0,0 +1,159 @@
1
+package com.porcupine.coord;
2
+
3
+
4
+/**
5
+ * Simple integer coordinate class<br>
6
+ * Unlike Coord, this is suitable for using in array indices etc.
7
+ * 
8
+ * @author MightyPork
9
+ */
10
+public class CoordI {
11
+
12
+	/** X coordinate */
13
+	public int x = 0;
14
+	/** Y coordinate */
15
+	public int y = 0;
16
+
17
+	/**
18
+	 * Integer 2D Coord
19
+	 * 
20
+	 * @param x x coord
21
+	 * @param y y coord
22
+	 */
23
+	public CoordI(int x, int y) {
24
+		this.x = x;
25
+		this.y = y;
26
+	}
27
+
28
+	/**
29
+	 * Create CoordI as copy of other
30
+	 * 
31
+	 * @param other coord to copy
32
+	 */
33
+	public CoordI(CoordI other) {
34
+		setTo(other);
35
+	}
36
+
37
+	/**
38
+	 * Get copy
39
+	 * 
40
+	 * @return copy
41
+	 */
42
+	public CoordI copy() {
43
+		return new CoordI(x, y);
44
+	}
45
+
46
+	/**
47
+	 * Set coords to
48
+	 * 
49
+	 * @param x x coord to set
50
+	 * @param y y coord to set
51
+	 */
52
+	public void setTo(int x, int y) {
53
+		this.x = x;
54
+		this.y = y;
55
+	}
56
+
57
+	/**
58
+	 * Set to coords from other coord
59
+	 * 
60
+	 * @param other source coord
61
+	 */
62
+	public void setTo(CoordI other) {
63
+		this.x = other.x;
64
+		this.y = other.y;
65
+	}
66
+
67
+	/**
68
+	 * Convert to double Coord
69
+	 * 
70
+	 * @return coord with X and y from this CoordI
71
+	 */
72
+	public Coord toCoord() {
73
+		return new Coord(x, y);