Compare commits
No commits in common. "976afae4905f086d0887d8184945a204ca6f0696" and "1ecc20a08c0e1af401a902adab332da24557dc8d" have entirely different histories.
976afae490
...
1ecc20a08c
17
.classpath
17
.classpath
@ -6,6 +6,17 @@
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="resources"/>
|
||||
<classpathentry including="**/*.java" kind="src" output="out/eclipse/classes-test" path="test/src">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/atriasoft-ephysics">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/atriasoft-ewol">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
@ -16,11 +27,7 @@
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
|
@ -19,10 +19,12 @@ 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.ege.tools.MeshGenerator;
|
||||
@ -33,8 +35,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.Gale;
|
||||
import org.atriasoft.gale.GaleApplication;
|
||||
import org.atriasoft.gale.Gale;
|
||||
import org.atriasoft.gale.backend3d.OpenGL;
|
||||
import org.atriasoft.gale.backend3d.OpenGL.Flag;
|
||||
import org.atriasoft.gale.context.GaleContext;
|
||||
@ -43,7 +45,7 @@ import org.atriasoft.gale.key.KeySpecial;
|
||||
import org.atriasoft.gale.key.KeyStatus;
|
||||
import org.atriasoft.gale.key.KeyType;
|
||||
import org.atriasoft.gale.resource.ResourceColored3DObject;
|
||||
import org.atriasoft.phyligram.PhysicBox;
|
||||
import org.atriasoft.phyligram.shape.Box;
|
||||
|
||||
public class CollisionTestApplication extends GaleApplication {
|
||||
public static Vector3f box1HalfSize;
|
||||
@ -110,15 +112,19 @@ public class CollisionTestApplication extends GaleApplication {
|
||||
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(Vector3f.ZERO, orientation)));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
final PhysicBox box2 = new PhysicBox();
|
||||
box2.setSize(new Vector3f(5.0f, 5.0f, 0.5f));
|
||||
box2.setOrigin(Vector3f.ZERO);
|
||||
box2.setMass(0);
|
||||
physics2.addShape(box2);
|
||||
localBox.addComponent(physics2);
|
||||
if (false) {
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
physics2.setTransform(new Transform3D(Vector3f.ZERO, orientation));
|
||||
final Box box2 = new Box();
|
||||
box2.setSize(new Vector3f(5.0f, 5.0f, 0.5f));
|
||||
box2.setOrigin(Vector3f.ZERO);
|
||||
box2.setMass(0);
|
||||
physics2.addShape(box2);
|
||||
localBox.addComponent(physics2);
|
||||
} else {
|
||||
localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0))));
|
||||
}
|
||||
this.env.addEntity(localBox);
|
||||
}
|
||||
/*
|
||||
@ -152,17 +158,40 @@ public class CollisionTestApplication extends GaleApplication {
|
||||
this.env.addEntity(gird);
|
||||
|
||||
final Entity player = new Entity(this.env);
|
||||
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);
|
||||
if (false) {
|
||||
final Transform3D playerTransform = new Transform3D(new Vector3f(0, -5, 13));
|
||||
//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)));
|
||||
final ComponentPhysics physics = new ComponentPhysics(this.env, playerTransform);
|
||||
physics.setBodyType(PhysicBodyType.BODY_DYNAMIC);
|
||||
final Box box = new Box();
|
||||
box.setSize(new Vector3f(0.3f, 0.3f, 0.9f));
|
||||
box.setOrigin(new Vector3f(0, 0, 0.9f));
|
||||
box.setMass(100);
|
||||
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);
|
||||
@ -180,9 +209,9 @@ public class CollisionTestApplication extends GaleApplication {
|
||||
final Engine tmpEngine = this.env.getEngine("physics");
|
||||
if (tmpEngine != null) {
|
||||
final EnginePhysics physicsEngine = (EnginePhysics) tmpEngine;
|
||||
//Disable gravity for test ...
|
||||
//Disable gravity for test ...
|
||||
//physicsEngine.setGravity(new Vector3f(0.0f, 0.0f, -1.0f));
|
||||
//physicsEngine.setGravity(new Vector3f(0.0f, 0.0f, -10.0f));
|
||||
physicsEngine.setGravity(new Vector3f(0.0f, 0.0f, -10.0f));
|
||||
}
|
||||
|
||||
// ready to let Gale & Ege manage the display
|
||||
|
@ -1,7 +1,7 @@
|
||||
package sample.atriasoft.ege.loxelEngine;
|
||||
|
||||
public class Log {
|
||||
private static final String LIBNAME = "LoxelEnginePerso";
|
||||
private static final String LIBNAME = "LoxelEngine";
|
||||
|
||||
public static void critical(String data) {
|
||||
System.out.println("[C] " + Log.LIBNAME + " | " + data);
|
||||
|
@ -0,0 +1,437 @@
|
||||
package sample.atriasoft.ege.loxelEngine;
|
||||
|
||||
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.ComponentPhysics;
|
||||
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.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;
|
||||
import org.atriasoft.phyligram.shape.Box;
|
||||
|
||||
public class LoxelApplication extends GaleApplication {
|
||||
public static Vector3f box1HalfSize;
|
||||
public static Vector3f box2HalfSize;
|
||||
// public static ComponentPosition relativeTestPos;
|
||||
// public static Box boxTest;
|
||||
public static List<Vector3f> testPoints = new ArrayList<>();
|
||||
public static List<Vector3f> testPointsBox = new ArrayList<>();
|
||||
public static List<Boolean> 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 LoxelApplication() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final GaleContext context) {
|
||||
// set the system global max speed
|
||||
//ComponentPhysics.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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(0, 0, 5)));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(0, 4, 12.5f)));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(-2, 2, 14.5f)));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(-5, -5, 14)));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(15, 15, 14), orientation));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(2, -2, 14.2f), orientation));
|
||||
physics2.setAngularReactionEnable(false);
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
physics2.setTransform(new Transform3D(new Vector3f(0, 0, 0.0f), orientation));
|
||||
final Box box2 = new Box();
|
||||
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")));
|
||||
// ComponentPhysics physics2 = new ComponentPhysics(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)));
|
||||
final ComponentPhysics physics = new ComponentPhysics(this.env, playerTransform);
|
||||
physics.setBodyType(PhysicBodyType.BODY_DYNAMIC);
|
||||
physics.setAngularReactionEnable(false);
|
||||
physics.setSleepingEnable(false);
|
||||
final Box box = new Box();
|
||||
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 < LoxelApplication.testPoints.size(); iii++) {
|
||||
final Vector3f elem = LoxelApplication.testPoints.get(iii);
|
||||
final boolean collide = LoxelApplication.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 < LoxelApplication.testPointsBox.size(); iii++) {
|
||||
final Vector3f elem = LoxelApplication.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 (LoxelApplication.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(LoxelApplication.testRpos.x(), LoxelApplication.testRpos.y(), LoxelApplication.testRpos.z()))
|
||||
.multiply(Matrix4f.createMatrixTranslate(new Vector3f(0, 0, 14))).multiply(LoxelApplication.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(LoxelApplication.box2HalfSize, transformation, new Color(0, 1, 0, 0.5f));
|
||||
this.debugDrawProperty.drawSquare(LoxelApplication.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();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package sample.atriasoft.ege.loxelEngine;
|
||||
|
||||
import org.atriasoft.ege.Ege;
|
||||
import org.atriasoft.etk.Uri;
|
||||
import org.atriasoft.gale.Gale;
|
||||
|
||||
import sample.atriasoft.ege.collisiontest.MainCollisionTest;
|
||||
|
||||
public class MainLoxelEngine {
|
||||
public static void main(final String[] args) {
|
||||
Gale.init();
|
||||
Ege.init();
|
||||
Uri.setGroup("DATA", "data/");
|
||||
Uri.setGroup("RES", "res");
|
||||
Uri.addLibrary("loxelEngine", MainLoxelEngine.class, "testDataLoxelEngine/");
|
||||
Uri.setApplication(MainLoxelEngine.class, "");
|
||||
Gale.run(new LoxelApplication(), args);
|
||||
}
|
||||
}
|
39
samples/src/sample/atriasoft/ege/loxelEnginePerso/Log.java
Normal file
39
samples/src/sample/atriasoft/ege/loxelEnginePerso/Log.java
Normal file
@ -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() {}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package sample.atriasoft.ege.loxelEngine;
|
||||
package sample.atriasoft.ege.loxelEnginePerso;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -14,7 +14,7 @@ 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.ComponentPhysics;
|
||||
import org.atriasoft.ege.components.ComponentPhysicsPerso;
|
||||
import org.atriasoft.ege.components.ComponentPlayer;
|
||||
import org.atriasoft.ege.components.ComponentPosition;
|
||||
import org.atriasoft.ege.components.ComponentPositionPlayer;
|
||||
@ -116,7 +116,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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 ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
final PhysicBox box2 = new PhysicBox();
|
||||
box2.setSize(new Vector3f(1.001f, 1.001f, 1.001f));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
@ -133,7 +133,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 2.5f))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
final PhysicBox box2 = new PhysicBox();
|
||||
box2.setSize(new Vector3f(2.0f, 2.0f, 2.0f));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
@ -149,7 +149,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 1.5f))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
final PhysicBox box2 = new PhysicBox();
|
||||
box2.setSize(new Vector3f(3.0f, 3.0f, 3.0f));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
@ -166,7 +166,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 0))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
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));
|
||||
@ -184,7 +184,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 0), orientation)));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
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));
|
||||
@ -202,7 +202,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 0.2f), orientation)));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
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));
|
||||
@ -221,7 +221,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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 ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
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));
|
||||
@ -261,7 +261,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
// new Uri("DATA", "basic.frag")));
|
||||
// env.addEntity(localBox);
|
||||
// }
|
||||
boolean selectCase1 = true;
|
||||
|
||||
if (!this.disable) {
|
||||
// add a cube to test collision ...
|
||||
final Entity localBox = new Entity(this.env);
|
||||
@ -270,45 +270,17 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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, 3, 0))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
PhysicTriangle box2 = new PhysicTriangle();
|
||||
if (selectCase1) {
|
||||
box2.setPoints(new Vector3f(4, 0, 0), new Vector3f(0, 4, 0), new Vector3f(-2, -2, 1));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
physics2.addShape(box2);
|
||||
box2 = new PhysicTriangle();
|
||||
box2.setPoints(new Vector3f(4, 0, 0), new Vector3f(0, 4, 0), new Vector3f(600, 600, -100));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
box2.setFrictionCoefficient(1.0f);
|
||||
box2.setBouncingCoefficient(0.5f);
|
||||
} else {
|
||||
box2.setPoints(new Vector3f(4, 0, 0), new Vector3f(0, 4, 0), new Vector3f(-2, -2, 1));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
box2.setBouncingCoefficient(0.5f);
|
||||
}
|
||||
physics2.addShape(box2);
|
||||
localBox.addComponent(physics2);
|
||||
this.env.addEntity(localBox);
|
||||
}
|
||||
if (selectCase1) {
|
||||
// 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(1.1f, 5.1f, 1.0f), Quaternion.fromEulerAngles(new Vector3f(0.15f, 0.95f, 0.3f)))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
final PhysicSphere box2 = new PhysicSphere();
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
box2.setSize(1.0f);
|
||||
box2.setPoints(new Vector3f(4, 0, 0), new Vector3f(0, 4, 0), new Vector3f(-2, -2, 1));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
physics2.addShape(box2);
|
||||
box2 = new PhysicTriangle();
|
||||
box2.setPoints(new Vector3f(4, 0, 0), new Vector3f(0, 4, 0), new Vector3f(6, 6, 0));
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
box2.setBouncingCoefficient(0.5f);
|
||||
physics2.addShape(box2);
|
||||
localBox.addComponent(physics2);
|
||||
this.env.addEntity(localBox);
|
||||
@ -320,8 +292,26 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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(1.8f, 5.8f, 4), Quaternion.fromEulerAngles(new Vector3f(0.15f, 0.95f, 0.3f)))));
|
||||
final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||
localBox.addComponent(new ComponentPosition(new Transform3D(new Vector3f(1.1f, 5.1f, 1.0f), Quaternion.fromEulerAngles(new Vector3f(0.15f, 0.95f, 0.3f)))));
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
final PhysicSphere box2 = new PhysicSphere();
|
||||
physics2.setBodyType(PhysicBodyType.BODY_STATIC);
|
||||
box2.setSize(1.0f);
|
||||
box2.setOrigin(new Vector3f(0, 0, 0));
|
||||
box2.setMass(0);
|
||||
physics2.addShape(box2);
|
||||
localBox.addComponent(physics2);
|
||||
this.env.addEntity(localBox);
|
||||
}
|
||||
if (true) {
|
||||
// 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(1, 5, 4), Quaternion.fromEulerAngles(new Vector3f(0.15f, 0.95f, 0.3f)))));
|
||||
final ComponentPhysicsPerso physics2 = new ComponentPhysicsPerso(this.env);
|
||||
physics2.setBodyType(PhysicBodyType.BODY_DYNAMIC);
|
||||
final PhysicSphere box2 = new PhysicSphere();
|
||||
box2.setSize(1.0f);
|
||||
@ -352,7 +342,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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 ComponentPhysics physics = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics = new ComponentPhysicsPerso(this.env);
|
||||
physics.setBodyType(PhysicBodyType.BODY_DYNAMIC);
|
||||
//physics.setAngularReactionEnable(false);
|
||||
//physics.setSleepingEnable(false);
|
||||
@ -375,7 +365,7 @@ public class LoxelApplicationPerso extends GaleApplication {
|
||||
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)));
|
||||
final ComponentPhysics physics = new ComponentPhysics(this.env);
|
||||
final ComponentPhysicsPerso physics = new ComponentPhysicsPerso(this.env);
|
||||
physics.setBodyType(PhysicBodyType.BODY_DYNAMIC);
|
||||
final PhysicBox box = new PhysicBox();
|
||||
box.setSize(new Vector3f(0.6f, 0.6f, 1.8f));
|
@ -1,4 +1,4 @@
|
||||
package sample.atriasoft.ege.loxelEngine;
|
||||
package sample.atriasoft.ege.loxelEnginePerso;
|
||||
|
||||
import org.atriasoft.ege.Ege;
|
||||
import org.atriasoft.etk.Uri;
|
@ -28,7 +28,7 @@ open module org.atriasoft.ege {
|
||||
requires transitive org.atriasoft.gale;
|
||||
requires transitive org.atriasoft.etk;
|
||||
requires transitive org.atriasoft.ewol;
|
||||
//requires transitive org.atriasoft.ephysics;
|
||||
requires transitive org.atriasoft.ephysics;
|
||||
requires transitive org.atriasoft.loader3d;
|
||||
requires org.atriasoft.iogami;
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
package org.atriasoft.ege;
|
||||
|
||||
import org.atriasoft.ege.camera.Camera;
|
||||
import org.atriasoft.ege.components.ComponentPhysics;
|
||||
import org.atriasoft.ege.components.ComponentPlayer;
|
||||
import org.atriasoft.ege.components.ComponentPositionPlayer;
|
||||
import org.atriasoft.ege.internal.Log;
|
||||
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.ewol.event.EventEntry;
|
||||
import org.atriasoft.ewol.event.EventInput;
|
||||
import org.atriasoft.ewol.event.EventTime;
|
||||
import org.atriasoft.gale.Gale;
|
||||
import org.atriasoft.gale.key.KeyKeyboard;
|
||||
import org.atriasoft.gale.key.KeyStatus;
|
||||
|
||||
@ -20,6 +21,7 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
private boolean fpsMode = false;
|
||||
private final Entity playerEntity;
|
||||
private ComponentPositionPlayer playerPosition;
|
||||
private ComponentPhysics playerPhysics;
|
||||
private final ComponentPlayer player;
|
||||
private boolean moveUp = false;
|
||||
private boolean moveDown = false;
|
||||
@ -32,6 +34,8 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
this.playerEntity = playerEntity;
|
||||
if (this.playerEntity.exist("position")) {
|
||||
this.playerPosition = (ComponentPositionPlayer) this.playerEntity.getComponent("position");
|
||||
} else if (this.playerEntity.exist("physics")) {
|
||||
this.playerPhysics = (ComponentPhysics) this.playerEntity.getComponent("physics");
|
||||
}
|
||||
this.player = (ComponentPlayer) this.playerEntity.getComponent("player");
|
||||
}
|
||||
@ -142,6 +146,8 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
this.playerPosition.setAngles(new Vector3f(0, 0, tmpAngle));
|
||||
this.camera.setRoll(-playerZAngle);
|
||||
Log.info("Change camera: " + this.camera.getYaw() + " " + this.camera.getPitch());
|
||||
} else if (this.playerPhysics != null) {
|
||||
//this.playerPhysics.applyTorque(new Vector3f(0, 0, (float) Math.toRadians(delta.x * this.player.getTurnSpeed())));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -149,6 +155,9 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
|
||||
@Override
|
||||
public void periodicCall(final EventTime event) {
|
||||
if (this.playerPhysics != null) {
|
||||
//this.camera.setRoll(-this.playerPhysics.getAngles().z);
|
||||
}
|
||||
float speed = 0;
|
||||
float walkFactor = 1;
|
||||
if (this.walk) {
|
||||
@ -168,6 +177,9 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
if (this.playerPosition != null) {
|
||||
playerZAngle = this.playerPosition.getAngles().z();
|
||||
playerTransform = this.playerPosition.getTransform();
|
||||
} else if (this.playerPhysics != null) {
|
||||
playerZAngle = 0; // TODO ...
|
||||
playerTransform = this.playerPhysics.getTransform();
|
||||
}
|
||||
final float dx = -(float) (distance * Math.sin(playerZAngle));
|
||||
final float dy = (float) (distance * Math.cos(playerZAngle));
|
||||
@ -188,6 +200,8 @@ public class ControlCameraPlayer implements ControlInterface {
|
||||
playerTransform = playerTransform.withPosition(tmpPos);
|
||||
if (this.playerPosition != null) {
|
||||
this.playerPosition.setTransform(playerTransform);
|
||||
} else if (this.playerPhysics != null) {
|
||||
this.playerPhysics.setTransform(playerTransform);
|
||||
}
|
||||
// here the camera is behind the player, we need to move the camera ...
|
||||
//Log.info(" pitch: " + Math.toDegrees(this.camera.getPitch()) + " " + Math.toDegrees(playerZAngle));
|
||||
|
@ -13,7 +13,7 @@ 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,7 +72,7 @@ public class Environement {
|
||||
addEngine(new EngineDynamicMeshs(this));
|
||||
addEngine(new EngineRender(this));
|
||||
//addEngine(new EnginePhysics(this));
|
||||
addEngine(new EnginePhysics(this));
|
||||
addEngine(new EnginePhysicsPerso(this));
|
||||
addEngine(new EngineParticle(this));
|
||||
addEngine(new EngineLight(this));
|
||||
this.startClock = Clock.systemUTC();
|
||||
|
@ -1,492 +1,574 @@
|
||||
package org.atriasoft.ege.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.atriasoft.ege.Component;
|
||||
import org.atriasoft.ege.Environement;
|
||||
import org.atriasoft.ege.engines.EngineGravity;
|
||||
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.ephysics.body.BodyType;
|
||||
import org.atriasoft.ephysics.body.RigidBody;
|
||||
import org.atriasoft.ephysics.collision.ProxyShape;
|
||||
import org.atriasoft.ephysics.collision.TriangleMesh;
|
||||
import org.atriasoft.ephysics.collision.TriangleVertexArray;
|
||||
import org.atriasoft.ephysics.collision.shapes.BoxShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.CapsuleShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.CollisionShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.ConcaveMeshShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.ConcaveShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.ConeShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.CylinderShape;
|
||||
import org.atriasoft.ephysics.collision.shapes.SphereShape;
|
||||
import org.atriasoft.etk.Color;
|
||||
import org.atriasoft.etk.math.FMath;
|
||||
import org.atriasoft.etk.math.Matrix4f;
|
||||
import org.atriasoft.etk.math.Quaternion;
|
||||
import org.atriasoft.etk.math.Transform3D;
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
import org.atriasoft.gale.resource.ResourceColored3DObject;
|
||||
import org.atriasoft.phyligram.ColisionPoint;
|
||||
import org.atriasoft.phyligram.PhysicBox;
|
||||
import org.atriasoft.phyligram.PhysicHeightMapChunk;
|
||||
import org.atriasoft.phyligram.PhysicMapVoxel;
|
||||
import org.atriasoft.phyligram.PhysicShape;
|
||||
import org.atriasoft.phyligram.PhysicSphere;
|
||||
import org.atriasoft.phyligram.PhysicTriangle;
|
||||
import org.atriasoft.phyligram.math.ToolCollisionOBBWithOBB;
|
||||
import org.atriasoft.phyligram.math.ToolCollisionSphereWithHeightMapChunk;
|
||||
import org.atriasoft.phyligram.math.ToolCollisionSphereWithSphere;
|
||||
import org.atriasoft.phyligram.math.ToolCollisionSphereWithTriangle;
|
||||
import org.atriasoft.phyligram.shape.AABB;
|
||||
import org.atriasoft.phyligram.shape.Box;
|
||||
import org.atriasoft.phyligram.shape.Capsule;
|
||||
import org.atriasoft.phyligram.shape.Concave;
|
||||
import org.atriasoft.phyligram.shape.Cone;
|
||||
import org.atriasoft.phyligram.shape.ConvexHull;
|
||||
import org.atriasoft.phyligram.shape.Cylinder;
|
||||
import org.atriasoft.phyligram.shape.Shape;
|
||||
import org.atriasoft.phyligram.shape.Sphere;
|
||||
|
||||
public class ComponentPhysics extends Component {
|
||||
public static float MINIMUM_BOUNCING_STOP = 0.0001f;
|
||||
//public static float ANGLE_MAX_BOUNCING = 0.02f;
|
||||
public static float globalMaxSpeed = Float.MAX_VALUE;
|
||||
private AABB aabb;
|
||||
private List<ComponentPhysics> aabbIntersection = new ArrayList<>();
|
||||
private Set<ComponentPhysics> collisionPrevious = new HashSet<>();
|
||||
private Map<ComponentPhysics, List<ColisionPoint>> collisionCurrent = new HashMap<>();
|
||||
//List<ColisionPoint> collisionPoints = new ArrayList<>();
|
||||
private List<PhysicShape> shapes = new ArrayList<>();
|
||||
// collision already exist ==> prepare friction:
|
||||
Transform3D previousPosition;
|
||||
private ComponentPosition position;
|
||||
private boolean manageGravity = true;
|
||||
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);
|
||||
// Apply dynamic force on it
|
||||
private Vector3f dynamicForceGlobal = new Vector3f(0, 0, 0);
|
||||
private EnginePhysics engine;
|
||||
private PhysicBodyType bodyType;
|
||||
public class ComponentPhysics extends Component implements PositionningInterface {
|
||||
public Signal<Transform3D> signalPosition = new Signal<>();
|
||||
protected Transform3D lastTransformEmit;
|
||||
protected EnginePhysics engine;
|
||||
protected RigidBody rigidBody;
|
||||
protected List<CollisionShape> listShape = new ArrayList<>();
|
||||
protected List<ProxyShape> listProxyShape = new ArrayList<>();
|
||||
|
||||
protected Vector3f staticForceApplyCenterOfMass = new Vector3f(0, 0, 0);
|
||||
|
||||
protected Vector3f staticTorqueApply = new Vector3f(0, 0, 0);
|
||||
|
||||
protected List<Shape> shape = new ArrayList<>(); //!< collision shape module ... (independent of bullet lib)
|
||||
|
||||
/**
|
||||
* Create a basic position component (no orientation and position (0,0,0))
|
||||
*/
|
||||
public ComponentPhysics(final Environement _env) {
|
||||
this.engine = (EnginePhysics) _env.getEngine(getType());
|
||||
// Initial position and orientation of the rigid body
|
||||
this.lastTransformEmit = new Transform3D(new Vector3f(0, 0, 0), Quaternion.IDENTITY);
|
||||
this.rigidBody = this.engine.getDynamicsWorld().createRigidBody(this.lastTransformEmit);
|
||||
this.rigidBody.setUserData(this);
|
||||
// set collision callback:
|
||||
//this.engine.getDynamicWorld().testCollision(this.rigidBody, this);
|
||||
this.rigidBody.getMaterial().setBounciness(0.0f);
|
||||
this.rigidBody.setAngularDamping(0.9f);
|
||||
this.rigidBody.setLinearDamping(0.9f);
|
||||
//this.rigidBody.getMaterial().setFrictionCoefficient(0.01f);
|
||||
//this.rigidBody.getMaterial().setRollingResistance(0.01f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic position component
|
||||
* @param _transform transformation of the position
|
||||
*/
|
||||
public ComponentPhysics(final Environement _env, final Transform3D _transform) {
|
||||
this.engine = (EnginePhysics) _env.getEngine(getType());
|
||||
// Create a rigid body in the world
|
||||
this.rigidBody = this.engine.getDynamicsWorld().createRigidBody(_transform);
|
||||
this.rigidBody.setUserData(this);
|
||||
this.lastTransformEmit = _transform;
|
||||
// set collision callback:
|
||||
//this.engine.getDynamicWorld().testCollision(this.rigidBody, this);
|
||||
Log.error("Bounciness=" + this.rigidBody.getMaterial().getBounciness());
|
||||
Log.error("FrictionCoefficient=" + this.rigidBody.getMaterial().getFrictionCoefficient());
|
||||
Log.error("RollingResistance=" + this.rigidBody.getMaterial().getRollingResistance());
|
||||
Log.error("LinearDamping=" + this.rigidBody.getLinearDamping());
|
||||
Log.error("AngularDamping=" + this.rigidBody.getAngularDamping());
|
||||
this.rigidBody.getMaterial().setBounciness(0.0f);
|
||||
//this.rigidBody.getMaterial().setFrictionCoefficient(0.01f);
|
||||
//this.rigidBody.getMaterial().setRollingResistance(0.01f);
|
||||
this.rigidBody.setAngularDamping(0.9f);
|
||||
this.rigidBody.setLinearDamping(0.9f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFriendComponent(Component component) {
|
||||
if (component.getType().contentEquals("position")) {
|
||||
if (component instanceof ComponentPosition tmp) {
|
||||
this.position = tmp;
|
||||
} else {
|
||||
Log.error("Not manage position model...");
|
||||
}
|
||||
public void addFriendComponent(final Component component) {
|
||||
if (component.getType().contains("position")) {
|
||||
Log.critical("Can not add a 'physic' component and a 'position' component ... ==> incompatible");
|
||||
}
|
||||
}
|
||||
|
||||
public void addIntersection(ComponentPhysics component) {
|
||||
// do not add multiple times
|
||||
if (this.aabbIntersection.contains(component)) {
|
||||
public void addShape(final Shape _shape) {
|
||||
this.shape.add(_shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an external force to the body at a given point (in world-space coordinates).
|
||||
* If the point is not at the center of mass of the body, it will also generate some torque and therefore, change the angular velocity of the body.
|
||||
* If the body is sleeping, calling this method will wake it up. Note that the force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing.
|
||||
* @param _force The force to apply on the body
|
||||
* @param _point The point where the force is applied (in world-space coordinates)
|
||||
*/
|
||||
public void applyForce(final Vector3f _force, final Vector3f _point) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.aabbIntersection.add(component);
|
||||
this.rigidBody.applyForce(_force, _point);
|
||||
}
|
||||
|
||||
public void addShape(PhysicShape shape) {
|
||||
this.shapes.add(shape);
|
||||
/**
|
||||
* Apply an external force to the body at its center of mass.
|
||||
* If the body is sleeping, calling this method will wake it up.
|
||||
* @note The force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing.
|
||||
* @param _force The external force to apply on the center of mass of the body
|
||||
*/
|
||||
public void applyForceToCenterOfMass(final Vector3f _force) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.rigidBody.applyForceToCenterOfMass(_force);
|
||||
}
|
||||
|
||||
public void applyColisionForce(float timeStep) {
|
||||
for (Entry<ComponentPhysics, List<ColisionPoint>> elem : this.collisionCurrent.entrySet()) {
|
||||
Float globalBouncing = null;
|
||||
if (!this.collisionPrevious.contains(elem.getKey())) {
|
||||
globalBouncing = elem.getKey().getBouncingCoefficient();
|
||||
public void applyForceToCenterOfMassStatic(final Vector3f _force) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.staticForceApplyCenterOfMass = _force;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an external force to the body at its center of mass.
|
||||
* If the body is sleeping, calling this method will wake it up.
|
||||
* @note The force is apply with a relative axis of the object
|
||||
* @note The force will we added to the sum of the applied forces and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing.
|
||||
* @param _force The external force to apply on the center of mass of the body
|
||||
*/
|
||||
public void applyRelativeForceToCenterOfMass(final Vector3f _force) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
final Vector3f force = this.rigidBody.getTransform().getOrientation().multiply(_force);
|
||||
this.rigidBody.applyForceToCenterOfMass(force);
|
||||
}
|
||||
|
||||
public void applyRelativeForceToCenterOfMassStatic(final Vector3f _force) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.staticForceApplyCenterOfMass = this.rigidBody.getTransform().getOrientation().multiply(_force);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an external torque to the body.
|
||||
* If the body is sleeping, calling this method will wake it up.
|
||||
* @note The torque is apply with a relative axis of the object
|
||||
* @note The force will we added to the sum of the applied torques and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing.
|
||||
* @param _torque The external torque to apply on the body
|
||||
*/
|
||||
public void applyRelativeTorque(final Vector3f _torque) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
final Vector3f torque = this.rigidBody.getTransform().getOrientation().multiply(_torque);
|
||||
this.rigidBody.applyTorque(torque);
|
||||
}
|
||||
|
||||
public void applyRelativeTorqueStatic(final Vector3f _torque) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.staticTorqueApply = this.rigidBody.getTransform().getOrientation().multiply(_torque);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an external torque to the body.
|
||||
* If the body is sleeping, calling this method will wake it up.
|
||||
* @note The force will we added to the sum of the applied torques and that this sum will be reset to zero at the end of each call of the DynamicsWorld::update() method. You can only apply a force to a dynamic body otherwise, this method will do nothing.
|
||||
* @param _torque The external torque to apply on the body
|
||||
*/
|
||||
public void applyTorque(final Vector3f _torque) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.rigidBody.applyTorque(_torque);
|
||||
}
|
||||
|
||||
public void applyTorqueStatic(final Vector3f _torque) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.staticTorqueApply = _torque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new contact point is found between two bodies that were separated before.
|
||||
* @param _other The other component that have the impact
|
||||
* @param _normal Normal of the impact
|
||||
* @param _pos Position of the impact at the current object
|
||||
* @param _posOther Position of the impact at the other object
|
||||
* @param _penetrationDepth Depth penetration in the object
|
||||
*/
|
||||
public void beginContact(final Component _other, final Vector3f _normal, final Vector3f _pos, final Vector3f _posOther, final float _penetrationDepth) {
|
||||
Log.warning(" collision [BEGIN] " + _pos + " depth=" + _penetrationDepth);
|
||||
}
|
||||
|
||||
public void drawShape(final ResourceColored3DObject _draw, final Camera _camera) {
|
||||
final Transform3D transform = getTransform();
|
||||
//final float[] mmm = new float[16];
|
||||
// Get the OpenGL matrix array of the transform
|
||||
final Matrix4f mmm = transform.getOpenGLMatrix();
|
||||
|
||||
final Matrix4f transformationMatrix = mmm.transpose();
|
||||
final Color tmpColor = new Color(1.0f, 0.0f, 0.0f, 0.3f);
|
||||
for (final Shape it : this.shape) {
|
||||
if (it instanceof Box tmpElement) {
|
||||
Log.debug(" Box");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
|
||||
_draw.drawSquare(tmpElement.getSize(), transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof Cylinder tmpElement) {
|
||||
Log.debug(" Cylinder");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
|
||||
_draw.drawCylinder(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof Capsule tmpElement) {
|
||||
Log.debug(" Capsule");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
|
||||
_draw.drawCapsule(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof Cone tmpElement) {
|
||||
Log.debug(" Cone");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
|
||||
_draw.drawCone(tmpElement.getRadius(), tmpElement.getSize(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof Sphere tmpElement) {
|
||||
|
||||
Log.debug(" Sphere");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrix.multiply(transformationMatrixLocal);
|
||||
_draw.drawSphere(tmpElement.getRadius(), 10, 10, transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof Concave tmpElement) {
|
||||
|
||||
Log.debug(" concave");
|
||||
final Transform3D transformLocal = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
|
||||
Matrix4f transformationMatrixLocal = transformLocal.getOpenGLMatrix();
|
||||
transformationMatrixLocal = transformationMatrixLocal.transpose();
|
||||
transformationMatrixLocal = transformationMatrixLocal.multiply(transformationMatrixLocal);
|
||||
|
||||
_draw.drawTriangles(tmpElement.getVertex(), tmpElement.getIndices(), transformationMatrixLocal, tmpColor);
|
||||
} else if (it instanceof ConvexHull tmpElement) {
|
||||
Log.debug(" convexHull");
|
||||
break;
|
||||
}
|
||||
float globalFriction = elem.getKey().getFrictionCoefficient();
|
||||
Vector3f globalForce = Vector3f.ZERO;
|
||||
for (ColisionPoint impact : elem.getValue()) {
|
||||
globalForce = globalForce.add(impact.force);
|
||||
}
|
||||
// nothing to apply ?
|
||||
if (globalForce == Vector3f.ZERO) {
|
||||
}
|
||||
}
|
||||
|
||||
// call done after all cycle update of the physical engine
|
||||
public void emitAll() {
|
||||
// emit only of new ...
|
||||
final Transform3D transform = getTransform();
|
||||
if (this.lastTransformEmit != transform) {
|
||||
this.lastTransformEmit = transform;
|
||||
this.signalPosition.emit(transform);
|
||||
}
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
if (this.shape.size() == 0) {
|
||||
Log.warning("No Shape Availlable ...");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: support more than one shape for each elements... (ProxyShape)
|
||||
for (final Shape it : this.shape) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
// when tuch a kinematy force is divide between the two
|
||||
if (elem.getKey().getBodyType() == PhysicBodyType.BODY_DYNAMIC) {
|
||||
globalForce = globalForce.multiply(0.5f);
|
||||
}
|
||||
if (globalBouncing != null) {
|
||||
// detect new collision ==> apply bouncing
|
||||
if (this.speed.length2() < MINIMUM_BOUNCING_STOP) {
|
||||
this.speed = Vector3f.ZERO;
|
||||
} else {
|
||||
// this force is not depending on the mass...
|
||||
this.speed = this.speed.reflect(globalForce.normalize()).multiply(globalBouncing); // apply the bouncing...
|
||||
}
|
||||
this.position.applyForce(globalForce);
|
||||
if (it instanceof Box tmpElement) {
|
||||
Log.debug(" Box");
|
||||
// Half extents of the box in the x, y and z directions
|
||||
final Vector3f halfExtents = new Vector3f(tmpElement.getSize().x(), tmpElement.getSize().y(), tmpElement.getSize().z());
|
||||
// Create the box shape
|
||||
final BoxShape shape = new BoxShape(halfExtents, 0.0001f);
|
||||
this.listShape.add(shape);
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
//orientation = orientation * ephysics::Quaternion(-0.707107, 0, 0, 0.707107);
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else if (it instanceof Cylinder tmpElement) {
|
||||
Log.debug(" Cylinder");
|
||||
// Create the Cylinder shape
|
||||
// Create the Cylinder shape
|
||||
final CylinderShape shape = new CylinderShape(tmpElement.getRadius(), tmpElement.getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
final Quaternion orientation = it.getOrientation().multiply(new Quaternion(-0.707107f, 0.0f, 0.0f, 0.707107f));
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), orientation);
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else if (it instanceof Capsule tmpElement) {
|
||||
Log.debug(" Capsule");
|
||||
// Create the Capsule shape
|
||||
final CapsuleShape shape = new CapsuleShape(tmpElement.getRadius(), tmpElement.getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
final Quaternion orientation = it.getOrientation().multiply(new Quaternion(-0.707107f, 0.0f, 0.0f, 0.707107f));
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), orientation);
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else if (it instanceof Cone tmpElement) {
|
||||
Log.debug(" Cone");
|
||||
// Create the Cone shape
|
||||
final ConeShape shape = new ConeShape(tmpElement.getRadius(), tmpElement.getSize());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
final Quaternion orientation = it.getOrientation().multiply(new Quaternion(-0.707107f, 0.0f, 0.0f, 0.707107f));
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), orientation);
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else if (it instanceof Sphere tmpElement) {
|
||||
Log.debug(" Sphere");
|
||||
// Create the box shape
|
||||
final SphereShape shape = new SphereShape(tmpElement.getRadius());
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
final Quaternion orientation = it.getOrientation().multiply(new Quaternion(-0.707107f, 0.0f, 0.0f, 0.707107f));
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), orientation);
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else if (it instanceof Concave tmpElement) {
|
||||
Log.debug(" Concave");
|
||||
//static etk::Vector<Vector3f> vertices = {Vector3f(-100.0f,-100.0f,-50.0f),Vector3f(100.0f,-100.0f,-50.0f),Vector3f(100.0f,100.0f,-50.0f)};
|
||||
//static etk::Vector<uint32_t> indices = {0,1,2};
|
||||
|
||||
//ephysics::TriangleVertexArray* triangleArray = ETK_NEW(ephysics::TriangleVertexArray, vertices, indices);
|
||||
final TriangleVertexArray triangleArray = new TriangleVertexArray(tmpElement.getVertex(), tmpElement.getIndices());
|
||||
// Now that we have a TriangleVertexArray, we need to create a TriangleMesh and add the TriangleVertexArray into it as a subpart.
|
||||
// Once this is done, we can create the actual ConcaveMeshShape and add it to the body we want to simulate as in the following example:
|
||||
final TriangleMesh triangleMesh = new TriangleMesh();
|
||||
// Add the triangle vertex array to the triangle mesh
|
||||
triangleMesh.addSubpart(triangleArray);
|
||||
// Create the concave mesh shape
|
||||
// TODO : Manage memory leak ...
|
||||
final ConcaveShape shape = new ConcaveMeshShape(triangleMesh);
|
||||
// The ephysic use Y as UP ==> ege use Z as UP
|
||||
final Quaternion orientation = it.getOrientation().multiply(new Quaternion(-0.707107f, 0.0f, 0.0f, 0.707107f));
|
||||
final Transform3D transform = new Transform3D(it.getOrigin(), it.getOrientation());
|
||||
final ProxyShape proxyShape = this.rigidBody.addCollisionShape(shape, transform, it.getMass());
|
||||
proxyShape.setUserData(this);
|
||||
this.listProxyShape.add(proxyShape);
|
||||
} else {
|
||||
// second consecutive time off collision ==> friction ...
|
||||
this.position.applyForce(globalForce);
|
||||
this.speed = this.position.getTransform().getPosition().less(this.previousPosition.getPosition());//.divide(timeStep);
|
||||
globalFriction = 1.0f - FMath.avg(0.0f, globalFriction, 1.0f) * timeStep;
|
||||
this.speed = this.speed.multiply(globalFriction);
|
||||
Log.debug(" ???");
|
||||
// TODO UNKNOWN type ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyForces(float timeStep, EngineGravity gravity) {
|
||||
// get the gravity at the specific position...
|
||||
Vector3f gravityAcceleration;
|
||||
if (this.manageGravity) {
|
||||
gravityAcceleration = gravity.getGravityAtPosition(this.position.getTransform().getPosition());
|
||||
} else {
|
||||
gravityAcceleration = new Vector3f(0, 0, 0);
|
||||
}
|
||||
// apply this force on the Object
|
||||
Log.info("apply gravity: " + gravityAcceleration);
|
||||
// relative to the object
|
||||
Vector3f staticForce = this.staticForce;
|
||||
float globalMass = 0;
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
globalMass += shape.getMass();
|
||||
}
|
||||
// note the acceleration is not real, it depend on the current delta time...
|
||||
Vector3f staticforceOriented = this.position.getTransform().getOrientation().multiply(staticForce);
|
||||
Vector3f dynamicforceOriented = this.position.getTransform().getOrientation().multiply(this.dynamicForce);
|
||||
Vector3f globalForce = staticforceOriented.add(dynamicforceOriented);
|
||||
if (globalMass > 0.0) {
|
||||
globalForce = globalForce.divide(globalMass);
|
||||
} else {
|
||||
gravityAcceleration = Vector3f.ZERO;
|
||||
}
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
gravityAcceleration = Vector3f.ZERO;
|
||||
}
|
||||
this.acceleration = gravityAcceleration.add(globalForce);
|
||||
this.speed = this.speed.add(this.acceleration.multiply(timeStep));
|
||||
limitWithMaxSpeed();
|
||||
Log.info("apply acceleration: " + this.acceleration);
|
||||
Log.info("apply speed: " + this.speed);
|
||||
this.position.setTransform(this.position.getTransform().withPosition(this.position.getTransform().getPosition().add(this.speed)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
public void applyColisionForce(float timeStep) {
|
||||
Vector3f globalForce = Vector3f.ZERO;
|
||||
float globalBouncing = 1.0f;
|
||||
this.haveBouncing = false;
|
||||
for (Entry<ComponentPhysics, List<ColisionPoint>> elem : this.collisionCurrent.entrySet()) {
|
||||
if (!this.collisionPrevious.contains(elem.getKey())) {
|
||||
this.haveBouncing = true;
|
||||
globalBouncing = FMath.min(globalBouncing, elem.getKey().getBouncingCoefficient());
|
||||
}
|
||||
for (ColisionPoint impact : elem.getValue()) {
|
||||
globalForce = globalForce.add(impact.force);
|
||||
}
|
||||
}
|
||||
if (globalForce == Vector3f.ZERO) {
|
||||
return;
|
||||
}
|
||||
if (this.haveBouncing) {
|
||||
// detect new collision ==> apply bouncing
|
||||
if (this.speed.length2() < MINIMUM_BOUNCING_STOP) {
|
||||
this.speed = Vector3f.ZERO;
|
||||
} else {
|
||||
// this force is not depending on the mass...
|
||||
this.speed = this.speed.reflect(globalForce.normalize()).multiply(globalBouncing); // apply the bouncing...
|
||||
}
|
||||
this.position.applyForce(globalForce);
|
||||
} else {
|
||||
this.position.applyForce(globalForce);
|
||||
this.speed = this.position.getTransform().getPosition().less(this.previousPosition.getPosition());//.divide(timeStep);
|
||||
}
|
||||
}
|
||||
|
||||
public void applyFriction(float timeStep) {
|
||||
if (this.collisionCurrent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
float globalFriction = 0.0f;
|
||||
for (Entry<ComponentPhysics, List<ColisionPoint>> elem : this.collisionCurrent.entrySet()) {
|
||||
globalFriction += elem.getKey().getFrictionCoefficient();
|
||||
}
|
||||
globalFriction = 1.0f - FMath.avg(0.0f, globalFriction, 1.0f) * timeStep;
|
||||
if (!this.haveBouncing) {
|
||||
this.speed = this.speed.multiply(globalFriction); // c'est ini qu'il faut mettre en place l'absortion complète
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the angular velocity (whole world).
|
||||
* @return The angular velocity vector of the body
|
||||
*/
|
||||
|
||||
private boolean checkCollide(PhysicShape shapeCurrent) {
|
||||
if (shapeCurrent instanceof PhysicBox shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicHeightMapChunk shape222) {
|
||||
// detect collision from cube on height-map !!!
|
||||
|
||||
} else if (shape instanceof PhysicBox shape222) {
|
||||
// detect collision between 2 cubes
|
||||
if (ToolCollisionOBBWithOBB.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else if (shapeCurrent instanceof PhysicSphere shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicHeightMapChunk shape222) {
|
||||
// detect collision from sphere on height-map !!!
|
||||
if (ToolCollisionSphereWithHeightMapChunk.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicTriangle shape222) {
|
||||
// detect collision from sphere on height-map !!!
|
||||
if (ToolCollisionSphereWithTriangle.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicBox shape222) {
|
||||
// detect collision from sphere on cube !!!
|
||||
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
// detect collision from sphere on sphere !!!
|
||||
if (ToolCollisionSphereWithSphere.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else if (shapeCurrent instanceof PhysicMapVoxel shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicBox shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shapeCurrent);
|
||||
public Vector3f getAngularVelocity() {
|
||||
if (this.rigidBody == null) {
|
||||
return new Vector3f(0, 0, 0);
|
||||
}
|
||||
return false;
|
||||
return this.rigidBody.getAngularVelocity();
|
||||
}
|
||||
|
||||
public boolean checkNarrowCollision() {
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
return false;
|
||||
/**
|
||||
* Get the linear velocity (whole world).
|
||||
* @return The linear velocity vector of the body
|
||||
*/
|
||||
public Vector3f getLinearVelocity() {
|
||||
if (this.rigidBody == null) {
|
||||
return new Vector3f(0, 0, 0);
|
||||
}
|
||||
for (ComponentPhysics elem : this.aabbIntersection) {
|
||||
boolean collide = false;
|
||||
for (PhysicShape shapeCurrent : this.shapes) {
|
||||
if (elem.checkCollide(shapeCurrent)) {
|
||||
collide = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (collide) {
|
||||
if (!this.collisionCurrent.containsKey(elem)) {
|
||||
this.collisionCurrent.put(elem, new ArrayList<>());
|
||||
}
|
||||
if (!elem.collisionCurrent.containsKey(this)) {
|
||||
elem.collisionCurrent.put(this, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
return this.rigidBody.getLinearVelocity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the angular velocity (local Body).
|
||||
* @return The angular velocity vector of the body
|
||||
*/
|
||||
public Vector3f getRelativeAngularVelocity() {
|
||||
if (this.rigidBody == null) {
|
||||
return new Vector3f(0, 0, 0);
|
||||
}
|
||||
return isNarrowCollide();
|
||||
final Vector3f value = this.rigidBody.getAngularVelocity();
|
||||
return this.rigidBody.getTransform().getOrientation().inverse().multiply(value);
|
||||
}
|
||||
|
||||
public void clearAABBIntersection() {
|
||||
this.aabbIntersection.clear();
|
||||
}
|
||||
|
||||
public void clearPreviousCollision() {
|
||||
// store the previous list of collide elements
|
||||
this.collisionPrevious = new HashSet<>(this.collisionCurrent.keySet());
|
||||
this.previousPosition = this.position.getTransform();
|
||||
this.aabbIntersection.clear();
|
||||
this.collisionCurrent.clear();
|
||||
}
|
||||
|
||||
public void clearShape() {
|
||||
this.shapes.clear();
|
||||
}
|
||||
|
||||
public AABB getAABB() {
|
||||
return this.aabb;
|
||||
}
|
||||
|
||||
public List<ComponentPhysics> getAabbIntersection() {
|
||||
return this.aabbIntersection;
|
||||
}
|
||||
|
||||
public PhysicBodyType getBodyType() {
|
||||
return this.bodyType;
|
||||
}
|
||||
|
||||
private float getBouncingCoefficient() {
|
||||
float total = 0.0f;
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
total = FMath.max(total, shape.getBouncingCoefficient());
|
||||
/**
|
||||
* Get the linear velocity (local Body).
|
||||
* @return The linear velocity vector of the body
|
||||
*/
|
||||
public Vector3f getRelativeLinearVelocity() {
|
||||
if (this.rigidBody == null) {
|
||||
return new Vector3f(0, 0, 0);
|
||||
}
|
||||
return total;
|
||||
final Vector3f value = this.rigidBody.getLinearVelocity();
|
||||
return this.rigidBody.getTransform().getOrientation().inverse().multiply(value);
|
||||
}
|
||||
|
||||
private List<ColisionPoint> getCollidePoints(PhysicShape shapeRemote) {
|
||||
List<ColisionPoint> out = new ArrayList<>();
|
||||
if (shapeRemote instanceof PhysicSphere remoteShere) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicSphere localShape) {
|
||||
ColisionPoint point = ToolCollisionSphereWithSphere.getCollisionPoint(remoteShere, localShape);
|
||||
if (point != null) {
|
||||
out.add(point);
|
||||
}
|
||||
} else if (shape instanceof PhysicTriangle localShape) {
|
||||
ColisionPoint point = ToolCollisionSphereWithTriangle.getCollisionPoint(remoteShere, localShape);
|
||||
if (point != null) {
|
||||
out.add(point);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else if (shapeRemote instanceof PhysicTriangle) {
|
||||
// nothing can happens ...
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shapeRemote);
|
||||
public List<Shape> getShape() {
|
||||
return this.shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a new transformation
|
||||
* @return Transformation of the position
|
||||
*/
|
||||
@Override
|
||||
public Transform3D getTransform() {
|
||||
if (this.rigidBody == null) {
|
||||
return Transform3D.IDENTITY;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public float getFrictionCoefficient() {
|
||||
float total = 0.0f;
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
total = FMath.max(total, shape.getFrictionCoefficient());
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public float getMaxSpeed() {
|
||||
return this.maxSpeed;
|
||||
return this.rigidBody.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return EnginePhysics.ENGINE_NAME;
|
||||
return "physics";
|
||||
}
|
||||
|
||||
public boolean isManageGravity() {
|
||||
return this.manageGravity;
|
||||
/**
|
||||
* Called when a new contact point is found between two bodies.
|
||||
* @param _other The other component that have the impact
|
||||
* @param _normal Normal of the impact
|
||||
* @param _pos Position of the impact at the current object
|
||||
* @param _posOther Position of the impact at the other object
|
||||
* @param _penetrationDepth Depth penetration in the object
|
||||
*/
|
||||
public void newContact(final Component _other, final Vector3f _normal, final Vector3f _pos, final Vector3f _posOther, final float _penetrationDepth) {
|
||||
Log.warning(" collision [ NEW ] " + _pos + " depth=" + _penetrationDepth);
|
||||
}
|
||||
|
||||
public boolean isNarrowCollide() {
|
||||
if (this.collisionCurrent.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
public void renderDebug(final ResourceColored3DObject _draw, final Camera _camera) {
|
||||
if (this.rigidBody == null) {}
|
||||
/*
|
||||
final Matrix4f transformationMatrix = Matrix4f.IDENTITY;
|
||||
final Color tmpColor = new Color(0.0f, 1.0f, 0.0f, 0.8f);
|
||||
final AABB value = this.rigidBody.getAABB();
|
||||
_draw.drawCubeLine(value.getMin(), value.getMax(), tmpColor, transformationMatrix, true, true);
|
||||
*/
|
||||
}
|
||||
|
||||
private void limitWithMaxSpeed() {
|
||||
if (this.speed.length2() > this.maxSpeed * this.maxSpeed) {
|
||||
this.speed = this.speed.safeNormalize().multiply(this.maxSpeed);
|
||||
}
|
||||
public void setAngularReactionEnable(final boolean value) {
|
||||
this.rigidBody.setAngularReactionEnable(value);
|
||||
}
|
||||
|
||||
public void narrowCollisionCreateContactAndForce() {
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
/**
|
||||
* Set the angular velocity (whole world).
|
||||
* @param _angularVelocity The angular velocity vector of the body
|
||||
*/
|
||||
public void setAngularVelocity(final Vector3f _angularVelocity) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
if (this.collisionCurrent.size() == 0) {
|
||||
this.rigidBody.setAngularVelocity(_angularVelocity);
|
||||
}
|
||||
|
||||
public void setBodyType(final PhysicBodyType _type) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
for (Entry<ComponentPhysics, List<ColisionPoint>> elem : this.collisionCurrent.entrySet()) {
|
||||
for (PhysicShape shapeCurrent : this.shapes) {
|
||||
//TODO Do a better method we do this many times ...
|
||||
/*
|
||||
if (!elem.checkCollide(shapeCurrent)) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
List<ColisionPoint> points = elem.getKey().getCollidePoints(shapeCurrent);
|
||||
elem.getValue().addAll(points);
|
||||
}
|
||||
switch (_type) {
|
||||
case BODY_STATIC -> this.rigidBody.setType(BodyType.STATIC);
|
||||
case BODY_KINEMATIC -> this.rigidBody.setType(BodyType.KINEMATIC);
|
||||
case BODY_DYNAMIC -> this.rigidBody.setType(BodyType.DYNAMIC);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriendComponent(Component component) {
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
public void renderDebug(ResourceColored3DObject debugDrawProperty) {
|
||||
Color displayColor;
|
||||
displayColor = new Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
for (Entry<ComponentPhysics, List<ColisionPoint>> elem : this.collisionCurrent.entrySet()) {
|
||||
for (ColisionPoint impact : elem.getValue()) {
|
||||
debugDrawProperty.drawSquare(new Vector3f(0.02f, 0.02f, 0.02f), Matrix4f.createMatrixTranslate(impact.position), displayColor);
|
||||
}
|
||||
}
|
||||
if (this.aabbIntersection.size() == 0) {
|
||||
displayColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
} else {
|
||||
if (this.collisionCurrent.size() == 0) {
|
||||
displayColor = new Color(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
displayColor = new Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
if (this.aabb != null) {
|
||||
debugDrawProperty.drawCubeLine(this.aabb.getMin(), this.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 : this.shapes) {
|
||||
shape.renderDebug(this.position.getTransform(), debugDrawProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setBodyType(PhysicBodyType bodyType) {
|
||||
this.bodyType = bodyType;
|
||||
}
|
||||
|
||||
public void setManageGravity(boolean manageGravity) {
|
||||
this.manageGravity = manageGravity;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(float maxSpeed) {
|
||||
this.maxSpeed = maxSpeed;
|
||||
}
|
||||
|
||||
public void updateAABB() {
|
||||
|
||||
if (this.position == null) {
|
||||
Log.info("No position in Entity ");
|
||||
/**
|
||||
* Set the linear velocity (whole world).
|
||||
* @param _linearVelocity The linear velocity vector of the body
|
||||
*/
|
||||
public void setLinearVelocity(final Vector3f _linearVelocity) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
// TODO Add a flag to check if it is needed to update the AABB...
|
||||
AABB aabbNew = AABB.createInvertedEmpty();
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
shape.updateAABB(this.position.getTransform(), aabbNew);
|
||||
}
|
||||
this.aabb = aabbNew;
|
||||
this.rigidBody.setLinearVelocity(_linearVelocity);
|
||||
}
|
||||
|
||||
public void updateForNarrowCollision() {
|
||||
this.collisionCurrent.clear();
|
||||
if (this.aabbIntersection.size() == 0) {
|
||||
/**
|
||||
* Set the angular velocity (local Body).
|
||||
* @param _angularVelocity The angular velocity vector of the body
|
||||
*/
|
||||
public void setRelativeAngularVelocity(final Vector3f _angularVelocity) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
if (this.position == null) {
|
||||
Log.info("No position in Entity ");
|
||||
final Vector3f value = this.rigidBody.getTransform().getOrientation().multiply(_angularVelocity);
|
||||
this.rigidBody.setAngularVelocity(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the linear velocity (local Body).
|
||||
* @param _linearVelocity The linear velocity vector of the body
|
||||
*/
|
||||
public void setRelativeLinearVelocity(final Vector3f _linearVelocity) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
shape.updateForNarrowCollision(this.position.getTransform());
|
||||
final Vector3f value = this.rigidBody.getTransform().getOrientation().multiply(_linearVelocity);
|
||||
this.rigidBody.setLinearVelocity(value);
|
||||
}
|
||||
|
||||
public void setShape(final List<Shape> _prop) {
|
||||
this.shape = _prop;
|
||||
}
|
||||
|
||||
public void setSleepingEnable(final boolean value) {
|
||||
this.rigidBody.setIsAllowedToSleep(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* set a new transformation
|
||||
* @param _transform transformation of the position
|
||||
*/
|
||||
public void setTransform(final Transform3D _transform) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
this.rigidBody.setTransform(_transform);
|
||||
}
|
||||
|
||||
// call of this function every time the call will be done
|
||||
public void update(final float _delta) {
|
||||
if (this.rigidBody == null) {
|
||||
return;
|
||||
}
|
||||
if (!this.staticForceApplyCenterOfMass.isZero()) {
|
||||
final Vector3f tmp = this.staticForceApplyCenterOfMass.multiply(_delta);
|
||||
Log.error("FORCE : " + tmp);
|
||||
this.rigidBody.applyForceToCenterOfMass(tmp);
|
||||
}
|
||||
if (!this.staticTorqueApply.isZero()) {
|
||||
final Vector3f tmp = this.staticTorqueApply.multiply(_delta);
|
||||
Log.error("TORQUE : " + tmp);
|
||||
this.rigidBody.applyTorque(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
390
src/org/atriasoft/ege/components/ComponentPhysicsPerso.java
Normal file
390
src/org/atriasoft/ege/components/ComponentPhysicsPerso.java
Normal file
@ -0,0 +1,390 @@
|
||||
package org.atriasoft.ege.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.atriasoft.ege.Component;
|
||||
import org.atriasoft.ege.Environement;
|
||||
import org.atriasoft.ege.engines.EngineGravity;
|
||||
import org.atriasoft.ege.engines.EnginePhysicsPerso;
|
||||
import org.atriasoft.ege.internal.Log;
|
||||
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.phyligram.ColisionPoint;
|
||||
import org.atriasoft.phyligram.PhysicBox;
|
||||
import org.atriasoft.phyligram.PhysicHeightMapChunk;
|
||||
import org.atriasoft.phyligram.PhysicMapVoxel;
|
||||
import org.atriasoft.phyligram.PhysicShape;
|
||||
import org.atriasoft.phyligram.PhysicSphere;
|
||||
import org.atriasoft.phyligram.PhysicTriangle;
|
||||
import org.atriasoft.phyligram.ToolCollisionOBBWithOBB;
|
||||
import org.atriasoft.phyligram.ToolCollisionSphereWithHeightMapChunk;
|
||||
import org.atriasoft.phyligram.ToolCollisionSphereWithSphere;
|
||||
import org.atriasoft.phyligram.ToolCollisionSphereWithTriangle;
|
||||
import org.atriasoft.phyligram.shape.AABB;
|
||||
|
||||
public class ComponentPhysicsPerso extends Component {
|
||||
public static float globalMaxSpeed = Float.MAX_VALUE;
|
||||
private AABB aabb;
|
||||
private List<ComponentPhysicsPerso> aabbIntersection = new ArrayList<>();
|
||||
private Map<ComponentPhysicsPerso, List<ColisionPoint>> narrowIntersection = new HashMap<>();
|
||||
//List<ColisionPoint> collisionPoints = new ArrayList<>();
|
||||
private List<PhysicShape> shapes = new ArrayList<>();
|
||||
private ComponentPosition position;
|
||||
private boolean manageGravity = true;
|
||||
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);
|
||||
// Apply dynamic force on it
|
||||
private Vector3f dynamicForceGlobal = new Vector3f(0, 0, 0);
|
||||
private EnginePhysicsPerso engine;
|
||||
private PhysicBodyType bodyType;
|
||||
|
||||
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) {
|
||||
this.position = tmp;
|
||||
} else {
|
||||
Log.error("Not manage position model...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addIntersection(ComponentPhysicsPerso component) {
|
||||
// do not add multiple times
|
||||
if (this.aabbIntersection.contains(component)) {
|
||||
return;
|
||||
}
|
||||
this.aabbIntersection.add(component);
|
||||
}
|
||||
|
||||
public void addShape(PhysicShape shape) {
|
||||
this.shapes.add(shape);
|
||||
}
|
||||
|
||||
public void applyColisionForce() {
|
||||
Vector3f globalForce = Vector3f.ZERO;
|
||||
for (Entry<ComponentPhysicsPerso, List<ColisionPoint>> elem : this.narrowIntersection.entrySet()) {
|
||||
for (ColisionPoint impact : elem.getValue()) {
|
||||
globalForce = globalForce.add(impact.force);
|
||||
}
|
||||
}
|
||||
// this force is not depending on the mass...
|
||||
this.speed = this.speed.add(globalForce);
|
||||
this.position.applyForce(globalForce);
|
||||
}
|
||||
|
||||
public void applyForces(float timeStep, EngineGravity gravity) {
|
||||
// get the gravity at the specific position...
|
||||
Vector3f gravityAcceleration;
|
||||
if (this.manageGravity) {
|
||||
gravityAcceleration = gravity.getGravityAtPosition(this.position.getTransform().getPosition());
|
||||
} else {
|
||||
gravityAcceleration = new Vector3f(0, 0, 0);
|
||||
}
|
||||
// apply this force on the Object
|
||||
Log.info("apply gravity: " + gravityAcceleration);
|
||||
// relative to the object
|
||||
Vector3f staticForce = this.staticForce;
|
||||
float globalMass = 0;
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
globalMass += shape.getMass();
|
||||
}
|
||||
// note the acceleration is not real, it depend on the current delta time...
|
||||
Vector3f staticforceOriented = this.position.getTransform().getOrientation().multiply(staticForce);
|
||||
Vector3f dynamicforceOriented = this.position.getTransform().getOrientation().multiply(this.dynamicForce);
|
||||
Vector3f globalForce = staticforceOriented.add(dynamicforceOriented);
|
||||
if (globalMass > 0.0) {
|
||||
globalForce = globalForce.divide(globalMass);
|
||||
} else {
|
||||
gravityAcceleration = Vector3f.ZERO;
|
||||
}
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
gravityAcceleration = Vector3f.ZERO;
|
||||
}
|
||||
this.acceleration = gravityAcceleration.add(globalForce);
|
||||
this.speed = this.speed.add(this.acceleration.multiply(timeStep));
|
||||
limitWithMaxSpeed();
|
||||
Log.info("apply acceleration: " + this.acceleration);
|
||||
Log.info("apply speed: " + this.speed);
|
||||
this.position.setTransform(this.position.getTransform().withPosition(this.position.getTransform().getPosition().add(this.speed)));
|
||||
}
|
||||
|
||||
private boolean checkCollide(PhysicShape shapeCurrent) {
|
||||
if (shapeCurrent instanceof PhysicBox shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicHeightMapChunk shape222) {
|
||||
// detect collision from cube on height-map !!!
|
||||
|
||||
} else if (shape instanceof PhysicBox shape222) {
|
||||
// detect collision between 2 cubes
|
||||
if (ToolCollisionOBBWithOBB.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else if (shapeCurrent instanceof PhysicSphere shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicHeightMapChunk shape222) {
|
||||
// detect collision from sphere on height-map !!!
|
||||
if (ToolCollisionSphereWithHeightMapChunk.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicTriangle shape222) {
|
||||
// detect collision from sphere on height-map !!!
|
||||
if (ToolCollisionSphereWithTriangle.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicBox shape222) {
|
||||
// detect collision from sphere on cube !!!
|
||||
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
// detect collision from sphere on sphere !!!
|
||||
if (ToolCollisionSphereWithSphere.testCollide(shape111, shape222)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else if (shapeCurrent instanceof PhysicMapVoxel shape111) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicBox shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicSphere shape222) {
|
||||
|
||||
} else if (shape instanceof PhysicMapVoxel shape222) {
|
||||
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shape);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shapeCurrent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkNarrowCollision() {
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
return false;
|
||||
}
|
||||
for (ComponentPhysicsPerso elem : this.aabbIntersection) {
|
||||
boolean collide = false;
|
||||
for (PhysicShape shapeCurrent : this.shapes) {
|
||||
if (elem.checkCollide(shapeCurrent)) {
|
||||
collide = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (collide) {
|
||||
if (!this.narrowIntersection.containsKey(elem)) {
|
||||
this.narrowIntersection.put(elem, new ArrayList<>());
|
||||
}
|
||||
if (!elem.narrowIntersection.containsKey(this)) {
|
||||
elem.narrowIntersection.put(this, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNarrowCollide();
|
||||
}
|
||||
|
||||
public void clearAABBIntersection() {
|
||||
this.aabbIntersection.clear();
|
||||
}
|
||||
|
||||
public void clearPreviousCollision() {
|
||||
this.aabbIntersection.clear();
|
||||
this.narrowIntersection.clear();
|
||||
}
|
||||
|
||||
public void clearShape() {
|
||||
this.shapes.clear();
|
||||
}
|
||||
|
||||
public AABB getAABB() {
|
||||
return this.aabb;
|
||||
}
|
||||
|
||||
public List<ComponentPhysicsPerso> getAabbIntersection() {
|
||||
return this.aabbIntersection;
|
||||
}
|
||||
|
||||
public PhysicBodyType getBodyType() {
|
||||
return this.bodyType;
|
||||
}
|
||||
|
||||
private List<ColisionPoint> getCollidePoints(PhysicShape shapeRemote) {
|
||||
List<ColisionPoint> out = new ArrayList<>();
|
||||
if (shapeRemote instanceof PhysicSphere remoteShere) {
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
if (shape instanceof PhysicSphere localShape) {
|
||||
ColisionPoint point = ToolCollisionSphereWithSphere.getCollisionPoint(remoteShere, localShape);
|
||||
if (point != null) {
|
||||
out.add(point);
|
||||
}
|
||||
} else if (shape instanceof PhysicTriangle localShape) {
|
||||
ColisionPoint point = ToolCollisionSphereWithTriangle.getCollisionPoint(remoteShere, localShape);
|
||||
if (point != null) {
|
||||
out.add(point);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else if (shapeRemote instanceof PhysicTriangle) {
|
||||
// nothing can happens ...
|
||||
} else {
|
||||
Log.error("Not manage collision model... " + shapeRemote);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public float getMaxSpeed() {
|
||||
return this.maxSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return EnginePhysicsPerso.ENGINE_NAME;
|
||||
}
|
||||
|
||||
public boolean isManageGravity() {
|
||||
return this.manageGravity;
|
||||
}
|
||||
|
||||
public boolean isNarrowCollide() {
|
||||
if (this.narrowIntersection.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void limitWithMaxSpeed() {
|
||||
if (this.speed.length2() > this.maxSpeed * this.maxSpeed) {
|
||||
this.speed = this.speed.safeNormalize().multiply(this.maxSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
public void narrowCollisionCreateContactAndForce() {
|
||||
if (this.bodyType != PhysicBodyType.BODY_DYNAMIC) {
|
||||
return;
|
||||
}
|
||||
if (this.narrowIntersection.size() == 0) {
|
||||
return;
|
||||
}
|
||||
for (Entry<ComponentPhysicsPerso, List<ColisionPoint>> elem : this.narrowIntersection.entrySet()) {
|
||||
for (PhysicShape shapeCurrent : this.shapes) {
|
||||
//TODO Do a better method we do this many times ...
|
||||
/*
|
||||
if (!elem.checkCollide(shapeCurrent)) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
List<ColisionPoint> points = elem.getKey().getCollidePoints(shapeCurrent);
|
||||
elem.getValue().addAll(points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriendComponent(Component component) {
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
public void renderDebug(ResourceColored3DObject debugDrawProperty) {
|
||||
Color displayColor;
|
||||
displayColor = new Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
for (Entry<ComponentPhysicsPerso, List<ColisionPoint>> elem : this.narrowIntersection.entrySet()) {
|
||||
for (ColisionPoint impact : elem.getValue()) {
|
||||
debugDrawProperty.drawSquare(new Vector3f(0.02f, 0.02f, 0.02f), Matrix4f.createMatrixTranslate(impact.position), displayColor);
|
||||
}
|
||||
}
|
||||
if (this.aabbIntersection.size() == 0) {
|
||||
displayColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
} else {
|
||||
if (this.narrowIntersection.size() == 0) {
|
||||
displayColor = new Color(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
displayColor = new Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
if (this.aabb != null) {
|
||||
debugDrawProperty.drawCubeLine(this.aabb.getMin(), this.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 : this.shapes) {
|
||||
shape.renderDebug(this.position.getTransform(), debugDrawProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setBodyType(PhysicBodyType bodyType) {
|
||||
this.bodyType = bodyType;
|
||||
}
|
||||
|
||||
public void setManageGravity(boolean manageGravity) {
|
||||
this.manageGravity = manageGravity;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(float maxSpeed) {
|
||||
this.maxSpeed = maxSpeed;
|
||||
}
|
||||
|
||||
public void updateAABB() {
|
||||
|
||||
if (this.position == null) {
|
||||
Log.info("No position in Entity ");
|
||||
return;
|
||||
}
|
||||
// TODO Add a flag to check if it is needed to update the AABB...
|
||||
AABB aabbNew = AABB.createInvertedEmpty();
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
shape.updateAABB(this.position.getTransform(), aabbNew);
|
||||
}
|
||||
this.aabb = aabbNew;
|
||||
}
|
||||
|
||||
public void updateForNarrowCollision() {
|
||||
this.narrowIntersection.clear();
|
||||
if (this.aabbIntersection.size() == 0) {
|
||||
return;
|
||||
}
|
||||
if (this.position == null) {
|
||||
Log.info("No position in Entity ");
|
||||
return;
|
||||
}
|
||||
for (PhysicShape shape : this.shapes) {
|
||||
shape.updateForNarrowCollision(this.position.getTransform());
|
||||
}
|
||||
}
|
||||
}
|
@ -3,18 +3,21 @@ package org.atriasoft.ege.components;
|
||||
import org.atriasoft.ege.Component;
|
||||
import org.atriasoft.ege.Signal;
|
||||
import org.atriasoft.ege.components.part.PositionningInterface;
|
||||
import org.atriasoft.ege.internal.Log;
|
||||
import org.atriasoft.etk.math.Transform3D;
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
|
||||
public class ComponentPosition extends Component implements PositionningInterface {
|
||||
public final Signal<Transform3D> signalPosition = new Signal<>();
|
||||
protected Transform3D transform;
|
||||
//protected Vector3f speed;
|
||||
|
||||
/**
|
||||
* Create a basic position component (no orientation and position (0,0,0))
|
||||
*/
|
||||
public ComponentPosition() {
|
||||
this.transform = Transform3D.IDENTITY;
|
||||
//this.speed = Vector3f.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,13 +30,19 @@ public class ComponentPosition extends Component implements PositionningInterfac
|
||||
|
||||
@Override
|
||||
public void addFriendComponent(final Component component) {
|
||||
|
||||
if (component.getType().equals("physics")) {
|
||||
Log.critical("Can not add a 'physics' component and a 'position' component ... ==> incompatible");
|
||||
}
|
||||
}
|
||||
|
||||
public void applyForce(Vector3f force) {
|
||||
this.transform = this.transform.withPosition(this.transform.getPosition().add(force));
|
||||
}
|
||||
|
||||
//public Vector3f getSpeed() {
|
||||
// return this.speed;
|
||||
//}
|
||||
|
||||
/**
|
||||
* set a new transformation
|
||||
* @return Transformation of the position
|
||||
@ -48,6 +57,10 @@ public class ComponentPosition extends Component implements PositionningInterfac
|
||||
return "position";
|
||||
}
|
||||
|
||||
//public void setSpeed(Vector3f speed) {
|
||||
// this.speed = speed;
|
||||
//}
|
||||
|
||||
/**
|
||||
* set a new transformation
|
||||
* @param transform transformation of the position
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.atriasoft.ege.engines;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.atriasoft.ege.Component;
|
||||
@ -7,73 +8,105 @@ import org.atriasoft.ege.Engine;
|
||||
import org.atriasoft.ege.Environement;
|
||||
import org.atriasoft.ege.camera.Camera;
|
||||
import org.atriasoft.ege.components.ComponentPhysics;
|
||||
import org.atriasoft.ege.components.PhysicBodyType;
|
||||
import org.atriasoft.ege.internal.Log;
|
||||
import org.atriasoft.ephysics.body.RigidBody;
|
||||
import org.atriasoft.ephysics.collision.ContactManifold;
|
||||
import org.atriasoft.ephysics.collision.shapes.AABB;
|
||||
import org.atriasoft.ephysics.constraint.ContactPoint;
|
||||
import org.atriasoft.ephysics.constraint.ContactPointInfo;
|
||||
import org.atriasoft.ephysics.engine.DynamicsWorld;
|
||||
import org.atriasoft.ephysics.engine.EventListener;
|
||||
import org.atriasoft.ephysics.engine.Island;
|
||||
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.phyligram.DebugDisplay;
|
||||
import org.atriasoft.phyligram.shape.AABB;
|
||||
|
||||
public class EnginePhysics extends Engine {
|
||||
public class EnginePhysics extends Engine implements EventListener {
|
||||
public static final String ENGINE_NAME = "physics";
|
||||
private static final float TIME_STEP = 0.005f;
|
||||
// Constant physics time step
|
||||
private static final float TIME_STEP = 0.016f;//1.0f / 60.0f;
|
||||
boolean propertyDebugAABB = false;
|
||||
boolean propertyDebugShape = false;
|
||||
// Start engine with no gravity
|
||||
private final Vector3f gravity = new Vector3f(0.0f, 0.0f, 0.0f);
|
||||
private float accumulator = 0;
|
||||
private EngineGravity gravity;
|
||||
protected EnginePhysics engine;
|
||||
private Vector<ComponentPhysics> components = new Vector<>();
|
||||
private Vector<ComponentPhysics> componentsWithCollision = new Vector<>();
|
||||
private ResourceColored3DObject debugDrawProperty = ResourceColored3DObject.create();
|
||||
//private final EngineGravity gravity;
|
||||
private final DynamicsWorld dynamicsWorld;
|
||||
|
||||
public EnginePhysics(Environement env) {
|
||||
private final Vector<ComponentPhysics> components = new Vector<>();
|
||||
|
||||
private final ResourceColored3DObject debugDrawProperty = ResourceColored3DObject.create();
|
||||
|
||||
public EnginePhysics(final Environement env) {
|
||||
super(env);
|
||||
/*
|
||||
this.gravity = (EngineGravity) env.getEngine("gravity");
|
||||
if (this.gravity == null) {
|
||||
Log.critical("Must initialyse Gravity before physics...");
|
||||
}
|
||||
*/
|
||||
final Vector3f gravity = new Vector3f(0.0f, 0.0f, 0.0f);
|
||||
this.dynamicsWorld = new DynamicsWorld(gravity);
|
||||
// Set the number of iterations of the constraint solver
|
||||
this.dynamicsWorld.setNbIterationsVelocitySolver(15);
|
||||
this.dynamicsWorld.setEventListener(this);
|
||||
}
|
||||
|
||||
private void addIncomponentWithCollision(ComponentPhysics elem) {
|
||||
if (this.componentsWithCollision.contains(elem)) {
|
||||
return;
|
||||
}
|
||||
this.componentsWithCollision.add(elem);
|
||||
}
|
||||
|
||||
private void applyForces(float timeStep) {
|
||||
for (ComponentPhysics it : this.components) {
|
||||
it.applyForces(timeStep, this.gravity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the previous data of collision.
|
||||
*/
|
||||
private void clearPreviousCycle() {
|
||||
for (ComponentPhysics it : this.components) {
|
||||
it.clearPreviousCollision();
|
||||
private void applyForces(final float timeStep) {
|
||||
for (final ComponentPhysics it : this.components) {
|
||||
//it.applyForces(TIME_STEP, gravity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdd(Component ref) {
|
||||
if (ref instanceof ComponentPhysics == false) {
|
||||
return;
|
||||
public void beginContact(final ContactPointInfo contact) {
|
||||
ComponentPhysics component1 = null;
|
||||
ComponentPhysics component2 = null;
|
||||
// Called when a new contact point is found between two bodies that were separated before.
|
||||
Log.warning("collision detection [BEGIN] " + contact.localPoint1 + " depth=" + contact.penetrationDepth);
|
||||
if (contact.shape1 != null && contact.shape1.getUserData() != null) {
|
||||
component1 = (ComponentPhysics) contact.shape1.getUserData();
|
||||
}
|
||||
if (contact.shape2 != null && contact.shape2.getUserData() != null) {
|
||||
component2 = (ComponentPhysics) contact.shape2.getUserData();
|
||||
}
|
||||
if (component1 != null) {
|
||||
component1.beginContact(component2, contact.normal, contact.localPoint1, contact.localPoint2, contact.penetrationDepth);
|
||||
}
|
||||
if (component2 != null) {
|
||||
component2.beginContact(component1, contact.normal.multiply(-1), contact.localPoint2, contact.localPoint1, contact.penetrationDepth);
|
||||
}
|
||||
this.components.add((ComponentPhysics) ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemove(Component ref) {
|
||||
public void beginInternalTick() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdd(final Component ref) {
|
||||
if (!(ref instanceof ComponentPhysics elem)) {
|
||||
return;
|
||||
}
|
||||
this.components.add(elem);
|
||||
elem.generate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemove(final Component ref) {
|
||||
this.components.remove(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collision Detection STEP 4: apply all calculated forces (with containts)
|
||||
* @param timeStep
|
||||
*/
|
||||
private void generateResultCollisionsForces(float timeStep) {
|
||||
for (ComponentPhysics it : this.componentsWithCollision) {
|
||||
it.applyColisionForce(timeStep);
|
||||
}
|
||||
@Override
|
||||
public void endInternalTick() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public DynamicsWorld getDynamicsWorld() {
|
||||
return this.dynamicsWorld;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,11 +116,32 @@ public class EnginePhysics extends Engine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long deltaMili, Camera camera) {
|
||||
public void newContact(final ContactPointInfo contact) {
|
||||
|
||||
ComponentPhysics component1 = null;
|
||||
ComponentPhysics component2 = null;
|
||||
//Called when a new contact point is found between two bodies.
|
||||
Log.warning("collision detection [ NEW ] " + contact.localPoint1 + " depth=" + contact.penetrationDepth);
|
||||
if (contact.shape1 != null && contact.shape1.getUserData() != null) {
|
||||
component1 = (ComponentPhysics) contact.shape1.getUserData();
|
||||
}
|
||||
if (contact.shape2 != null && contact.shape2.getUserData() != null) {
|
||||
component2 = (ComponentPhysics) contact.shape2.getUserData();
|
||||
}
|
||||
if (component1 != null) {
|
||||
component1.newContact(component2, contact.normal, contact.localPoint1, contact.localPoint2, contact.penetrationDepth);
|
||||
}
|
||||
if (component2 != null) {
|
||||
component2.newContact(component1, contact.normal.multiply(-1), contact.localPoint2, contact.localPoint1, contact.penetrationDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(final long deltaMili, final Camera camera) {
|
||||
// TODO Auto-generated method stub
|
||||
for (ComponentPhysics it : this.components) {
|
||||
for (final ComponentPhysics it : this.components) {
|
||||
//Log.info("Render " + it);
|
||||
it.renderDebug(this.debugDrawProperty);
|
||||
it.renderDebug(this.debugDrawProperty, camera);
|
||||
}
|
||||
//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));
|
||||
@ -96,93 +150,77 @@ public class EnginePhysics extends Engine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDebug(long deltaMili, Camera camera) {
|
||||
// TODO Auto-generated method stub
|
||||
DebugDisplay.onDraw();
|
||||
DebugDisplay.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long deltaMili) {
|
||||
// Add the time difference in the accumulator
|
||||
this.accumulator += deltaMili * 0.0001f;
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (this.accumulator >= TIME_STEP) {
|
||||
Log.info("update physic ... " + this.accumulator);
|
||||
clearPreviousCycle();
|
||||
applyForces(TIME_STEP);
|
||||
// update AABB after because in rotation force, the Bounding box change...
|
||||
updateAABB(TIME_STEP);
|
||||
// update the colision tree between each object in the room
|
||||
updateCollisionsAABB(TIME_STEP);
|
||||
updateCollisionsNarrowPhase(TIME_STEP);
|
||||
generateResultCollisionsForces(TIME_STEP);
|
||||
// Decrease the accumulated time
|
||||
this.accumulator -= TIME_STEP;
|
||||
public void renderDebug(final long deltaMili, final Camera camera) {
|
||||
if (this.propertyDebugShape) {
|
||||
for (final ComponentPhysics it : this.components) {
|
||||
it.drawShape(this.debugDrawProperty, camera);
|
||||
}
|
||||
}
|
||||
if (this.propertyDebugAABB) {
|
||||
for (final ComponentPhysics it : this.components) {
|
||||
it.renderDebug(this.debugDrawProperty, camera);
|
||||
}
|
||||
}
|
||||
final Matrix4f transformationMatrix = Matrix4f.IDENTITY;
|
||||
final Color tmpColor = new Color(0.0f, 0.0f, 1.0f, 0.8f);
|
||||
final List<Island> islands = this.dynamicsWorld.getIslands();
|
||||
for (final Island it : islands) {
|
||||
// TODO compute island AABB to display it ...
|
||||
final AABB islandElements = new AABB();
|
||||
for (final RigidBody elem : it.getBodies()) {
|
||||
final AABB tmp = elem.getAABB();
|
||||
islandElements.mergeWithAABB(tmp);
|
||||
}
|
||||
this.debugDrawProperty.drawCubeLine(islandElements.getMin(), islandElements.getMax(), tmpColor, transformationMatrix, true, true);
|
||||
}
|
||||
|
||||
final List<ContactManifold> listContact = this.dynamicsWorld.getContactsList();
|
||||
//Log.info("nb contact: " + listContact.size());
|
||||
for (final ContactManifold it : listContact) {
|
||||
for (int iii = 0; iii < it.getNbContactPoints(); iii++) {
|
||||
final ContactPoint contact = it.getContactPoint(iii);
|
||||
this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(contact.getWorldPointOnBody1())), new Color(0, 1, 0, 1));
|
||||
this.debugDrawProperty.drawSquare(new Vector3f(0.05f, 0.05f, 0.05f), Matrix4f.IDENTITY.multiply(Matrix4f.createMatrixTranslate(contact.getWorldPointOnBody2())), new Color(0, 1, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (ComponentPhysics it : this.components) {
|
||||
it.updateAABB();
|
||||
public void setGravity(final Vector3f _axePower) {
|
||||
if (this.dynamicsWorld != null) {
|
||||
final Vector3f gravity = _axePower;
|
||||
this.dynamicsWorld.setGravity(gravity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
// TODO : generate a B-TREE to manage collision, it is faster, but now, this is not the purpose ...
|
||||
private void updateCollisionsAABB(float timeStep) {
|
||||
this.componentsWithCollision.clear();
|
||||
// clear all object intersection
|
||||
for (ComponentPhysics it : this.components) {
|
||||
it.clearAABBIntersection();
|
||||
@Override
|
||||
public void update(long deltaMili) {
|
||||
//Log.error("=================================================================" + deltaMili);
|
||||
if (deltaMili > 1000) {
|
||||
deltaMili = (long) (TIME_STEP * 1000.0f);
|
||||
}
|
||||
// update the current object intersection...
|
||||
for (int iii = 0; iii < this.components.size(); iii++) {
|
||||
ComponentPhysics current = this.components.get(iii);
|
||||
AABB currentAABB = current.getAABB();
|
||||
for (int jjj = iii + 1; jjj < this.components.size(); jjj++) {
|
||||
ComponentPhysics remote = this.components.get(jjj);
|
||||
if (current.getBodyType() != PhysicBodyType.BODY_DYNAMIC && remote.getBodyType() != PhysicBodyType.BODY_DYNAMIC) {
|
||||
continue;
|
||||
}
|
||||
// prefer checking the collision, this a time-constant operation, check if collision already exist is a unpredictable time.
|
||||
if (currentAABB.intersect(this.components.get(jjj).getAABB()) == true) {
|
||||
current.addIntersection(remote);
|
||||
remote.addIntersection(current);
|
||||
addIncomponentWithCollision(remote);
|
||||
addIncomponentWithCollision(current);
|
||||
final float deltaTime = deltaMili * 0.0001f;
|
||||
// Add the time difference in the accumulator
|
||||
this.accumulator += deltaTime;
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (this.accumulator >= TIME_STEP) {
|
||||
//Log.error("---------------------------------------------------" + TIME_STEP);
|
||||
if (this.dynamicsWorld != null) {
|
||||
// call every object to usdate their constant forces applied
|
||||
for (final ComponentPhysics it : this.components) {
|
||||
if (it != null) {
|
||||
it.update(TIME_STEP);
|
||||
}
|
||||
}
|
||||
// Update the Dynamics world with a constant time step
|
||||
Log.debug("Update the Physic engine ... " + TIME_STEP);
|
||||
this.dynamicsWorld.update(TIME_STEP);
|
||||
}
|
||||
// Decrease the accumulated time
|
||||
this.accumulator -= TIME_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (ComponentPhysics it : this.componentsWithCollision) {
|
||||
it.updateForNarrowCollision();
|
||||
}
|
||||
// check for every component if the narrow collision is available.
|
||||
for (int iii = 0; iii < this.componentsWithCollision.size(); iii++) {
|
||||
ComponentPhysics current = this.componentsWithCollision.get(iii);
|
||||
boolean collide = current.checkNarrowCollision();
|
||||
|
||||
}
|
||||
// update the force of collision available.
|
||||
for (int iii = 0; iii < this.components.size(); iii++) {
|
||||
ComponentPhysics current = this.components.get(iii);
|
||||
current.narrowCollisionCreateContactAndForce();
|
||||
for (final ComponentPhysics elem : this.components) {
|
||||
elem.emitAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
189
src/org/atriasoft/ege/engines/EnginePhysicsPerso.java
Normal file
189
src/org/atriasoft/ege/engines/EnginePhysicsPerso.java
Normal file
@ -0,0 +1,189 @@
|
||||
package org.atriasoft.ege.engines;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
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.ege.components.PhysicBodyType;
|
||||
import org.atriasoft.ege.internal.Log;
|
||||
import org.atriasoft.gale.resource.ResourceColored3DObject;
|
||||
import org.atriasoft.phyligram.DebugDisplay;
|
||||
import org.atriasoft.phyligram.shape.AABB;
|
||||
|
||||
public class EnginePhysicsPerso extends Engine {
|
||||
public static final String ENGINE_NAME = "physicsPerso";
|
||||
private static final float TIME_STEP = 0.005f;
|
||||
private float accumulator = 0;
|
||||
private EngineGravity gravity;
|
||||
protected EnginePhysicsPerso engine;
|
||||
private Vector<ComponentPhysicsPerso> components = new Vector<>();
|
||||
private Vector<ComponentPhysicsPerso> componentsWithCollision = 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...");
|
||||
}
|
||||
}
|
||||
|
||||
private void addIncomponentWithCollision(ComponentPhysicsPerso elem) {
|
||||
if (this.componentsWithCollision.contains(elem)) {
|
||||
return;
|
||||
}
|
||||
this.componentsWithCollision.add(elem);
|
||||
}
|
||||
|
||||
private void applyForces(float timeStep) {
|
||||
for (ComponentPhysicsPerso it : this.components) {
|
||||
it.applyForces(TIME_STEP, this.gravity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the previous data of collision.
|
||||
*/
|
||||
private void clearPreviousCycle() {
|
||||
for (ComponentPhysicsPerso it : this.components) {
|
||||
it.clearPreviousCollision();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdd(Component ref) {
|
||||
if (ref instanceof ComponentPhysicsPerso == false) {
|
||||
return;
|
||||
}
|
||||
this.components.add((ComponentPhysicsPerso) ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemove(Component ref) {
|
||||
this.components.remove(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collision Detection STEP 4: apply all calculated forces (with containts)
|
||||
* @param timeStep
|
||||
*/
|
||||
private void generateResultCollisionsForces(float timeStep) {
|
||||
for (ComponentPhysicsPerso it : this.componentsWithCollision) {
|
||||
it.applyColisionForce();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
// TODO Auto-generated method stub
|
||||
return ENGINE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long deltaMili, Camera camera) {
|
||||
// TODO Auto-generated method stub
|
||||
for (ComponentPhysicsPerso it : this.components) {
|
||||
//Log.info("Render " + it);
|
||||
it.renderDebug(this.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
|
||||
DebugDisplay.onDraw();
|
||||
DebugDisplay.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long deltaMili) {
|
||||
// Add the time difference in the accumulator
|
||||
this.accumulator += deltaMili * 0.0001f;
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (this.accumulator >= TIME_STEP) {
|
||||
Log.info("update physic ... " + this.accumulator);
|
||||
clearPreviousCycle();
|
||||
applyForces(TIME_STEP);
|
||||
// update AABB after because in rotation force, the Bounding box change...
|
||||
updateAABB(TIME_STEP);
|
||||
// update the colision tree between each object in the room
|
||||
updateCollisionsAABB(TIME_STEP);
|
||||
updateCollisionsNarrowPhase(TIME_STEP);
|
||||
generateResultCollisionsForces(TIME_STEP);
|
||||
// Decrease the accumulated time
|
||||
this.accumulator -= TIME_STEP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 : this.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
|
||||
*/
|
||||
// TODO : generate a B-TREE to manage collision, it is faster, but now, this is not the purpose ...
|
||||
private void updateCollisionsAABB(float timeStep) {
|
||||
this.componentsWithCollision.clear();
|
||||
// clear all object intersection
|
||||
for (ComponentPhysicsPerso it : this.components) {
|
||||
it.clearAABBIntersection();
|
||||
}
|
||||
// update the current object intersection...
|
||||
for (int iii = 0; iii < this.components.size(); iii++) {
|
||||
ComponentPhysicsPerso current = this.components.get(iii);
|
||||
AABB currentAABB = current.getAABB();
|
||||
for (int jjj = iii + 1; jjj < this.components.size(); jjj++) {
|
||||
ComponentPhysicsPerso remote = this.components.get(jjj);
|
||||
if (current.getBodyType() != PhysicBodyType.BODY_DYNAMIC && remote.getBodyType() != PhysicBodyType.BODY_DYNAMIC) {
|
||||
continue;
|
||||
}
|
||||
// prefer checking the collision, this a time-constant operation, check if collision already exist is a unpredictable time.
|
||||
if (currentAABB.intersect(this.components.get(jjj).getAABB()) == true) {
|
||||
current.addIntersection(remote);
|
||||
remote.addIntersection(current);
|
||||
addIncomponentWithCollision(remote);
|
||||
addIncomponentWithCollision(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 : this.componentsWithCollision) {
|
||||
it.updateForNarrowCollision();
|
||||
}
|
||||
// check for every component if the narrow collision is available.
|
||||
for (int iii = 0; iii < this.componentsWithCollision.size(); iii++) {
|
||||
ComponentPhysicsPerso current = this.componentsWithCollision.get(iii);
|
||||
boolean collide = current.checkNarrowCollision();
|
||||
|
||||
}
|
||||
// update the force of collision available.
|
||||
for (int iii = 0; iii < this.components.size(); iii++) {
|
||||
ComponentPhysicsPerso current = this.components.get(iii);
|
||||
current.narrowCollisionCreateContactAndForce();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,9 +16,7 @@ public abstract class PhysicShape {
|
||||
// protected Vector3f origin;
|
||||
protected Transform3D transform;
|
||||
protected Transform3D transformGlobal;
|
||||
protected float mass = 0.0f;
|
||||
protected float frictionCoefficient = 0.0f;
|
||||
protected float bouncingCoefficient = 0.0f;
|
||||
protected float mass = 0;
|
||||
|
||||
public PhysicShape() {
|
||||
this.transform = Transform3D.IDENTITY;
|
||||
@ -38,14 +36,6 @@ public abstract class PhysicShape {
|
||||
this.colisionPoints.add(colision);
|
||||
}
|
||||
|
||||
public float getBouncingCoefficient() {
|
||||
return this.bouncingCoefficient;
|
||||
}
|
||||
|
||||
public float getFrictionCoefficient() {
|
||||
return this.frictionCoefficient;
|
||||
}
|
||||
|
||||
public float getMass() {
|
||||
return this.mass;
|
||||
}
|
||||
@ -72,14 +62,6 @@ public abstract class PhysicShape {
|
||||
|
||||
public abstract void renderDebug(Transform3D transform, ResourceColored3DObject debugDrawProperty);
|
||||
|
||||
public void setBouncingCoefficient(float bouncingCoefficient) {
|
||||
this.bouncingCoefficient = bouncingCoefficient;
|
||||
}
|
||||
|
||||
public void setFrictionCoefficient(float frictionCoefficient) {
|
||||
this.frictionCoefficient = frictionCoefficient;
|
||||
}
|
||||
|
||||
public void setMass(float mass) {
|
||||
this.mass = mass;
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
package org.atriasoft.phyligram.math;
|
||||
package org.atriasoft.phyligram;
|
||||
|
||||
import org.atriasoft.etk.math.Quaternion;
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
import org.atriasoft.phyligram.ColisionPoint;
|
||||
import org.atriasoft.phyligram.Collision;
|
||||
import org.atriasoft.phyligram.DebugDisplay;
|
||||
import org.atriasoft.phyligram.PhysicBox;
|
||||
import org.atriasoft.phyligram.internal.Log;
|
||||
|
||||
// set the relevant elements of our oriented bounding box
|
||||
class OBB {
|
||||
@ -14,17 +11,101 @@ class OBB {
|
||||
public Vector3f axisY;
|
||||
public Vector3f axisZ;
|
||||
public Vector3f halfSize;
|
||||
|
||||
|
||||
public OBB() {
|
||||
this.position = Vector3f.ZERO;
|
||||
this.axisX = Vector3f.ZERO;
|
||||
this.axisY = Vector3f.ZERO;
|
||||
this.axisZ = Vector3f.ZERO;
|
||||
this.halfSize = Vector3f.ZERO;
|
||||
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);
|
||||
@ -35,7 +116,7 @@ public class ToolCollisionOBBWithOBB {
|
||||
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);
|
||||
@ -52,7 +133,7 @@ public class ToolCollisionOBBWithOBB {
|
||||
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());
|
||||
@ -69,7 +150,7 @@ public class ToolCollisionOBBWithOBB {
|
||||
}
|
||||
}
|
||||
/* res = trensfert in generic plan the new res ... */
|
||||
|
||||
|
||||
DebugDisplay.testRpos = quat1.inverse().getMatrix4().multiply(rPos2);
|
||||
DebugDisplay.testQTransfert = quatTransfer1;
|
||||
DebugDisplay.box1HalfSize = box1.narrowPhaseHalfSize;
|
||||
@ -90,11 +171,11 @@ public class ToolCollisionOBBWithOBB {
|
||||
Collision colision = new Collision(collide2, box1, collide1, isStatic1);
|
||||
box2.addColision(colision);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static ColisionPoint[] 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);
|
||||
@ -207,75 +288,18 @@ public class ToolCollisionOBBWithOBB {
|
||||
return out;
|
||||
}
|
||||
// line in AABB
|
||||
// TODO:
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
//
|
||||
// // 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 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))));
|
||||
}
|
||||
|
||||
// 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 Vector3f pointDistanceInAABB(Vector3f halfSize, Vector3f point) {
|
||||
float outX = 0;
|
||||
float outY = 0;
|
||||
@ -351,31 +375,4 @@ public class ToolCollisionOBBWithOBB {
|
||||
outY = 0;
|
||||
return new Vector3f(outX, outY, outZ);
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
private ToolCollisionOBBWithOBB() {}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
package org.atriasoft.phyligram.math;
|
||||
package org.atriasoft.phyligram;
|
||||
|
||||
import org.atriasoft.ege.geometry.Triangle;
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
import org.atriasoft.phyligram.PhysicHeightMapChunk;
|
||||
import org.atriasoft.phyligram.PhysicSphere;
|
||||
|
||||
public class ToolCollisionSphereWithHeightMapChunk {
|
||||
//intersection entre 2 droite (en 2d avec estimation en 3D
|
@ -1,8 +1,6 @@
|
||||
package org.atriasoft.phyligram.math;
|
||||
package org.atriasoft.phyligram;
|
||||
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
import org.atriasoft.phyligram.ColisionPoint;
|
||||
import org.atriasoft.phyligram.PhysicSphere;
|
||||
import org.atriasoft.phyligram.internal.Log;
|
||||
|
||||
public class ToolCollisionSphereWithSphere {
|
@ -1,11 +1,8 @@
|
||||
package org.atriasoft.phyligram.math;
|
||||
package org.atriasoft.phyligram;
|
||||
|
||||
import org.atriasoft.ege.geometry.Plane;
|
||||
import org.atriasoft.etk.math.FMath;
|
||||
import org.atriasoft.etk.math.Vector3f;
|
||||
import org.atriasoft.phyligram.ColisionPoint;
|
||||
import org.atriasoft.phyligram.PhysicSphere;
|
||||
import org.atriasoft.phyligram.PhysicTriangle;
|
||||
|
||||
// https://realtimecollisiondetection.net/blog/?p=103
|
||||
public class ToolCollisionSphereWithTriangle {
|
@ -1,16 +1,15 @@
|
||||
package org.atriasoft.phyligram.shape;
|
||||
|
||||
import org.atriasoft.ege.geometry.Triangle;
|
||||
import org.atriasoft.ephysics.collision.Triangle;
|
||||
|
||||
public class HeightMapChunk extends Shape {
|
||||
private Triangle[] triangles;
|
||||
|
||||
public HeightMapChunk(Triangle[] triangles) {
|
||||
this.triangles = triangles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display() {
|
||||
// TODO Auto-generated method stub
|
||||
super.display();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user