diff --git a/.project b/.project
index 3c97cd6..1902c26 100644
--- a/.project
+++ b/.project
@@ -6,6 +6,11 @@
atriasoft-ege
+
+ org.python.pydev.PyDevBuilder
+
+
+
org.eclipse.jdt.core.javabuilder
@@ -14,5 +19,6 @@
org.eclipse.jdt.core.javanature
+ org.python.pydev.pythonNature
diff --git a/.pydevproject b/.pydevproject
new file mode 100644
index 0000000..2b04565
--- /dev/null
+++ b/.pydevproject
@@ -0,0 +1,5 @@
+
+
+ Default
+ python interpreter
+
diff --git a/blender/io_scene_emf/__init__.py b/blender/io_scene_emf/__init__.py
index 3589674..2d8d173 100644
--- a/blender/io_scene_emf/__init__.py
+++ b/blender/io_scene_emf/__init__.py
@@ -125,7 +125,7 @@ class ExportEMF(bpy.types.Operator, ExportHelper):
global_matrix[0][0] = \
global_matrix[1][1] = \
- global_matrix[2][2] = self.global_scale
+ global_matrix[2][2] = 1.0 #self.global_scale
return export_emf.save(self, context, **keywords)
diff --git a/blender/io_scene_emf/exportEmf.py b/blender/io_scene_emf/exportEmf.py
index 7d8b37b..3c2c122 100644
--- a/blender/io_scene_emf/exportEmf.py
+++ b/blender/io_scene_emf/exportEmf.py
@@ -8,5 +8,17 @@ import bpy
#bpy.ops.export_scene.emf(filepath="/home/heero/dev/workspace-game/atriasoft/ege/samples/resources/emf/Entry.emf")
-bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/workspace-game/model/tower.blend")
-bpy.ops.export_scene.emf(filepath="/home/heero/dev/workspace-game/atriasoft/ege/samples/resources/emf/tower.emf")
+bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck1.blend")
+bpy.ops.export_scene.emf(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck_001.emf")
+
+bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck2.blend")
+bpy.ops.export_scene.emf(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck_002.emf")
+
+bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck3.blend")
+bpy.ops.export_scene.emf(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/truck_003.emf")
+
+bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/car1.blend")
+bpy.ops.export_scene.emf(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/car_001.emf")
+
+bpy.ops.wm.open_mainfile(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/map_2.blend")
+bpy.ops.export_scene.emf(filepath="/home/heero/dev/WORKSPACE-game/Edouard-DUPIN/zleep/resources/lowPoly/map_002.emf")
\ No newline at end of file
diff --git a/blender/io_scene_emf/export_emf.py b/blender/io_scene_emf/export_emf.py
index dbdb49e..b3ecf17 100644
--- a/blender/io_scene_emf/export_emf.py
+++ b/blender/io_scene_emf/export_emf.py
@@ -684,7 +684,7 @@ def _write(context,
collection = col
break
if collection.name != "root":
- raise "Can not detect collition 'root'"
+ raise "Can not detect collection 'root'"
#print("* collection name: " + str(collection.name) + "/" + str(collection.name_full) )
print("============================================================================================");
diff --git a/samples/src/sample/atriasoft/ege/loxelEngine/LoxelApplication.java b/samples/src/sample/atriasoft/ege/loxelEngine/LoxelApplication.java
index cb9b242..a0a0ccc 100644
--- a/samples/src/sample/atriasoft/ege/loxelEngine/LoxelApplication.java
+++ b/samples/src/sample/atriasoft/ege/loxelEngine/LoxelApplication.java
@@ -37,8 +37,8 @@ import org.atriasoft.etk.math.Quaternion;
import org.atriasoft.etk.math.Transform3D;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector3f;
-import org.atriasoft.gale.GaleApplication;
import org.atriasoft.gale.Gale;
+import org.atriasoft.gale.GaleApplication;
import org.atriasoft.gale.backend3d.OpenGL;
import org.atriasoft.gale.backend3d.OpenGL.Flag;
import org.atriasoft.gale.context.GaleContext;
diff --git a/samples/src/sample/atriasoft/ege/loxelEngine/MainLoxelEngine.java b/samples/src/sample/atriasoft/ege/loxelEngine/MainLoxelEngine.java
index 77eb2bf..c9b1b0f 100644
--- a/samples/src/sample/atriasoft/ege/loxelEngine/MainLoxelEngine.java
+++ b/samples/src/sample/atriasoft/ege/loxelEngine/MainLoxelEngine.java
@@ -12,8 +12,8 @@ public class MainLoxelEngine {
Ege.init();
Uri.setGroup("DATA", "data/");
Uri.setGroup("RES", "res");
- Uri.addLibrary("loxelEngine", MainCollisionTest.class, "testDataLoxelEngine/");
- Uri.setApplication(MainCollisionTest.class, "");
+ Uri.addLibrary("loxelEngine", MainLoxelEngine.class, "testDataLoxelEngine/");
+ Uri.setApplication(MainLoxelEngine.class, "");
Gale.run(new LoxelApplication(), args);
}
}
diff --git a/samples/src/sample/atriasoft/ege/loxelEnginePerso/Log.java b/samples/src/sample/atriasoft/ege/loxelEnginePerso/Log.java
new file mode 100644
index 0000000..e2a2ac6
--- /dev/null
+++ b/samples/src/sample/atriasoft/ege/loxelEnginePerso/Log.java
@@ -0,0 +1,39 @@
+package sample.atriasoft.ege.loxelEnginePerso;
+
+public class Log {
+ private static final String LIBNAME = "LoxelEnginePerso";
+
+ public static void critical(String data) {
+ System.out.println("[C] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void debug(String data) {
+ System.out.println("[D] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void error(String data) {
+ System.out.println("[E] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void info(String data) {
+ System.out.println("[I] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void print(String data) {
+ System.out.println(data);
+ }
+
+ public static void todo(String data) {
+ System.out.println("[TODO] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void verbose(String data) {
+ System.out.println("[V] " + Log.LIBNAME + " | " + data);
+ }
+
+ public static void warning(String data) {
+ System.out.println("[W] " + Log.LIBNAME + " | " + data);
+ }
+
+ private Log() {}
+}
diff --git a/samples/src/sample/atriasoft/ege/loxelEnginePerso/LoxelApplicationPerso.java b/samples/src/sample/atriasoft/ege/loxelEnginePerso/LoxelApplicationPerso.java
new file mode 100644
index 0000000..15acab3
--- /dev/null
+++ b/samples/src/sample/atriasoft/ege/loxelEnginePerso/LoxelApplicationPerso.java
@@ -0,0 +1,438 @@
+package sample.atriasoft.ege.loxelEnginePerso;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.atriasoft.ege.ControlCameraPlayer;
+import org.atriasoft.ege.Engine;
+import org.atriasoft.ege.Entity;
+import org.atriasoft.ege.Environement;
+import org.atriasoft.ege.GameStatus;
+import org.atriasoft.ege.Light;
+import org.atriasoft.ege.Material;
+import org.atriasoft.ege.camera.Camera;
+import org.atriasoft.ege.components.ComponentGravityStatic;
+import org.atriasoft.ege.components.ComponentLight;
+import org.atriasoft.ege.components.ComponentLightSun;
+import org.atriasoft.ege.components.ComponentMaterial;
+import org.atriasoft.ege.components.ComponentPhysicsPerso;
+import org.atriasoft.ege.components.ComponentPlayer;
+import org.atriasoft.ege.components.ComponentPosition;
+import org.atriasoft.ege.components.ComponentPositionPlayer;
+import org.atriasoft.ege.components.ComponentRenderColoredStaticMesh;
+import org.atriasoft.ege.components.ComponentRenderTexturedMaterialsStaticMesh;
+import org.atriasoft.ege.components.ComponentRenderTexturedStaticMesh;
+import org.atriasoft.ege.components.ComponentStaticMesh;
+import org.atriasoft.ege.components.ComponentTexture;
+import org.atriasoft.ege.components.PhysicBodyType;
+import org.atriasoft.ege.engines.EngineLight;
+import org.atriasoft.ege.engines.EnginePhysics;
+import org.atriasoft.ege.map.MapVoxel;
+import org.atriasoft.phyligram.PhysicBox;
+import org.atriasoft.ege.tools.MeshGenerator;
+import org.atriasoft.etk.Color;
+import org.atriasoft.etk.Uri;
+import org.atriasoft.etk.math.Matrix4f;
+import org.atriasoft.etk.math.Quaternion;
+import org.atriasoft.etk.math.Transform3D;
+import org.atriasoft.etk.math.Vector2f;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.Gale;
+import org.atriasoft.gale.GaleApplication;
+import org.atriasoft.gale.backend3d.OpenGL;
+import org.atriasoft.gale.backend3d.OpenGL.Flag;
+import org.atriasoft.gale.context.GaleContext;
+import org.atriasoft.gale.key.KeyKeyboard;
+import org.atriasoft.gale.key.KeySpecial;
+import org.atriasoft.gale.key.KeyStatus;
+import org.atriasoft.gale.key.KeyType;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+
+public class LoxelApplicationPerso extends GaleApplication {
+ public static Vector3f box1HalfSize;
+ public static Vector3f box2HalfSize;
+ // public static ComponentPosition relativeTestPos;
+ // public static Box boxTest;
+ public static List testPoints = new ArrayList<>();
+ public static List testPointsBox = new ArrayList<>();
+ public static List testPointsCollide = new ArrayList<>();
+ public static Quaternion testQTransfert;
+ public static Vector3f testRpos;
+ private float angleLight = 0;
+ private Quaternion basicRotation = Quaternion.IDENTITY;
+ private Quaternion basicRotation2 = Quaternion.IDENTITY;
+ private ResourceColored3DObject debugDrawProperty;
+ private Environement env;
+ private ComponentPosition lightPosition;
+ private MapVoxel map;
+ private ComponentPlayer objectPlayer;
+ private ComponentPosition objectPosition;
+ private ControlCameraPlayer simpleControl;
+
+ public LoxelApplicationPerso() {
+
+ }
+
+ @Override
+ public void onCreate(final GaleContext context) {
+ // set the system global max speed
+ //ComponentPhysicsPerso.globalMaxSpeed = 3;
+ Gale.getContext().grabPointerEvents(true, new Vector2f(0, 0));
+ this.env = new Environement();
+ setSize(new Vector2f(1500, 1500));
+ setTitle("Loxel sample");
+ this.map = new MapVoxel(this.env);
+ // this.env.addEngine(map);
+ // map.init();
+
+ // simple sun to have a global light ...
+ final Entity globalGravity = new Entity(this.env);
+ globalGravity.addComponent(new ComponentGravityStatic(new Vector3f(0, 0, -1)));
+ this.env.addEntity(globalGravity);
+
+ // simple sun to have a global light ...
+ final Entity sun = new Entity(this.env);
+ sun.addComponent(new ComponentPosition(new Transform3D(new Vector3f(1000, 1000, 1000))));
+ sun.addComponent(new ComponentLightSun(new Light(new Color(0.4f, 0.4f, 0.4f), new Vector3f(0, 0, 0), new Vector3f(0.8f, 0, 0))));
+ this.env.addEntity(sun);
+
+ // add a cube to show where in the light ...
+ final Entity localLight = new Entity(this.env);
+ this.lightPosition = new ComponentPosition(new Transform3D(new Vector3f(-10, -10, 17)));
+ // localLight.addComponent(lightPosition);
+ // localLight.addComponent(new ComponentStaticMesh(new Uri("RES", "cube.obj")));
+ // localLight.addComponent(new ComponentTexture(new Uri("RES", "grass.png")));
+ // localLight.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+ // localLight.addComponent(new ComponentRenderTexturedStaticMesh(
+ // new Uri("DATA", "basic.vert"),
+ // new Uri("DATA", "basic.frag")));
+ // env.addEntity(localLight);
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentLight(new Light(new Color(0.0f, 1.0f, 0.0f), new Vector3f(0, 0, 0), new Vector3f(0.8f, 0.03f, 0.002f))));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0, 0, 5))));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(0.5f, 0.5f, 0.5f));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentLight(new Light(new Color(0.0f,1.0f, 0.0f), new Vector3f(0, 0, 0), new Vector3f(0.8f, 0.03f, 0.002f))));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0, 4, 12.5f))));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(0.5f, 0.5f, 0.5f));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(-2, 2, 14.5f))));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(0.5f, 0.5f, 0.5f));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(-5, -5, 14))));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(2, 2, 2));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ Quaternion orientation = new Quaternion(0.5f, 0.2f, 0.4f, 1);
+ orientation = orientation.normalize();
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(15, 15, 14), orientation)));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(4, 4, 4));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ final Entity localBox = new Entity(this.env);
+ final Quaternion orientation = new Quaternion(0.3f, 1.3f, 0.4f, 1);
+ //orientation.normalize();
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(2, -2, 14.2f), orientation)));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ // TODO: physics2.setAngularReactionEnable(false);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(0.5f, 0.5f, 0.5f));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ {
+ // this is the floor
+ final Entity localBox = new Entity(this.env);
+ Quaternion orientation = new Quaternion(0, 0, 0, 1);
+ orientation = orientation.normalize();
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/dirt.png", "loxelEngine")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0.0f), orientation)));
+ final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
+ physics2.setBodyType(PhysicBodyType.BODY_STATIC);
+ final PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(20.0f, 20.0f, 0.5f));
+ box2.setOrigin(new Vector3f(0, 0, 0));
+ box2.setMass(0);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ this.env.addEntity(localBox);
+ }
+ // {
+ // // add a cube to test collision ...
+ // Entity localBox = new Entity(this.env);
+ // relativeTestPos = new ComponentPosition(new Transform3D(new Vector3f(0,0,14),new Quaternion(0.5f,0.2f,0.4f,1)));
+ // localBox.addComponent(relativeTestPos);
+ //// localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ //// localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ //// localBox.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+ //// localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ //// new Uri("DATA", "basic.vert"),
+ //// new Uri("DATA", "basic.frag")));
+ // ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(true);
+ // boxTest = new Box();
+ // boxTest.setSize(new Vector3f(1,1,1));
+ // boxTest.setOrigin(new Vector3f(0,0,0));
+ // boxTest.setMass(1);
+ // physics2.addShape(boxTest);
+ // localBox.addComponent(physics2);
+ // env.addEntity(localBox);
+ // }
+ // {
+ // Entity localBox = new Entity(this.env);
+ // localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0,0,14))));
+ // localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ // localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png", "loxelEngine")));
+ // localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ // new Uri("DATA", "basic.vert"),
+ // new Uri("DATA", "basic.frag")));
+ // env.addEntity(localBox);
+ // }
+
+ final Entity gird = new Entity(this.env);
+ gird.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0))));
+ gird.addComponent(new ComponentStaticMesh(MeshGenerator.createGrid(5)));
+ gird.addComponent(new ComponentRenderColoredStaticMesh(new Uri("DATA", "wireColor.vert", "ege"), new Uri("DATA", "wireColor.frag", "ege")));
+ this.env.addEntity(gird);
+
+ final Entity player = new Entity(this.env);
+ if (false) {
+ final Transform3D playerTransform = new Transform3D(new Vector3f(0, -5, 1));
+ //this.objectPosition = new ComponentPositionPlayer();
+ //player.addComponent(this.objectPosition);
+ this.objectPlayer = new ComponentPlayer();
+ player.addComponent(this.objectPlayer);
+ player.addComponent(new ComponentMaterial(new Material()));
+ //player.addComponent(new ComponentStaticMesh(new Uri("RES", "person.obj")));
+ player.addComponent(new ComponentStaticMesh(new Uri("RES", "person_-yfw_zup.obj")));
+ player.addComponent(new ComponentTexture(new Uri("RES", "playerTexture.png")));
+ player.addComponent(new ComponentRenderTexturedMaterialsStaticMesh(new Uri("DATA", "basicMaterial.vert", "loxelEngine"), new Uri("DATA", "basicMaterial.frag", "loxelEngine"),
+ (EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
+ player.addComponent(new ComponentPosition(playerTransform));
+ final ComponentPhysicsPerso physics = new ComponentPhysicsPerso(this.env);
+ physics.setBodyType(PhysicBodyType.BODY_DYNAMIC);
+ //physics.setAngularReactionEnable(false);
+ //physics.setSleepingEnable(false);
+ final PhysicBox box = new PhysicBox();
+ box.setSize(new Vector3f(0.3f, 0.3f, 0.9f));
+ box.setOrigin(new Vector3f(0, 0, 0.9f));
+ box.setMass(1);
+ physics.addShape(box);
+ player.addComponent(physics);
+ this.env.addEntity(player);
+ } else {
+ final Transform3D playerTransform = new Transform3D(new Vector3f(0, -5, 0));
+ this.objectPosition = new ComponentPositionPlayer();
+ player.addComponent(this.objectPosition);
+ this.objectPlayer = new ComponentPlayer();
+ player.addComponent(this.objectPlayer);
+ player.addComponent(new ComponentMaterial(new Material()));
+ //player.addComponent(new ComponentStaticMesh(new Uri("RES", "person.obj")));
+ player.addComponent(new ComponentStaticMesh(new Uri("RES", "person_-yfw_zup.obj")));
+ player.addComponent(new ComponentTexture(new Uri("RES", "playerTexture.png")));
+ player.addComponent(new ComponentRenderTexturedMaterialsStaticMesh(new Uri("DATA", "basicMaterial.vert", "loxelEngine"), new Uri("DATA", "basicMaterial.frag", "loxelEngine"),
+ (EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
+ this.env.addEntity(player);
+ }
+ final Camera mainView = new Camera();
+ this.env.addCamera("default", mainView);
+ mainView.setPitch((float) Math.PI * -0.25f);
+ mainView.setPosition(new Vector3f(0, -5, 5));
+
+ this.simpleControl = new ControlCameraPlayer(mainView, player);
+ this.env.addControlInterface(this.simpleControl);
+
+ // start the engine.
+ this.env.setPropertyStatus(GameStatus.gameStart);
+
+ this.basicRotation = Quaternion.fromEulerAngles(new Vector3f(0.005f, 0.005f, 0.01f));
+ this.basicRotation2 = Quaternion.fromEulerAngles(new Vector3f(0.003f, 0.01f, 0.001f));
+
+ final Engine tmpEngine = this.env.getEngine("physics");
+ if (tmpEngine != null) {
+ final EnginePhysics physicsEngine = (EnginePhysics) tmpEngine;
+ //Disable gravity for test ...
+ physicsEngine.setGravity(new Vector3f(0.0f, 0.0f, -9.0f));
+ }
+
+ // ready to let Gale & Ege manage the display
+ Log.info("==> Init APPL (END)");
+ }
+
+ @Override
+ public void onDraw(final GaleContext context) {
+ //Log.info("==> appl Draw ...");
+ final Vector2f size = getSize();
+ // Store openGl context.
+ OpenGL.push();
+ // set projection matrix:
+ final Matrix4f tmpProjection = Matrix4f.createMatrixPerspective(3.14f * 0.5f, getAspectRatio(), 0.1f, 50000);
+ OpenGL.setMatrix(tmpProjection);
+
+ // set the basic openGL view port: (Draw in all the windows...)
+ OpenGL.setViewPort(new Vector2f(0, 0), size);
+
+ // clear background
+ final Color bgColor = new Color(0.18f, 0.43f, 0.95f, 1.0f);
+ OpenGL.clearColor(bgColor);
+ // real clear request:
+ OpenGL.clear(OpenGL.ClearFlag.clearFlag_colorBuffer);
+ OpenGL.clear(OpenGL.ClearFlag.clearFlag_depthBuffer);
+ OpenGL.enable(Flag.flag_depthTest);
+
+ //Log.info("==> appl Draw ...");
+ this.env.render(20, "default");
+ if (this.debugDrawProperty == null) {
+ this.debugDrawProperty = ResourceColored3DObject.create();
+ }
+ // now render the point test collision ...
+ for (int iii = 0; iii < LoxelApplicationPerso.testPoints.size(); iii++) {
+ final Vector3f elem = LoxelApplicationPerso.testPoints.get(iii);
+ final boolean collide = LoxelApplicationPerso.testPointsCollide.get(iii);
+ if (collide) {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.1f, 0.1f, 0.1f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(1, 0, 0, 1));
+ } else if (iii == 0) {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(0, 1, 0, 1));
+ } else if (iii == 7) {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(1, 1, 0, 1));
+ } else {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.1f, 0.1f, 0.1f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(1, 1, 1, 1));
+ }
+ }
+ for (int iii = 0; iii < LoxelApplicationPerso.testPointsBox.size(); iii++) {
+ final Vector3f elem = LoxelApplicationPerso.testPointsBox.get(iii);
+ if (iii == 0) {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(0, 1, 0, 1));
+ } else if (iii == 7) {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(1, 1, 0, 1));
+ } else {
+ this.debugDrawProperty.drawSquare(new Vector3f(0.1f, 0.1f, 0.1f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(new Vector3f(elem.x(), elem.y(), elem.z() + 14))),
+ new Color(0, 0, 1, 1));
+ }
+ }
+
+ if (LoxelApplicationPerso.testRpos != null) {
+ //debugDrawProperty.drawSquare(box2HalfSize, testQTransfert.getMatrix4().multiplyNew(Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z+14))), new Color(0,1,0,0.5f));
+ //Matrix4f transformation = Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z)).multiply(testQTransfert.getMatrix4()).multiply(Matrix4f.createMatrixTranslate(new Vector3f(0,0,14)));
+ //Matrix4f transformation = testQTransfert.getMatrix4().multiply(Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z))).multiply(Matrix4f.createMatrixTranslate(new Vector3f(0,0,14)));
+ //Matrix4f transformation = testQTransfert.getMatrix4().multiply(Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z))).multiply(Matrix4f.createMatrixTranslate(new Vector3f(0,0,14)));
+ final Matrix4f transformation = Matrix4f.createMatrixTranslate(new Vector3f(LoxelApplicationPerso.testRpos.x(), LoxelApplicationPerso.testRpos.y(), LoxelApplicationPerso.testRpos.z()))
+ .multiply(Matrix4f.createMatrixTranslate(new Vector3f(0, 0, 14))).multiply(LoxelApplicationPerso.testQTransfert.getMatrix4());
+ // OK sans la box1 orientation ...
+ //Matrix4f transformation = Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z)).multiply(testQTransfert.getMatrix4()).multiply(Matrix4f.createMatrixTranslate(new Vector3f(0,0,14)));
+ //Matrix4f transformation = Matrix4f.createMatrixTranslate(new Vector3f(testRpos.x,testRpos.y,testRpos.z)).multiply(testQTransfert.getMatrix4()).multiply(Matrix4f.createMatrixTranslate(new Vector3f(0,0,14)));
+ this.debugDrawProperty.drawSquare(LoxelApplicationPerso.box2HalfSize, transformation, new Color(0, 1, 0, 0.5f));
+ this.debugDrawProperty.drawSquare(LoxelApplicationPerso.box1HalfSize, Matrix4f.createMatrixTranslate(new Vector3f(0, 0, 14)), new Color(0, 0, 1, 0.5f));
+ }
+
+ // Restore context of matrix
+ OpenGL.pop();
+ }
+
+ @Override
+ public void onKeyboard(final KeySpecial special, final KeyKeyboard type, final Character value, final KeyStatus state) {
+ if (type == KeyKeyboard.F1) {
+ Gale.getContext().grabPointerEvents(false, new Vector2f(0, 0));
+ }
+ if (type == KeyKeyboard.F2) {
+ Gale.getContext().grabPointerEvents(true, new Vector2f(0, 0));
+ }
+ if (type == KeyKeyboard.F12) {
+ Gale.getContext().setFullScreen(!Gale.getContext().getFullScreen());
+ }
+ this.env.onKeyboard(special, type, value, state);
+ }
+
+ @Override
+ public void onPointer(final KeySpecial special, final KeyType type, final int pointerID, final Vector2f pos, final KeyStatus state) {
+ this.env.onPointer(special, type, pointerID, pos, state);
+ }
+
+ @Override
+ public void onRegenerateDisplay(final GaleContext context) {
+ //Log.verbose("Regenerate Gale Application");
+ this.angleLight += 0.01;
+ this.lightPosition.setTransform(this.lightPosition.getTransform()
+ .withPosition(new Vector3f(5 + (float) Math.cos(this.angleLight) * 7.0f, 5 + (float) Math.sin(this.angleLight) * 7.0f, this.lightPosition.getTransform().getPosition().z())));
+ this.env.periodicCall();
+ markDrawingIsNeeded();
+ }
+}
diff --git a/samples/src/sample/atriasoft/ege/loxelEnginePerso/MainLoxelEnginePerso.java b/samples/src/sample/atriasoft/ege/loxelEnginePerso/MainLoxelEnginePerso.java
new file mode 100644
index 0000000..0513658
--- /dev/null
+++ b/samples/src/sample/atriasoft/ege/loxelEnginePerso/MainLoxelEnginePerso.java
@@ -0,0 +1,19 @@
+package sample.atriasoft.ege.loxelEnginePerso;
+
+import org.atriasoft.ege.Ege;
+import org.atriasoft.etk.Uri;
+import org.atriasoft.gale.Gale;
+
+import sample.atriasoft.ege.collisiontest.MainCollisionTest;
+
+public class MainLoxelEnginePerso {
+ public static void main(final String[] args) {
+ Gale.init();
+ Ege.init();
+ Uri.setGroup("DATA", "data/");
+ Uri.setGroup("RES", "res");
+ Uri.addLibrary("loxelEngine", MainLoxelEnginePerso.class, "testDataLoxelEngine/");
+ Uri.setApplication(MainLoxelEnginePerso.class, "");
+ Gale.run(new LoxelApplicationPerso(), args);
+ }
+}
diff --git a/src/module-info.java b/src/module-info.java
index 2ff9ef9..341c3ed 100644
--- a/src/module-info.java
+++ b/src/module-info.java
@@ -11,6 +11,7 @@ open module org.atriasoft.ege {
exports org.atriasoft.ege.map;
exports org.atriasoft.ege.physics.shape;
exports org.atriasoft.ege.tools;
+ exports org.atriasoft.phyligram;
exports entities;
exports guis;
exports models;
diff --git a/src/org/atriasoft/ege/Environement.java b/src/org/atriasoft/ege/Environement.java
index 1c4f6fd..5feee6f 100644
--- a/src/org/atriasoft/ege/Environement.java
+++ b/src/org/atriasoft/ege/Environement.java
@@ -8,12 +8,14 @@ import java.util.List;
import java.util.Map;
import org.atriasoft.ege.camera.Camera;
+import org.atriasoft.ege.components.ComponentPhysicsPerso;
import org.atriasoft.ege.engines.EngineAI;
import org.atriasoft.ege.engines.EngineDynamicMeshs;
import org.atriasoft.ege.engines.EngineGravity;
import org.atriasoft.ege.engines.EngineLight;
import org.atriasoft.ege.engines.EngineParticle;
import org.atriasoft.ege.engines.EnginePhysics;
+import org.atriasoft.ege.engines.EnginePhysicsPerso;
import org.atriasoft.ege.engines.EnginePlayer;
import org.atriasoft.ege.engines.EngineRender;
import org.atriasoft.ege.internal.Log;
@@ -72,6 +74,7 @@ public class Environement {
addEngine(new EngineDynamicMeshs(this));
addEngine(new EngineRender(this));
addEngine(new EnginePhysics(this));
+ addEngine(new EnginePhysicsPerso(this));
addEngine(new EngineParticle(this));
addEngine(new EngineLight(this));
startClock = Clock.systemUTC();
diff --git a/src/org/atriasoft/ege/components/ComponentLight.java b/src/org/atriasoft/ege/components/ComponentLight.java
index b774397..896cd5b 100644
--- a/src/org/atriasoft/ege/components/ComponentLight.java
+++ b/src/org/atriasoft/ege/components/ComponentLight.java
@@ -3,6 +3,7 @@ package org.atriasoft.ege.components;
import org.atriasoft.ege.Component;
import org.atriasoft.ege.Light;
import org.atriasoft.ege.components.part.PositionningInterface;
+import org.atriasoft.ege.internal.Log;
import org.atriasoft.etk.math.Vector3f;
public class ComponentLight extends Component {
@@ -21,7 +22,11 @@ public class ComponentLight extends Component {
@Override
public void addFriendComponent(final Component component) {
if (component.getType().contentEquals("position") || component.getType().contentEquals("physics")) {
- this.position = (PositionningInterface)component;
+ if (component instanceof PositionningInterface tmp) {
+ this.position = tmp;
+ } else {
+ Log.error("component: " + component.getClass().getCanonicalName() + " is not an instance of " + PositionningInterface.class.getCanonicalName());
+ }
}
}
diff --git a/src/org/atriasoft/ege/components/ComponentPhysics.java b/src/org/atriasoft/ege/components/ComponentPhysics.java
index f2b95bd..716922f 100644
--- a/src/org/atriasoft/ege/components/ComponentPhysics.java
+++ b/src/org/atriasoft/ege/components/ComponentPhysics.java
@@ -7,6 +7,7 @@ import org.atriasoft.ege.Component;
import org.atriasoft.ege.Environement;
import org.atriasoft.ege.Signal;
import org.atriasoft.ege.camera.Camera;
+import org.atriasoft.ege.components.part.PositionningInterface;
import org.atriasoft.ege.engines.EnginePhysics;
import org.atriasoft.ege.internal.Log;
import org.atriasoft.ege.physics.shape.Box;
@@ -38,8 +39,8 @@ import org.atriasoft.etk.math.Transform3D;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.gale.resource.ResourceColored3DObject;
-public class ComponentPhysics extends Component {
- public Signal signalPosition = new Signal<>();;
+public class ComponentPhysics extends Component implements PositionningInterface {
+ public Signal signalPosition = new Signal<>();
protected Transform3D lastTransformEmit;
protected EnginePhysics engine;
protected RigidBody rigidBody;
@@ -232,7 +233,7 @@ public class ComponentPhysics extends Component {
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
transformationMatrixLocal = transformationMatrixLocal.transpose();
- transformationMatrixLocal = transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
+ transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
_draw.drawSquare(tmpElement.getSize(), transformationMatrixLocal, tmpColor);
} else if (it.isCylinder()) {
Log.debug(" Cylinder");
@@ -241,7 +242,7 @@ public class ComponentPhysics extends Component {
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
transformationMatrixLocal = transformationMatrixLocal.transpose();
- transformationMatrixLocal = transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
+ transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
_draw.drawCylinder(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
} else if (it.isCapsule()) {
Log.debug(" Capsule");
@@ -250,7 +251,7 @@ public class ComponentPhysics extends Component {
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
transformationMatrixLocal = transformationMatrixLocal.transpose();
- transformationMatrixLocal = transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
+ transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
_draw.drawCapsule(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
} else if (it.isCone()) {
Log.debug(" Cone");
@@ -259,7 +260,7 @@ public class ComponentPhysics extends Component {
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
transformationMatrixLocal = transformationMatrixLocal.transpose();
- transformationMatrixLocal = transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
+ transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
_draw.drawCone(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
} else if (it.isSphere()) {
@@ -269,7 +270,7 @@ public class ComponentPhysics extends Component {
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
transformationMatrixLocal = transformationMatrixLocal.transpose();
- transformationMatrixLocal = transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
+ transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
_draw.drawSphere(tmpElement.getRadius(), 10, 10, transformationMatrixLocal, tmpColor);
} else if (it.isConcave()) {
@@ -453,6 +454,7 @@ public class ComponentPhysics extends Component {
* set a new transformation
* @return Transformation of the position
*/
+ @Override
public Transform3D getTransform() {
if (this.rigidBody == null) {
return Transform3D.IDENTITY;
diff --git a/src/org/atriasoft/ege/components/ComponentPhysicsPerso.java b/src/org/atriasoft/ege/components/ComponentPhysicsPerso.java
new file mode 100644
index 0000000..4df62e6
--- /dev/null
+++ b/src/org/atriasoft/ege/components/ComponentPhysicsPerso.java
@@ -0,0 +1,334 @@
+package org.atriasoft.ege.components;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.atriasoft.etk.Color;
+import org.atriasoft.etk.math.Matrix4f;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+import org.atriasoft.ege.internal.Log;
+import org.atriasoft.ege.Component;
+import org.atriasoft.ege.Environement;
+import org.atriasoft.ege.engines.EngineGravity;
+import org.atriasoft.ege.engines.EnginePhysics;
+import org.atriasoft.ege.engines.EnginePhysicsPerso;
+import org.atriasoft.phyligram.PhysicBox;
+import org.atriasoft.phyligram.PhysicCollisionAABB;
+import org.atriasoft.phyligram.PhysicMapVoxel;
+import org.atriasoft.phyligram.PhysicShape;
+import org.atriasoft.phyligram.PhysicSphere;
+import org.atriasoft.phyligram.ToolCollisionOBBWithOBB;
+
+
+public class ComponentPhysicsPerso extends Component {
+ private PhysicCollisionAABB aabb;
+ private List aabbIntersection = new ArrayList();
+ private List narrowIntersection = new ArrayList();
+ private List shapes = new ArrayList();
+ private ComponentPosition position;
+ private boolean staticObject = false;
+ private boolean manageGravity = false;
+ public static float globalMaxSpeed = Float.MAX_VALUE;
+ private float maxSpeed = globalMaxSpeed;
+ // current speed of the object
+ private Vector3f speed = new Vector3f(0,0,0);
+ // current acceleration of the object
+ private Vector3f acceleration = new Vector3f(0,0,0);
+ // Applied static force on it
+ private Vector3f staticForce = new Vector3f(0,0,0);
+ // Apply dynamic force on it
+ private Vector3f dynamicForce = new Vector3f(0,0,0);
+ private EnginePhysicsPerso engine;
+ private PhysicBodyType bodyType;
+
+
+ @Override
+ public String getType() {
+ return EnginePhysicsPerso.ENGINE_NAME;
+ }
+
+ public ComponentPhysicsPerso(final Environement _env) {
+ this.engine = (EnginePhysicsPerso) _env.getEngine(getType());
+ }
+
+ @Override
+ public void addFriendComponent(Component component) {
+ if (component.getType().contentEquals("position")) {
+ if (component instanceof ComponentPosition tmp) {
+ position = tmp;
+ } else {
+ Log.error("Not manage position model...");
+ }
+ }
+ }
+ @Override
+ public void removeFriendComponent(Component component) {
+ // nothing to do.
+ }
+
+ public void updateAABB() {
+ if (position == null) {
+ Log.info("No position in Entity ");
+ return;
+ }
+ // TODO Add a flag to check if it is needed to update the AABB...
+ PhysicCollisionAABB aabbNew = PhysicCollisionAABB.beforeCalculated();
+ for (PhysicShape shape : shapes) {
+ shape.updateAABB(position.getTransform(), aabbNew);
+ }
+ aabb = aabbNew;
+ }
+
+ public PhysicCollisionAABB getAABB() {
+ return aabb;
+ }
+
+ public void updateForNarrowCollision() {
+ narrowIntersection.clear();
+ if (aabbIntersection.size() == 0) {
+ return;
+ }
+ if (position == null) {
+ Log.info("No position in Entity ");
+ return;
+ }
+ for (PhysicShape shape : shapes) {
+ shape.updateForNarrowCollision(position.getTransform());
+ }
+ }
+ public boolean isNarrowCollide() {
+ if (narrowIntersection.size() == 0) {
+ return false;
+ }
+ return true;
+ }
+ public boolean checkNarrowCollision() {
+ if (this.staticObject == true) {
+ return false;
+ }
+ for (ComponentPhysicsPerso elem : aabbIntersection) {
+ boolean collide = false;
+ for (PhysicShape shapeCurrent : shapes) {
+ if (elem.checkCollide(shapeCurrent) == true) {
+ collide = true;
+ break;
+ }
+ }
+ if (collide == true) {
+ narrowIntersection.add(elem);
+ elem.narrowIntersection.add(this);
+ }
+ }
+ return isNarrowCollide();
+ }
+ public void narrowCollisionCreateContactAndForce() {
+ if (narrowIntersection.size() == 0) {
+ return;
+ }
+ for (ComponentPhysicsPerso elem : narrowIntersection) {
+ for (PhysicShape shapeCurrent : this.shapes) {
+ //TODO Do a better method we do this many times ...
+ if (elem.checkCollide(shapeCurrent) == false) {
+ continue;
+ }
+ elem.getCollidePoints(shapeCurrent, this.staticObject);
+ }
+ }
+ }
+
+ private boolean checkCollide(PhysicShape shapeCurrent) {
+ if (shapeCurrent instanceof PhysicBox) {
+ PhysicBox shape111 = (PhysicBox)shapeCurrent;
+ for (PhysicShape shape : shapes) {
+ if (shape instanceof PhysicBox) {
+ PhysicBox shape222 = (PhysicBox)shape;
+ if (ToolCollisionOBBWithOBB.testCollide(shape111, shape222) == true) {
+ return true;
+ }
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else if (shapeCurrent instanceof PhysicSphere) {
+ for (PhysicShape shape : shapes) {
+ if (shape instanceof PhysicBox) {
+
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else if (shapeCurrent instanceof PhysicMapVoxel) {
+ for (PhysicShape shape : shapes) {
+ if (shape instanceof PhysicBox) {
+
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else {
+ Log.error("Not manage collision model... " + shapeCurrent);
+ }
+ return false;
+ }
+ private void getCollidePoints(PhysicShape shapeCurrent, boolean isStatic) {
+ if (shapeCurrent instanceof PhysicBox) {
+ PhysicBox shape111 = (PhysicBox)shapeCurrent;
+ for (PhysicShape shape : this.shapes) {
+ if (shape instanceof PhysicBox) {
+ PhysicBox shape222 = (PhysicBox)shape;
+ ToolCollisionOBBWithOBB.getCollidePoints(shape111, isStatic, shape222, this.staticObject);
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else if (shapeCurrent instanceof PhysicSphere) {
+ for (PhysicShape shape : this.shapes) {
+ if (shape instanceof PhysicBox) {
+
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else if (shapeCurrent instanceof PhysicMapVoxel) {
+ for (PhysicShape shape : this.shapes) {
+ if (shape instanceof PhysicBox) {
+
+ } else if (shape instanceof PhysicSphere) {
+
+ } else if (shape instanceof PhysicMapVoxel) {
+
+ } else {
+ Log.error("Not manage collision model... " + shape);
+ }
+ }
+ } else {
+ Log.error("Not manage collision model... " + shapeCurrent);
+ }
+ return;
+ }
+
+ public void applyForces(float timeStep, EngineGravity gravity) {
+ // get the gravity at the specific position...
+ Vector3f gravityForce;
+ if (manageGravity == true) {
+ gravityForce = gravity.getGravityAtPosition(position.getTransform().getPosition()).multiply(timeStep);
+ } else {
+ gravityForce = new Vector3f(0,0,0);
+ }
+ // apply this force on the Object
+ Log.info("apply gravity: " + gravityForce);
+ // relative to the object
+ Vector3f staticForce = this.staticForce.multiply(timeStep);
+ float globalMass = 0;
+ for (PhysicShape shape : shapes) {
+ globalMass += shape.getMass();
+ }
+ // note the acceleration is not real, it depend on the current delta time...
+ this.acceleration = gravityForce.add(this.position.getTransform().getOrientation().multiply(staticForce)).add(this.position.getTransform().getOrientation().multiply(dynamicForce)).multiply(globalMass);
+ this.dynamicForce = new Vector3f(0,0,0);
+ this.speed.add(this.acceleration);
+ limitWithMaxSpeed();
+ Log.info("apply acceleration: " + this.acceleration);
+ Log.info("apply speed: " + this.speed);
+ this.position.getTransform().getPosition().add(this.speed.multiply(timeStep));
+ }
+
+ public void renderDebug(ResourceColored3DObject debugDrawProperty) {
+ Color displayColor;
+ if (this.aabbIntersection.size() == 0) {
+ displayColor = new Color(1,1,1,1);
+ } else {
+ if (this.narrowIntersection.size() == 0) {
+ displayColor = new Color(1,1,0,1);
+ } else {
+ displayColor = new Color(1,0,0,1);
+ }
+ }
+ if (aabb != null) {
+ debugDrawProperty.drawCubeLine(aabb.getMin(), aabb.getMax(), displayColor, Matrix4f.IDENTITY, true, true);
+ //debugDrawProperty.drawCubeLine(new Vector3f(0,0,0), new Vector3f(32,32,32), new Color(1,0,1,1), Matrix4f.identity(), true, true);
+ } else {
+ Log.error("no AABB");
+ }
+ for (PhysicShape shape : shapes) {
+ shape.renderDebug(position.getTransform(), debugDrawProperty);
+ }
+ }
+ public void addShape(PhysicShape shape) {
+ shapes.add(shape);
+ }
+ public void clearShape() {
+ shapes.clear();
+ }
+ public boolean isManageGravity() {
+ return manageGravity;
+ }
+ public void setManageGravity(boolean manageGravity) {
+ this.manageGravity = manageGravity;
+ }
+ private void limitWithMaxSpeed() {
+ if (this.speed.length2() > this.maxSpeed*this.maxSpeed) {
+ this.speed.safeNormalize().multiply(this.maxSpeed);
+ }
+ }
+ public float getMaxSpeed() {
+ return maxSpeed;
+ }
+
+ public void setMaxSpeed(float maxSpeed) {
+ this.maxSpeed = maxSpeed;
+ }
+
+ public void clearAABBIntersection() {
+ this.aabbIntersection.clear();
+ }
+ public void addIntersection(ComponentPhysicsPerso component) {
+ // do not add multiple times
+ for (ComponentPhysicsPerso elem : this.aabbIntersection) {
+ if (elem == component) {
+ return;
+ }
+ }
+ this.aabbIntersection.add(component);
+ }
+ public List getAabbIntersection() {
+ return aabbIntersection;
+ }
+
+ public boolean isStaticObject() {
+ return staticObject;
+ }
+
+ public void setStaticObject(boolean staticObject) {
+ this.staticObject = staticObject;
+ }
+
+ public PhysicBodyType getBodyType() {
+ return bodyType;
+ }
+
+ public void setBodyType(PhysicBodyType bodyType) {
+ this.bodyType = bodyType;
+ }
+}
diff --git a/src/org/atriasoft/ege/components/ComponentPlayer.java b/src/org/atriasoft/ege/components/ComponentPlayer.java
index 4f5ae32..58edbff 100644
--- a/src/org/atriasoft/ege/components/ComponentPlayer.java
+++ b/src/org/atriasoft/ege/components/ComponentPlayer.java
@@ -4,7 +4,7 @@ import org.atriasoft.ege.Component;
import org.atriasoft.ege.engines.EnginePlayer;
public class ComponentPlayer extends Component {
- private float runSpeed = 35;
+ private float runSpeed = 20;
private float strafSpeed = 25;
private float turnSpeed = 0.45f;
private float jumpPower = 30;
diff --git a/src/org/atriasoft/ege/components/ComponentPosition.java b/src/org/atriasoft/ege/components/ComponentPosition.java
index 6647a50..2c9fa08 100644
--- a/src/org/atriasoft/ege/components/ComponentPosition.java
+++ b/src/org/atriasoft/ege/components/ComponentPosition.java
@@ -27,8 +27,8 @@ public class ComponentPosition extends Component implements PositionningInterfac
@Override
public void addFriendComponent(final Component component) {
- if (component.getType().contains("physics")) {
- Log.critical("Can not add a 'physic' component and a 'position' component ... ==> incompatible");
+ if (component.getType().equals("physics")) {
+ Log.critical("Can not add a 'physics' component and a 'position' component ... ==> incompatible");
}
}
diff --git a/src/org/atriasoft/ege/engines/EnginePhysicsPerso.java b/src/org/atriasoft/ege/engines/EnginePhysicsPerso.java
new file mode 100644
index 0000000..ceae58f
--- /dev/null
+++ b/src/org/atriasoft/ege/engines/EnginePhysicsPerso.java
@@ -0,0 +1,152 @@
+package org.atriasoft.ege.engines;
+
+import java.util.Vector;
+
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+import org.atriasoft.ege.internal.Log;
+import org.atriasoft.ege.Component;
+import org.atriasoft.ege.Engine;
+import org.atriasoft.ege.Environement;
+import org.atriasoft.ege.camera.Camera;
+import org.atriasoft.ege.components.ComponentPhysicsPerso;
+import org.atriasoft.phyligram.PhysicCollisionAABB;
+
+public class EnginePhysicsPerso extends Engine {
+ public static final String ENGINE_NAME = "physicsPerso";
+ private float accumulator = 0;
+ private static final float TIME_STEP = 0.005f;
+ private EngineGravity gravity;
+ protected EnginePhysicsPerso engine;
+ private Vector components = new Vector();
+ private ResourceColored3DObject debugDrawProperty = ResourceColored3DObject.create();
+
+ public EnginePhysicsPerso(Environement env) {
+ super(env);
+ this.gravity = (EngineGravity)env.getEngine("gravity");
+ if (this.gravity == null) {
+ Log.critical("Must initialyse Gravity before physics...");
+ }
+ }
+
+ @Override
+ public void componentRemove(Component ref) {
+ components.remove(ref);
+ }
+
+ @Override
+ public void componentAdd(Component ref) {
+ if (ref instanceof ComponentPhysicsPerso == false) {
+ return;
+ }
+ components.add((ComponentPhysicsPerso)ref);
+ }
+
+ @Override
+ public void update(long deltaMili) {
+ // Add the time difference in the accumulator
+ accumulator += (float)deltaMili*0.0001f;
+ // While there is enough accumulated time to take one or several physics steps
+ while (accumulator >= TIME_STEP) {
+ Log.info("update physic ... " + accumulator);
+ //applyForces(TIME_STEP);
+ updateAABB(TIME_STEP);
+ updateCollisionsAABB(TIME_STEP);
+ updateCollisionsNarrowPhase(TIME_STEP);
+ generateResultCollisionsForces(TIME_STEP);
+ // Decrease the accumulated time
+ accumulator -= TIME_STEP;
+ }
+
+ }
+
+ private void applyForces(float timeStep) {
+ for (ComponentPhysicsPerso it: components) {
+ it.applyForces(TIME_STEP, gravity);
+ }
+ }
+ /**
+ * Collision detection STEP 1: Upadte the AABB positioning of each elements
+ * @param timeStep Delta time since the last check
+ */
+ private void updateAABB(float timeStep) {
+ for (ComponentPhysicsPerso it: components) {
+ it.updateAABB();
+ }
+ }
+ /**
+ * Collision Detection STEP 2: update the list of each element that collide together in the AABB Boxs (update is done between each boxes)
+ * @param timeStep Delta time since the last check
+ */
+ private void updateCollisionsAABB(float timeStep) {
+ // clear all object intersection
+ for (ComponentPhysicsPerso it: components) {
+ it.clearAABBIntersection();
+ }
+ // update the current object intersection...
+ for (int iii=0; iii< components.size(); iii++) {
+ ComponentPhysicsPerso current = components.get(iii);
+ PhysicCollisionAABB currentAABB = current.getAABB();
+ for (int jjj=iii+1; jjj< components.size(); jjj++) {
+ ComponentPhysicsPerso remote = components.get(jjj);
+ if (currentAABB.intersect(components.get(jjj).getAABB()) == true) {
+ current.addIntersection(remote);
+ remote.addIntersection(current);
+ }
+ }
+ }
+ }
+ /**
+ * Collision Detection STEP 3: Narrow phase: process the collision between every OBB boxes (or other..)
+ * @param timeStep Delta time since the last check
+ */
+ private void updateCollisionsNarrowPhase(float timeStep) {
+ // clear all object intersection
+ for (ComponentPhysicsPerso it: components) {
+ it.updateForNarrowCollision();
+ }
+ // check for every component if the narrow collision is available.
+ for (int iii=0; iii< components.size(); iii++) {
+ ComponentPhysicsPerso current = components.get(iii);
+ boolean collide = current.checkNarrowCollision();
+
+ }
+ // update the force of collision available.
+ for (int iii=0; iii< components.size(); iii++) {
+ ComponentPhysicsPerso current = components.get(iii);
+ current.narrowCollisionCreateContactAndForce();
+ }
+ }
+ /**
+ * Collision Detection STEP 4: apply all calculated forces (with containts)
+ * @param timeStep
+ */
+ private void generateResultCollisionsForces(float timeStep) {
+
+ }
+
+ @Override
+ public void render(long deltaMili, Camera camera) {
+ // TODO Auto-generated method stub
+ for (ComponentPhysicsPerso it: this.components) {
+ //Log.info("Render " + it);
+ it.renderDebug(debugDrawProperty);
+ }
+ //debugDrawProperty.drawCone(2, 5, 9, 12, Matrix4f.identity(), new Color(1,1,0,1));
+ //debugDrawProperty.drawSquare(new Vector3f(1,1,1), Matrix4f.identity(), new Color(1,1,0,1));
+ //debugDrawProperty.drawCubeLine(new Vector3f(1,1,1), new Vector3f(5,5,5), new Color(1,0,1,1), Matrix4f.identity(), true, true);
+ //debugDrawProperty.drawCubeLine(new Vector3f(0,0,0), new Vector3f(32,32,32), new Color(1,0,1,1), Matrix4f.identity(), true, true);
+ }
+
+ @Override
+ public void renderDebug(long deltaMili, Camera camera) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getType() {
+ // TODO Auto-generated method stub
+ return ENGINE_NAME;
+ }
+
+}
diff --git a/src/org/atriasoft/ege/physics/shape/Shape.java b/src/org/atriasoft/ege/physics/shape/Shape.java
index a7e2cf0..6f33506 100644
--- a/src/org/atriasoft/ege/physics/shape/Shape.java
+++ b/src/org/atriasoft/ege/physics/shape/Shape.java
@@ -5,6 +5,7 @@
*/
package org.atriasoft.ege.physics.shape;
+import org.atriasoft.ege.internal.Log;
import org.atriasoft.etk.math.Quaternion;
import org.atriasoft.etk.math.Vector3f;
@@ -58,6 +59,7 @@ public class Shape {
};
public boolean parse(final String _line) {
+ Log.error("dfgdfg");
/*
if(strncmp(_line, "origin:", 7) == 0) {
sscanf(&_line[7], "%f %f %f", &m_origin.m_floats[0], &m_origin.m_floats[1], &m_origin.m_floats[2] );
diff --git a/src/org/atriasoft/phyligram/ColisionPoints.java b/src/org/atriasoft/phyligram/ColisionPoints.java
new file mode 100644
index 0000000..7c97d06
--- /dev/null
+++ b/src/org/atriasoft/phyligram/ColisionPoints.java
@@ -0,0 +1,13 @@
+package org.atriasoft.phyligram;
+
+import org.atriasoft.etk.math.Vector3f;
+
+public class ColisionPoints {
+ public Vector3f position;
+ public Vector3f force;
+
+ public ColisionPoints(Vector3f position, Vector3f force) {
+ this.position = position;
+ this.force = force;
+ }
+}
diff --git a/src/org/atriasoft/phyligram/Collision.java b/src/org/atriasoft/phyligram/Collision.java
new file mode 100644
index 0000000..6248da5
--- /dev/null
+++ b/src/org/atriasoft/phyligram/Collision.java
@@ -0,0 +1,17 @@
+package org.atriasoft.phyligram;
+
+public class Collision {
+ public final ColisionPoints[] colisionPointLocal;
+ public final PhysicShape shapeRemote;
+ public final ColisionPoints[] colisionPointRemote;
+ public final boolean staticRemote;
+ public Collision(ColisionPoints[] colisionPointLocal, PhysicShape shapeRemote,
+ ColisionPoints[] colisionPointRemote, boolean staticRemote) {
+ super();
+ this.colisionPointLocal = colisionPointLocal;
+ this.shapeRemote = shapeRemote;
+ this.colisionPointRemote = colisionPointRemote;
+ this.staticRemote = staticRemote;
+ }
+
+}
diff --git a/src/org/atriasoft/phyligram/DebugDisplay.java b/src/org/atriasoft/phyligram/DebugDisplay.java
new file mode 100644
index 0000000..abda111
--- /dev/null
+++ b/src/org/atriasoft/phyligram/DebugDisplay.java
@@ -0,0 +1,327 @@
+package org.atriasoft.phyligram;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.atriasoft.etk.Color;
+import org.atriasoft.etk.math.Matrix4f;
+import org.atriasoft.etk.math.Quaternion;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.backend3d.OpenGL;
+import org.atriasoft.gale.context.GaleContext;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+
+public class DebugDisplay {
+// public static ComponentPosition relativeTestPos;
+// public static PhysicBox boxTest;
+ public static List testPoints = new ArrayList();
+ public static List testPointsBox = new ArrayList();
+ public static List testPointsCollide = new ArrayList();
+ public static Vector3f testRpos;
+ public static Quaternion testQTransfert;
+ public static Vector3f box1HalfSize;
+ public static Vector3f box2HalfSize;
+ private ResourceColored3DObject debugDrawProperty;
+ public DebugDisplay(){
+
+ }
+ /*
+ @Override
+ public void onCreate(Context context) {
+ // set the system global max speed
+ ComponentPhysics.globalMaxSpeed = 3;
+ Gale.getContext().grabPointerEvents(true, new Vector2f(0,0));
+ env = new Environement();
+ this.canDraw = true;
+ setSize(new Vector2f(1500, 1500));
+ setTitle("Loxel sample");
+ map = new MapVoxel(this.env);
+// this.env.addEngine(map);
+// map.init();
+
+ // simple sun to have a global light ...
+ Entity globalGravity = new Entity(this.env);
+ globalGravity.addComponent(new ComponentGravityStatic(new Vector3f(0,0,-1)));
+ env.addEntity(globalGravity);
+
+ // simple sun to have a global light ...
+ Entity sun = new Entity(this.env);
+ sun.addComponent(new ComponentPosition(new Transform3D(new Vector3f(1000,1000,1000))));
+ sun.addComponent(new ComponentLightSun(new Light(new Vector3f(0.4f,0.4f,0.4f), new Vector3f(0,0,0), new Vector3f(0.8f,0,0))));
+ env.addEntity(sun);
+
+ // add a cube to show where in the light ...
+ Entity localLight = new Entity(this.env);
+ lightPosition = new ComponentPosition(new Transform3D(new Vector3f(-10,-10,17)));
+// localLight.addComponent(lightPosition);
+// localLight.addComponent(new ComponentStaticMesh(new Uri("RES", "cube.obj")));
+// localLight.addComponent(new ComponentTexture(new Uri("RES", "grass.png")));
+// localLight.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+// localLight.addComponent(new ComponentRenderTexturedStaticMesh(
+// new Uri("DATA", "basic.vert"),
+// new Uri("DATA", "basic.frag")));
+// env.addEntity(localLight);
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(-2,-2,14))));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(1,1,1));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0,4,12.5f))));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(1,1,1));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(-2,2,14.5f))));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(1,1,1));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(-5,-5,14))));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(4,4,4));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ Quaternion transform = new Quaternion(0.5f,0.2f,0.4f,1);
+ transform.normalize();
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(15,15,14), transform)));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(8,8,8));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ Quaternion transform = new Quaternion(0.3f,0.3f,0.4f,1);
+ transform.normalize();
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(2,-2,14.2f),transform)));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(1,1,1));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+ {
+ // add a cube to test collision ...
+ Entity localBox = new Entity(this.env);
+ Quaternion transform = new Quaternion(0,0,1,1);
+ transform.normalize();
+ localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(2,2,14.2f),transform)));
+ localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+ localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+ localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+ new Uri("DATA", "basic.vert"),
+ new Uri("DATA", "basic.frag")));
+ ComponentPhysics physics2 = new ComponentPhysics(true);
+ PhysicBox box2 = new PhysicBox();
+ box2.setSize(new Vector3f(1,1,1));
+ box2.setOrigin(new Vector3f(0,0,0));
+ box2.setMass(1);
+ physics2.addShape(box2);
+ localBox.addComponent(physics2);
+ env.addEntity(localBox);
+ }
+// {
+// // add a cube to test collision ...
+// Entity localBox = new Entity(this.env);
+// relativeTestPos = new ComponentPosition(new Transform3D(new Vector3f(0,0,14),new Quaternion(0.5f,0.2f,0.4f,1)));
+// localBox.addComponent(relativeTestPos);
+//// localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+//// localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+//// localBox.addComponent(new ComponentLight(new Light(new Vector3f(0,1,0), new Vector3f(0,0,0), new Vector3f(0.8f,0.03f,0.002f))));
+//// localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+//// new Uri("DATA", "basic.vert"),
+//// new Uri("DATA", "basic.frag")));
+// ComponentPhysics physics2 = new ComponentPhysics(true);
+// boxTest = new PhysicBox();
+// boxTest.setSize(new Vector3f(1,1,1));
+// boxTest.setOrigin(new Vector3f(0,0,0));
+// boxTest.setMass(1);
+// physics2.addShape(boxTest);
+// localBox.addComponent(physics2);
+// env.addEntity(localBox);
+// }
+// {
+// Entity localBox = new Entity(this.env);
+// localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0,0,14))));
+// localBox.addComponent(new ComponentStaticMesh(new Uri("RES", "cube-one.obj")));
+// localBox.addComponent(new ComponentTexture(new Uri("DATA", "blocks/clay.png")));
+// localBox.addComponent(new ComponentRenderTexturedStaticMesh(
+// new Uri("DATA", "basic.vert"),
+// new Uri("DATA", "basic.frag")));
+// env.addEntity(localBox);
+// }
+
+ Entity gird = new Entity(this.env);
+ gird.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0,0,13))));
+ gird.addComponent(new ComponentStaticMesh(MeshGenerator.createGrid(5)));
+ gird.addComponent(new ComponentRenderColoredStaticMesh(
+ new Uri("DATA_EGE", "wireColor.vert"),
+ new Uri("DATA_EGE", "wireColor.frag")));
+ env.addEntity(gird);
+
+ Entity player = new Entity(this.env);
+ objectPosition = new ComponentPositionPlayer(new Transform3D(new Vector3f(5,5,13)));
+ player.addComponent(objectPosition);
+ objectPlayer = new ComponentPlayer();
+ player.addComponent(objectPlayer);
+ player.addComponent(new ComponentMaterial(new Material()));
+ //player.addComponent(new ComponentStaticMesh(new Uri("RES", "person.obj")));
+ player.addComponent(new ComponentStaticMesh(new Uri("RES", "person_-yfw_zup.obj")));
+ player.addComponent(new ComponentTexture(new Uri("RES", "playerTexture.png")));
+ player.addComponent(new ComponentRenderTexturedMaterialsStaticMesh(
+ new Uri("DATA", "basicMaterial.vert"),
+ new Uri("DATA", "basicMaterial.frag"),
+ (EngineLight)env.getEngine(EngineLight.ENGINE_NAME)));
+ ComponentPhysics physics = new ComponentPhysics(true);
+ PhysicBox box = new PhysicBox();
+ box.setSize(new Vector3f(0.6f,0.6f,1.8f));
+ box.setOrigin(new Vector3f(0,0,0.9f));
+ box.setMass(1);
+ physics.addShape(box);
+ player.addComponent(physics);
+ env.addEntity(player);
+
+
+ Camera mainView = new Camera();
+ env.addCamera("default", mainView);
+ mainView.setPitch((float)Math.PI*-0.25f);
+ mainView.setPosition(new Vector3f(0,-5,5));
+
+ this.simpleControl = new ControlCameraPlayer(mainView, player);
+ env.addControlInterface(simpleControl);
+
+ // start the engine.
+ env.setPropertyStatus(GameStatus.gameStart);
+
+ basicRotation.setEulerAngles(new Vector3f(0.005f,0.005f,0.01f));
+ basicRotation2.setEulerAngles(new Vector3f(0.003f,0.01f,0.001f));
+ // ready to let Gale & Ege manage the display
+ Log.info("==> Init APPL (END)");
+ creationDone = true;
+ }
+ */
+
+ public void onDraw(GaleContext context) {
+ if (this.debugDrawProperty == null) {
+ debugDrawProperty = ResourceColored3DObject.create();
+ }
+ // now render the point test collision ...
+ for (int iii=0; iii tmp = new ArrayList<>();
+ tmp.add(new Vector3f(0,0,0));
+ tmp.add(force);
+ debugDrawProperty.drawLine(tmp, new Color(1, 0, 0, 1), Matrix4f.createMatrixTranslate(subPosition), true, false);
+ }
+
+ @Override
+ public void renderDebug(Transform3D transformGlobal, ResourceColored3DObject debugDrawProperty) {
+ debugDrawProperty.drawSquare(this.size.multiply(0.5f), this.transform.getOpenGLMatrix().multiply(transformGlobal.getOpenGLMatrix()), new Color(0, 1, 0, 0.25f));
+ Vector3f dimention = this.size.multiply(0.5f);
+ renderPoint2(new Vector3f(+dimention.x(), +dimention.y(), +dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(-dimention.x(), +dimention.y(), +dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(+dimention.x(), -dimention.y(), +dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(-dimention.x(), -dimention.y(), +dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(+dimention.x(), +dimention.y(), -dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(-dimention.x(), +dimention.y(), -dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint(new Vector3f(+dimention.x(), -dimention.y(), -dimention.z()), transformGlobal, debugDrawProperty);
+ renderPoint3(new Vector3f(-dimention.x(), -dimention.y(), -dimention.z()), transformGlobal, debugDrawProperty);
+ for (Collision elem: this.colisionPoints) {
+ if (elem != null) {
+ if (elem.colisionPointLocal == null) {
+ Log.error("colision point must be set !!!");
+ continue;
+ }
+ for (int iii = 0; iii < elem.colisionPointLocal.length; iii++) {
+ renderPoint4(elem.colisionPointLocal[iii].position, elem.colisionPointLocal[iii].force, debugDrawProperty);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/org/atriasoft/phyligram/PhysicCollisionAABB.java b/src/org/atriasoft/phyligram/PhysicCollisionAABB.java
new file mode 100644
index 0000000..1348025
--- /dev/null
+++ b/src/org/atriasoft/phyligram/PhysicCollisionAABB.java
@@ -0,0 +1,77 @@
+package org.atriasoft.phyligram;
+
+import org.atriasoft.etk.math.Vector3f;
+
+public class PhysicCollisionAABB {
+ public float minX;
+ public float minY;
+ public float minZ;
+ public float maxX;
+ public float maxY;
+ public float maxZ;
+ public PhysicCollisionAABB(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
+ super();
+ this.minX = minX;
+ this.minY = minY;
+ this.minZ = minZ;
+ this.maxX = maxX;
+ this.maxY = maxY;
+ this.maxZ = maxZ;
+ }
+ public boolean intersect(PhysicCollisionAABB other) {
+ if (this == other) {
+ return false;
+ }
+ if (minX > other.maxX) {
+ return false;
+ }
+ if (maxX < other.minX) {
+ return false;
+ }
+ if (minY > other.maxY) {
+ return false;
+ }
+ if (maxY < other.minY) {
+ return false;
+ }
+ if (minZ > other.maxZ) {
+ return false;
+ }
+ if (maxZ < other.minZ) {
+ return false;
+ }
+ return true;
+ }
+ public void update(Vector3f point) {
+ if (minX > point.x()) {
+ minX = point.x();
+ }
+ if (maxX < point.x()) {
+ maxX = point.x();
+ }
+ if (minY > point.y()) {
+ minY = point.y();
+ }
+ if (maxY < point.y()) {
+ maxY = point.y();
+ }
+ if (minZ > point.z()) {
+ minZ = point.z();
+ }
+ if (maxZ < point.z()) {
+ maxZ = point.z();
+ }
+ }
+ public Vector3f getMin() {
+ return new Vector3f(minX, minY, minZ);
+ }
+ public Vector3f getMax() {
+ return new Vector3f(maxX, maxY, maxZ);
+ }
+ public static PhysicCollisionAABB beforeCalculated() {
+ // TODO Auto-generated method stub
+ return new PhysicCollisionAABB(999999,999999,999999,-999999,-999999,-999999);
+ }
+}
+
+
diff --git a/src/org/atriasoft/phyligram/PhysicMapVoxel.java b/src/org/atriasoft/phyligram/PhysicMapVoxel.java
new file mode 100644
index 0000000..ec96f57
--- /dev/null
+++ b/src/org/atriasoft/phyligram/PhysicMapVoxel.java
@@ -0,0 +1,42 @@
+package org.atriasoft.phyligram;
+
+import org.atriasoft.etk.math.Transform3D;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+import org.atriasoft.ege.map.VoxelChunk;
+
+public class PhysicMapVoxel extends PhysicShape {
+ // Box size property in X, Y and Z
+ private VoxelChunk chunk;
+ public PhysicMapVoxel(VoxelChunk chunk) {
+ super(PhysicShapeType.MAP_VOXEL);
+ this.chunk = chunk;
+ }
+ @Override
+ public void updateAABB(Transform3D transform, PhysicCollisionAABB aabb) {
+ if (this.chunk == null) {
+ return;
+ }
+ this.colisionPoints.clear();
+ aabb.update(new Vector3f(this.chunk.getPosition().x(),this.chunk.getPosition().y(),this.chunk.getPosition().z()));
+ aabb.update(new Vector3f(
+ this.chunk.getPosition().x() + VoxelChunk.VOXEL_CHUNK_SIZE,
+ this.chunk.getPosition().y() + VoxelChunk.VOXEL_CHUNK_SIZE,
+ this.chunk.getPosition().z() + VoxelChunk.VOXEL_CHUNK_SIZE));
+ }
+ // only needed for the narrow phase calculation ...
+ private Vector3f narrowPhaseGlobalPos;
+ private Vector3f narrowPhaseAxisX = new Vector3f(1,0,0);
+ private Vector3f narrowPhaseAxisY = new Vector3f(1,0,0);
+ private Vector3f narrowPhaseAxisZ = new Vector3f(1,0,0);
+ private Vector3f narrowPhaseHalfSize = new Vector3f(0.5f,0.5f,0.5f);
+ @Override
+ public void updateForNarrowCollision(Transform3D transform) {
+ this.narrowPhaseGlobalPos = transform.multiply(this.transform.multiply(new Vector3f(0,0,0)));
+ }
+ @Override
+ public void renderDebug(Transform3D transform, ResourceColored3DObject debugDrawProperty) {
+
+
+ }
+}
diff --git a/src/org/atriasoft/phyligram/PhysicShape.java b/src/org/atriasoft/phyligram/PhysicShape.java
new file mode 100644
index 0000000..3c90611
--- /dev/null
+++ b/src/org/atriasoft/phyligram/PhysicShape.java
@@ -0,0 +1,101 @@
+package org.atriasoft.phyligram;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.atriasoft.etk.math.Quaternion;
+import org.atriasoft.etk.math.Transform3D;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+
+
+
+
+public abstract class PhysicShape {
+
+
+
+ protected List colisionPoints = new ArrayList<>();
+ // protected Quaternion quaternion;
+ // protected Vector3f origin;
+ protected Transform3D transform;
+ protected Transform3D transformGlobal;
+ protected float mass = 0;
+ protected final PhysicShapeType type;
+
+ public PhysicShape(PhysicShapeType type) {
+ this.type = type;
+ this.transform = Transform3D.IDENTITY;
+ // this.quaternion = Quaternion.identity();
+ // this.origin = Vector3f.zero();
+ this.mass = 0;
+ }
+
+ public PhysicShape(PhysicShapeType type, Quaternion quaternion, Vector3f origin, float mass) {
+ this.type = type;
+ this.transform = new Transform3D(origin, quaternion);
+ // this.quaternion = quaternion;
+ // this.origin = origin;
+ this.mass = mass;
+ }
+
+ public Quaternion getQuaternionFull() {
+ return transformGlobal.getOrientation().multiply(transform.getOrientation());
+ }
+
+ public Quaternion getQuaternion() {
+ return transform.getOrientation();
+ }
+
+ public void setQuaternion(Quaternion quaternion) {
+ this.transform = this.transform.withOrientation(quaternion);
+ }
+
+ public Vector3f getOrigin() {
+ return this.transform.getPosition();
+ }
+
+ public void setOrigin(Vector3f origin) {
+ this.transform = this.transform.withPosition(origin);
+ }
+
+ public Transform3D getTransform() {
+ return transform;
+ }
+
+ public void setTransform(Transform3D transform) {
+ this.transform = transform;
+ }
+
+ public Transform3D getTransformGlobal() {
+ return transformGlobal;
+ }
+
+ public void setTransformGlobal(Transform3D transform) {
+ this.transformGlobal = transform;
+ }
+
+ public float getMass() {
+ return mass;
+ }
+
+ public void setMass(float mass) {
+ this.mass = mass;
+ }
+
+ public PhysicShapeType getType() {
+ return type;
+ }
+
+ public void addColision(Collision colision) {
+ colisionPoints.add(colision);
+ }
+
+
+ public abstract void updateAABB(Transform3D transform, PhysicCollisionAABB aabb);
+
+ public abstract void updateForNarrowCollision(Transform3D transform);
+
+ public abstract void renderDebug(Transform3D transform, ResourceColored3DObject debugDrawProperty);
+
+}
diff --git a/src/org/atriasoft/phyligram/PhysicShapeType.java b/src/org/atriasoft/phyligram/PhysicShapeType.java
new file mode 100644
index 0000000..8f162cd
--- /dev/null
+++ b/src/org/atriasoft/phyligram/PhysicShapeType.java
@@ -0,0 +1,13 @@
+package org.atriasoft.phyligram;
+
+public enum PhysicShapeType {
+ UNKNOWN,
+ BOX,
+ CAPSULE,
+ CONE,
+ CONVEXHULL,
+ CYLINDER,
+ SPHERE,
+ CONCAVE,
+ MAP_VOXEL
+}
diff --git a/src/org/atriasoft/phyligram/PhysicSphere.java b/src/org/atriasoft/phyligram/PhysicSphere.java
new file mode 100644
index 0000000..8a6b8af
--- /dev/null
+++ b/src/org/atriasoft/phyligram/PhysicSphere.java
@@ -0,0 +1,38 @@
+package org.atriasoft.phyligram;
+
+import org.atriasoft.etk.Color;
+import org.atriasoft.etk.math.Transform3D;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.gale.resource.ResourceColored3DObject;
+
+public class PhysicSphere extends PhysicShape {
+ // Box size property in X, Y and Z
+ private float size;
+ public PhysicSphere() {
+ super(PhysicShapeType.SPHERE);
+ }
+ public float getSize() {
+ return size;
+ }
+ public void setSize(float size) {
+ this.size = size;
+ }
+ @Override
+ public void updateAABB(Transform3D transform, PhysicCollisionAABB aabb) {
+ aabb.update(transform.multiply(this.transform.getPosition()).add(this.size,0,0));
+ aabb.update(transform.multiply(this.transform.getPosition()).add(-this.size,0,0));
+ aabb.update(transform.multiply(this.transform.getPosition()).add(0,this.size,0));
+ aabb.update(transform.multiply(this.transform.getPosition()).add(0,-this.size,0));
+ aabb.update(transform.multiply(this.transform.getPosition()).add(0,0,this.size));
+ aabb.update(transform.multiply(this.transform.getPosition()).add(0,0,-this.size));
+ }
+ @Override
+ public void updateForNarrowCollision(Transform3D transform) {
+
+ }
+ @Override
+ public void renderDebug(Transform3D transform, ResourceColored3DObject debugDrawProperty) {
+ debugDrawProperty.drawSphere(this.size, 9, 9, this.transform.getOpenGLMatrix().multiply(transform.getOpenGLMatrix()), new Color(0,1,0,1));
+
+ }
+}
\ No newline at end of file
diff --git a/src/org/atriasoft/phyligram/ToolCollisionOBBWithOBB.java b/src/org/atriasoft/phyligram/ToolCollisionOBBWithOBB.java
new file mode 100644
index 0000000..e7286eb
--- /dev/null
+++ b/src/org/atriasoft/phyligram/ToolCollisionOBBWithOBB.java
@@ -0,0 +1,378 @@
+package org.atriasoft.phyligram;
+
+import org.atriasoft.etk.math.Quaternion;
+import org.atriasoft.etk.math.Vector3f;
+import org.atriasoft.phyligram.internal.Log;
+
+// set the relevant elements of our oriented bounding box
+class OBB {
+ public Vector3f position;
+ public Vector3f axisX;
+ public Vector3f axisY;
+ public Vector3f axisZ;
+ public Vector3f halfSize;
+
+ public OBB() {
+ position = Vector3f.ZERO;
+ axisX = Vector3f.ZERO;
+ axisY = Vector3f.ZERO;
+ axisZ = Vector3f.ZERO;
+ halfSize = Vector3f.ZERO;
+ }
+};
+
+public class ToolCollisionOBBWithOBB {
+ private ToolCollisionOBBWithOBB() {}
+
+ // check if there's a separating plane in between the selected axes
+ private static boolean getSeparatingPlane(Vector3f rPos, Vector3f plane, OBB box1, OBB box2) {
+ return (Math.abs(rPos.dot(plane)) > (Math.abs(box1.axisX.multiply(box1.halfSize.x()).dot(plane)) + Math.abs(box1.axisY.multiply(box1.halfSize.y()).dot(plane))
+ + Math.abs(box1.axisZ.multiply(box1.halfSize.z()).dot(plane)) + Math.abs(box2.axisX.multiply(box2.halfSize.x()).dot(plane))
+ + Math.abs(box2.axisY.multiply(box2.halfSize.y()).dot(plane)) + Math.abs(box2.axisZ.multiply(box2.halfSize.z()).dot(plane))));
+ }
+
+ // test for separating planes in all 15 axes
+ public static boolean getCollision(OBB box1, OBB box2) {
+ Vector3f rPos = box2.position.less(box1.position);
+ boolean ret = getSeparatingPlane(rPos, box1.axisX, box1, box2) || getSeparatingPlane(rPos, box1.axisY, box1, box2) || getSeparatingPlane(rPos, box1.axisZ, box1, box2)
+ || getSeparatingPlane(rPos, box2.axisX, box1, box2) || getSeparatingPlane(rPos, box2.axisY, box1, box2) || getSeparatingPlane(rPos, box2.axisZ, box1, box2)
+ || getSeparatingPlane(rPos, box1.axisX.cross(box2.axisX), box1, box2) || getSeparatingPlane(rPos, box1.axisX.cross(box2.axisY), box1, box2)
+ || getSeparatingPlane(rPos, box1.axisX.cross(box2.axisZ), box1, box2) || getSeparatingPlane(rPos, box1.axisY.cross(box2.axisX), box1, box2)
+ || getSeparatingPlane(rPos, box1.axisY.cross(box2.axisY), box1, box2) || getSeparatingPlane(rPos, box1.axisY.cross(box2.axisZ), box1, box2)
+ || getSeparatingPlane(rPos, box1.axisZ.cross(box2.axisX), box1, box2) || getSeparatingPlane(rPos, box1.axisZ.cross(box2.axisY), box1, box2)
+ || getSeparatingPlane(rPos, box1.axisZ.cross(box2.axisZ), box1, box2);
+ return !ret;
+ }
+//
+// // a quick test to see the code working
+// public static void main(String[] args) {
+// // create two obbs
+// OBB aaa = new OBB();
+// OBB bbb = new OBB();
+//
+// // set the first obb's properties
+// aaa.position = new Vector3f(0.0f, 0.0f, 0.0f); // set its center position
+//
+// // set the half size
+// aaa.halfSize = new Vector3f(10.0f, 1.0f, 1.0f);
+//
+// // set the axes orientation
+// aaa.axisX = new Vector3f(1.0f, 0.0f, 0.0f);
+// aaa.axisY = new Vector3f(0.0f, 1.0f, 0.0f);
+// aaa.axisZ = new Vector3f(0.0f, 0.0f, 1.0f);
+//
+// // set the second obb's properties
+// bbb.position = new Vector3f(20.0f, 0.0f, 0.0f); // set its center position
+//
+// // set the half size
+// bbb.halfSize = new Vector3f(10.0f, 1.0f, 1.0f);
+//
+// // set the axes orientation
+// bbb.axisX = new Vector3f(1.0f, 0.0f, 0.0f);
+// bbb.axisY = new Vector3f(0.0f, 1.0f, 0.0f);
+// bbb.axisZ = new Vector3f(0.0f, 0.0f, 1.0f);
+//
+// // run the code and get the result as a message
+// if (getCollision(aaa, bbb)) {
+// Log.info("Collision!!!");
+// } else {
+// Log.info("NO Collision!!!");
+// }
+// }
+
+ // check if there's a separating plane in between the selected axes
+ private static boolean getSeparatingPlane222(Vector3f rPos, Vector3f plane, PhysicBox box1, PhysicBox box2) {
+ return (Math.abs(rPos.dot(plane)) > (Math.abs(box1.narrowPhaseAxisX.multiply(box1.narrowPhaseHalfSize.x()).dot(plane))
+ + Math.abs(box1.narrowPhaseAxisY.multiply(box1.narrowPhaseHalfSize.y()).dot(plane)) + Math.abs(box1.narrowPhaseAxisZ.multiply(box1.narrowPhaseHalfSize.z()).dot(plane))
+ + Math.abs(box2.narrowPhaseAxisX.multiply(box2.narrowPhaseHalfSize.x()).dot(plane)) + Math.abs(box2.narrowPhaseAxisY.multiply(box2.narrowPhaseHalfSize.y()).dot(plane))
+ + Math.abs(box2.narrowPhaseAxisZ.multiply(box2.narrowPhaseHalfSize.z()).dot(plane))));
+ }
+
+ public static boolean testCollide(PhysicBox box1, PhysicBox box2) {
+
+ Vector3f rPos = box2.narrowPhaseGlobalPos.less(box1.narrowPhaseGlobalPos);
+ boolean ret = getSeparatingPlane222(rPos, box1.narrowPhaseAxisX, box1, box2) || getSeparatingPlane222(rPos, box1.narrowPhaseAxisY, box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisZ, box1, box2) || getSeparatingPlane222(rPos, box2.narrowPhaseAxisX, box1, box2)
+ || getSeparatingPlane222(rPos, box2.narrowPhaseAxisY, box1, box2) || getSeparatingPlane222(rPos, box2.narrowPhaseAxisZ, box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisX.cross(box2.narrowPhaseAxisX), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisX.cross(box2.narrowPhaseAxisY), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisX.cross(box2.narrowPhaseAxisZ), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisY.cross(box2.narrowPhaseAxisX), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisY.cross(box2.narrowPhaseAxisY), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisY.cross(box2.narrowPhaseAxisZ), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisZ.cross(box2.narrowPhaseAxisX), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisZ.cross(box2.narrowPhaseAxisY), box1, box2)
+ || getSeparatingPlane222(rPos, box1.narrowPhaseAxisZ.cross(box2.narrowPhaseAxisZ), box1, box2);
+ return !ret;
+ }
+
+ public static void getCollidePoints(PhysicBox box1, boolean isStatic1, PhysicBox box2, boolean isStatic2) {
+ // Log.info("Try to calculare reverse force ........");
+ Vector3f rPos1 = box1.narrowPhaseGlobalPos.less(box2.narrowPhaseGlobalPos);
+ Vector3f rPos2 = box2.narrowPhaseGlobalPos.less(box1.narrowPhaseGlobalPos);
+ Quaternion quat1 = box1.getQuaternionFull();
+ Quaternion quat2 = box2.getQuaternionFull();
+ // Step 1: set the Box 2 in the repere of the Box 1:
+ Quaternion quatTransfer1 = Quaternion.diff(quat1, quat2);
+ Quaternion quatTransfer2 = Quaternion.diff(quat2, quat1);
+ // quatTransfer.normalize();
+
+ // DebugDisplay.relativeTest = quatTransfer;
+ // Vector3f tmp = rPos.addNew(new Vector3f(0,0,14));
+ // DebugDisplay.relativeTestPos.getTransform().setPosition(tmp);
+ // DebugDisplay.relativeTestPos.getTransform().setOrientation(quatTransfer);
+ // DebugDisplay.boxTest.setSize(box1.getSize());
+ // Log.info("" + rPos + quatTransfer1);
+ // /*res = */getCollidePointsAABBCenteredWithOBB(box1.narrowPhaseHalfSize, box2.narrowPhaseHalfSize, quatTransfer, rPos);
+ /* res = transfert in generic plan the new res ... */
+ // test origin AABB with OBB collision
+ // Step 2: set the Box 1 in the repere of the Box 2:
+ // test origin AABB with OBB collision
+ // tmp = rPos.addNew(new Vector3f(0,0,14));
+ DebugDisplay.testRpos = quat2.inverse().getMatrix4().multiply(rPos1);
+ DebugDisplay.testQTransfert = quatTransfer2;
+ DebugDisplay.box1HalfSize = box2.narrowPhaseHalfSize;
+ DebugDisplay.box2HalfSize = box1.narrowPhaseHalfSize;
+
+ // DebugDisplay.relativeTestPos.getTransform().setPosition(tmp);
+ // DebugDisplay.relativeTestPos.getTransform().setOrientation(quatTransfer);
+ // DebugDisplay.boxTest.setSize(box1.getSize());
+ // foinctionne avec la box qui n'est pas orienter...
+ // getCollidePointsAABBCenteredWithOBB(box2.narrowPhaseHalfSize, box1.narrowPhaseHalfSize, quatTransfer2, rPos1);
+ // fonctionne quand le block est trourner de 90% petit pb de positionnement en hauteur....
+ // getCollidePointsAABBCenteredWithOBB(box2.narrowPhaseHalfSize, box1.narrowPhaseHalfSize, quatTransfer2, quat2.multiply(rPos2));
+ ColisionPoints[] collide1 = getCollidePointsAABBCenteredWithOBB(box2.narrowPhaseHalfSize, box1.narrowPhaseHalfSize, quatTransfer2, quat2.inverse().getMatrix4().multiply(rPos1));
+ // transfer detection point collision in global environement:
+ if (collide1 != null) {
+ for (int iii = 0; iii < collide1.length; iii++) {
+ collide1[iii].position = quat1.multiply(collide1[iii].position).add(box1.narrowPhaseGlobalPos);
+ collide1[iii].force = quat2.multiply(collide1[iii].force);//.add(box1.narrowPhaseGlobalPos);
+ }
+ }
+ /* res = trensfert in generic plan the new res ... */
+
+ DebugDisplay.testRpos = quat1.inverse().getMatrix4().multiply(rPos2);
+ DebugDisplay.testQTransfert = quatTransfer1;
+ DebugDisplay.box1HalfSize = box1.narrowPhaseHalfSize;
+ DebugDisplay.box2HalfSize = box2.narrowPhaseHalfSize;
+ ColisionPoints[] collide2 = getCollidePointsAABBCenteredWithOBB(box1.narrowPhaseHalfSize, box2.narrowPhaseHalfSize, quatTransfer1, quat1.inverse().getMatrix4().multiply(rPos2));
+ if (collide2 != null) {
+ for (int iii = 0; iii < collide2.length; iii++) {
+ collide2[iii].position = quat2.multiply(collide2[iii].position).add(box2.narrowPhaseGlobalPos);
+ collide2[iii].force = quat1.multiply(collide2[iii].force);//.add(box2.narrowPhaseGlobalPos);
+ }
+ }
+ // add only if NOT static, when static no colision is performed
+ if (true) { //!isStatic1) {
+ Collision colision = new Collision(collide1, box2, collide2, isStatic2);
+ box1.addColision(colision);
+ }
+ if (true) { //!isStatic1) {
+ Collision colision = new Collision(collide2, box1, collide1, isStatic1);
+ box2.addColision(colision);
+ }
+
+ }
+
+ public static ColisionPoints[] getCollidePointsAABBCenteredWithOBB(Vector3f box1HalfSize, Vector3f box2HalfSize, Quaternion box2Orientation, Vector3f box2Position) {
+
+ // point in AABB
+ Vector3f topBackRight = box2Orientation.multiply(new Vector3f(+box2HalfSize.x(), +box2HalfSize.y(), +box2HalfSize.z())).add(box2Position);
+ Vector3f topBackLeft = box2Orientation.multiply(new Vector3f(-box2HalfSize.x(), +box2HalfSize.y(), +box2HalfSize.z())).add(box2Position);
+ Vector3f topFrontRight = box2Orientation.multiply(new Vector3f(+box2HalfSize.x(), -box2HalfSize.y(), +box2HalfSize.z())).add(box2Position);
+ Vector3f topFrontLeft = box2Orientation.multiply(new Vector3f(-box2HalfSize.x(), -box2HalfSize.y(), +box2HalfSize.z())).add(box2Position);
+ Vector3f bottomBackRight = box2Orientation.multiply(new Vector3f(+box2HalfSize.x(), +box2HalfSize.y(), -box2HalfSize.z())).add(box2Position);
+ Vector3f bottomBackLeft = box2Orientation.multiply(new Vector3f(-box2HalfSize.x(), +box2HalfSize.y(), -box2HalfSize.z())).add(box2Position);
+ Vector3f bottomFrontRight = box2Orientation.multiply(new Vector3f(+box2HalfSize.x(), -box2HalfSize.y(), -box2HalfSize.z())).add(box2Position);
+ Vector3f bottomFrontLeft = box2Orientation.multiply(new Vector3f(-box2HalfSize.x(), -box2HalfSize.y(), -box2HalfSize.z())).add(box2Position);
+ DebugDisplay.testPoints.clear();
+ DebugDisplay.testPoints.add(topBackRight);
+ DebugDisplay.testPoints.add(topBackLeft);
+ DebugDisplay.testPoints.add(topFrontRight);
+ DebugDisplay.testPoints.add(topFrontLeft);
+ DebugDisplay.testPoints.add(bottomBackRight);
+ DebugDisplay.testPoints.add(bottomBackLeft);
+ DebugDisplay.testPoints.add(bottomFrontRight);
+ DebugDisplay.testPoints.add(bottomFrontLeft);
+ DebugDisplay.testPointsBox.clear();
+ DebugDisplay.testPointsBox.add(new Vector3f(+box1HalfSize.x(), +box1HalfSize.y(), +box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(-box1HalfSize.x(), +box1HalfSize.y(), +box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(+box1HalfSize.x(), -box1HalfSize.y(), +box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(-box1HalfSize.x(), -box1HalfSize.y(), +box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(+box1HalfSize.x(), +box1HalfSize.y(), -box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(-box1HalfSize.x(), +box1HalfSize.y(), -box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(+box1HalfSize.x(), -box1HalfSize.y(), -box1HalfSize.z()));
+ DebugDisplay.testPointsBox.add(new Vector3f(-box1HalfSize.x(), -box1HalfSize.y(), -box1HalfSize.z()));
+ Vector3f insideTopBackRight = pointDistanceInAABB(box1HalfSize, topBackRight);
+ Vector3f insideTopBackLeft = pointDistanceInAABB(box1HalfSize, topBackLeft);
+ Vector3f insideTopFrontRight = pointDistanceInAABB(box1HalfSize, topFrontRight);
+ Vector3f insideTopFrontLeft = pointDistanceInAABB(box1HalfSize, topFrontLeft);
+ Vector3f insideBottomBackRight = pointDistanceInAABB(box1HalfSize, bottomBackRight);
+ Vector3f insideBottomBackLeft = pointDistanceInAABB(box1HalfSize, bottomBackLeft);
+ Vector3f insideBottomFrontRight = pointDistanceInAABB(box1HalfSize, bottomFrontRight);
+ Vector3f insideBottomFrontLeft = pointDistanceInAABB(box1HalfSize, bottomFrontLeft);
+ DebugDisplay.testPointsCollide.clear();
+ DebugDisplay.testPointsCollide.add(insideTopBackRight == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideTopBackLeft == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideTopFrontRight == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideTopFrontLeft == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideBottomBackRight == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideBottomBackLeft == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideBottomFrontRight == null ? false : true);
+ DebugDisplay.testPointsCollide.add(insideBottomFrontLeft == null ? false : true);
+ int count = 0;
+ if (insideTopBackRight != null) {
+ count++;
+ }
+ if (insideTopBackLeft != null) {
+ count++;
+ }
+ if (insideTopFrontRight != null) {
+ count++;
+ }
+ if (insideTopFrontLeft != null) {
+ count++;
+ }
+ if (insideBottomBackRight != null) {
+ count++;
+ }
+ if (insideBottomBackLeft != null) {
+ count++;
+ }
+ if (insideBottomFrontRight != null) {
+ count++;
+ }
+ if (insideBottomFrontLeft != null) {
+ count++;
+ }
+ ColisionPoints[] out = new ColisionPoints[count];
+ count = 0;
+ if (insideTopBackRight != null) {
+ out[count] = new ColisionPoints(new Vector3f(+box2HalfSize.x(), +box2HalfSize.y(), +box2HalfSize.z()), insideTopBackRight);
+ count++;
+ }
+ if (insideTopBackLeft != null) {
+ out[count] = new ColisionPoints(new Vector3f(-box2HalfSize.x(), +box2HalfSize.y(), +box2HalfSize.z()), insideTopBackLeft);
+ count++;
+ }
+ if (insideTopFrontRight != null) {
+ out[count] = new ColisionPoints(new Vector3f(+box2HalfSize.x(), -box2HalfSize.y(), +box2HalfSize.z()), insideTopFrontRight);
+ count++;
+ }
+ if (insideTopFrontLeft != null) {
+ out[count] = new ColisionPoints(new Vector3f(-box2HalfSize.x(), -box2HalfSize.y(), +box2HalfSize.z()), insideTopFrontLeft);
+ count++;
+ }
+ if (insideBottomBackRight != null) {
+ out[count] = new ColisionPoints(new Vector3f(+box2HalfSize.x(), +box2HalfSize.y(), -box2HalfSize.z()), insideBottomBackRight);
+ count++;
+ }
+ if (insideBottomBackLeft != null) {
+ out[count] = new ColisionPoints(new Vector3f(-box2HalfSize.x(), +box2HalfSize.y(), -box2HalfSize.z()), insideBottomBackLeft);
+ count++;
+ }
+ if (insideBottomFrontRight != null) {
+ out[count] = new ColisionPoints(new Vector3f(+box2HalfSize.x(), -box2HalfSize.y(), -box2HalfSize.z()), insideBottomFrontRight);
+ count++;
+ }
+ if (insideBottomFrontLeft != null) {
+ out[count] = new ColisionPoints(new Vector3f(-box2HalfSize.x(), -box2HalfSize.y(), -box2HalfSize.z()), insideBottomFrontLeft);
+ count++;
+ }
+ if (count != 0) {
+ // Find a point inside the BOX ...
+ /*
+ Log.info("Detect point inside ... " + insideTopBackRight + " " + insideTopBackLeft + " " + insideTopFrontRight + " " + insideTopFrontLeft + " " + insideBottomBackRight + " "
+ + insideBottomBackLeft + " " + insideBottomFrontRight + " " + insideBottomFrontLeft);
+ */
+ return out;
+ }
+ // line in AABB
+ // TODO:
+ // Log.info("Need to detect line inside ..."); // pas tot a fait... si ca colisione déja avec un point de l'autre ...
+ return null;
+ }
+
+ public static boolean pointInAABB(Vector3f halfSize, Vector3f point) {
+ if (point.x() > -halfSize.x() && point.x() < halfSize.x() && point.y() > -halfSize.y() && point.y() < halfSize.y() && point.z() > -halfSize.z() && point.z() < halfSize.z()) {
+ return true;
+ }
+ return false;
+ }
+
+ public static Vector3f pointDistanceInAABB(Vector3f halfSize, Vector3f point) {
+ float outX = 0;
+ float outY = 0;
+ float outZ = 0;
+ if (point.x() < 0) {
+ if (point.x() > -halfSize.x()) {
+
+ outX = -(halfSize.x() + point.x());
+
+ //out.x = -halfSize.x - point.x;
+ //out.x = -halfSize.x + point.x;
+ //out.x = + point.x;
+ } else {
+ return null;
+ }
+ } else {
+ if (point.x() < halfSize.x()) {
+ //out.x = halfSize.x + point.x;
+ outX = halfSize.x() - point.x();
+ //out.x = - point.x;
+ } else {
+ return null;
+ }
+ }
+ if (point.y() < 0) {
+ if (point.y() > -halfSize.y()) {
+ outY = -halfSize.y() - point.y();
+ //out.y = -halfSize.y + point.y;
+ //out.y = point.y;
+ } else {
+ return null;
+ }
+ } else {
+ if (point.y() < halfSize.y()) {
+ //out.y = halfSize.y + point.y;
+ outY = halfSize.y() - point.y();
+ //out.y = - point.y;
+ } else {
+ return null;
+ }
+ }
+ if (point.z() < 0) {
+ if (point.z() > -halfSize.z()) {
+ outZ = -halfSize.z() - point.z();
+ //out.z = -halfSize.z + point.z;
+ //out.z = + point.z;
+ } else {
+ return null;
+ }
+ } else {
+ if (point.z() < halfSize.z()) {
+ //out.z = halfSize.z + point.z;
+ outZ = halfSize.z() - point.z();
+ //out.z = - point.z;
+ } else {
+ return null;
+ }
+ }
+ if (Math.abs(outX) < Math.abs(outY)) {
+ outY = 0;
+ if (Math.abs(outX) < Math.abs(outZ)) {
+ outZ = 0;
+ return new Vector3f(outX, outY, outZ);
+ }
+ outX = 0;
+ return new Vector3f(outX, outY, outZ);
+ }
+ outX = 0;
+ if (Math.abs(outY) < Math.abs(outZ)) {
+ outZ = 0;
+ return new Vector3f(outX, outY, outZ);
+ }
+ outY = 0;
+ return new Vector3f(outX, outY, outZ);
+ }
+}
diff --git a/src/org/atriasoft/phyligram/internal/Log.java b/src/org/atriasoft/phyligram/internal/Log.java
new file mode 100644
index 0000000..43eda0c
--- /dev/null
+++ b/src/org/atriasoft/phyligram/internal/Log.java
@@ -0,0 +1,68 @@
+package org.atriasoft.phyligram.internal;
+
+import io.scenarium.logger.LogLevel;
+import io.scenarium.logger.Logger;
+
+public class Log {
+ private static final String LIB_NAME = "ege";
+ private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
+ private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
+ private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
+ private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
+ private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
+ private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
+ private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
+ private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
+ private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
+
+ public static void critical(final String data) {
+ if (PRINT_CRITICAL) {
+ Logger.critical(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void debug(final String data) {
+ if (PRINT_DEBUG) {
+ Logger.debug(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void error(final String data) {
+ if (PRINT_ERROR) {
+ Logger.error(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void info(final String data) {
+ if (PRINT_INFO) {
+ Logger.info(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void print(final String data) {
+ if (PRINT_PRINT) {
+ Logger.print(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void todo(final String data) {
+ if (PRINT_TODO) {
+ Logger.todo(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void verbose(final String data) {
+ if (PRINT_VERBOSE) {
+ Logger.verbose(LIB_NAME_DRAW, data);
+ }
+ }
+
+ public static void warning(final String data) {
+ if (PRINT_WARNING) {
+ Logger.warning(LIB_NAME_DRAW, data);
+ }
+ }
+
+ private Log() {}
+
+}