[DEV] basic AABB collision
This commit is contained in:
parent
e72f6b3449
commit
d53dca94a5
@ -147,19 +147,24 @@ public class Vector3f {
|
||||
}
|
||||
/**
|
||||
* @brief Normalize this vector x^2 + y^2 + z^2 = 1 (check if not deviding by 0, if it is the case ==> return (1,0,0))
|
||||
* @return the current vector
|
||||
*/
|
||||
public void safeNormalize() {
|
||||
public Vector3f safeNormalize() {
|
||||
float length = length();
|
||||
if (length != 0.0f) {
|
||||
this.devide(length);
|
||||
return this;
|
||||
}
|
||||
this.setValue(1,0,0);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @brief Normalize this vector x^2 + y^2 + z^2 = 1
|
||||
* @return the current vector
|
||||
*/
|
||||
public void normalize() {
|
||||
public Vector3f normalize() {
|
||||
this.devide(this.length());
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @brief Return a normalized version of this vector
|
||||
|
@ -1,12 +1,13 @@
|
||||
package org.atriaSoft.gale.test.sample2;
|
||||
|
||||
public class Log {
|
||||
private static String LIBNAME = "Sample1";
|
||||
private static String LIBNAME = "Sample2";
|
||||
public static void print(String data) {
|
||||
System.out.println(data);
|
||||
}
|
||||
public static void critical(String data) {
|
||||
System.out.println("[C] " + LIBNAME + " | " + data);
|
||||
System.exit(-1);
|
||||
}
|
||||
public static void error(String data) {
|
||||
System.out.println("[E] " + LIBNAME + " | " + data);
|
||||
|
@ -18,6 +18,7 @@ import org.atriaSoft.gameEngine.camera.Camera;
|
||||
import org.atriaSoft.gameEngine.engines.EngineRender;
|
||||
import org.atriaSoft.gameEngine.engines.EngineAI;
|
||||
import org.atriaSoft.gameEngine.engines.EngineDynamicMeshs;
|
||||
import org.atriaSoft.gameEngine.engines.EngineGravity;
|
||||
import org.atriaSoft.gameEngine.engines.EngineLight;
|
||||
import org.atriaSoft.gameEngine.engines.EngineParticle;
|
||||
import org.atriaSoft.gameEngine.engines.EnginePhysics;
|
||||
@ -41,7 +42,7 @@ public class Environement {
|
||||
//protected List<Mesh> listMeshToDrawFirst = new ArrayList<Mesh>();
|
||||
|
||||
public Environement() {
|
||||
// we add the 4 classical engines (the order is used to the global rendering cycle ...
|
||||
addEngine(new EngineGravity(this));
|
||||
addEngine(new EnginePlayer(this));
|
||||
addEngine(new EngineAI(this));
|
||||
addEngine(new EngineDynamicMeshs(this));
|
||||
|
@ -7,6 +7,7 @@ public class Log {
|
||||
}
|
||||
public static void critical(String data) {
|
||||
System.out.println("[C] " + LIBNAME + " | " + data);
|
||||
System.exit(-1);
|
||||
}
|
||||
public static void error(String data) {
|
||||
System.out.println("[E] " + LIBNAME + " | " + data);
|
||||
|
@ -0,0 +1,16 @@
|
||||
package org.atriaSoft.gameEngine.components;
|
||||
|
||||
import org.atriaSoft.etk.math.Vector3f;
|
||||
import org.atriaSoft.gameEngine.Component;
|
||||
import org.atriaSoft.gameEngine.Light;
|
||||
|
||||
public abstract class ComponentGravity extends Component {
|
||||
public ComponentGravity() {
|
||||
super();
|
||||
}
|
||||
@Override
|
||||
public String getType() {
|
||||
return "gravity";
|
||||
}
|
||||
public abstract Vector3f getGravityAtPosition(Vector3f position);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.atriaSoft.gameEngine.components;
|
||||
|
||||
import org.atriaSoft.etk.math.Vector3f;
|
||||
import org.atriaSoft.gameEngine.Component;
|
||||
import org.atriaSoft.gameEngine.Light;
|
||||
|
||||
public class ComponentGravityStatic extends ComponentGravity {
|
||||
private Vector3f gravity;
|
||||
public ComponentGravityStatic(Vector3f gravity) {
|
||||
super();
|
||||
this.gravity = gravity;
|
||||
}
|
||||
@Override
|
||||
public Vector3f getGravityAtPosition(Vector3f position) {
|
||||
return gravity;
|
||||
}
|
||||
public Vector3f getGravity() {
|
||||
return gravity;
|
||||
}
|
||||
public void setGravity(Vector3f gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
}
|
@ -5,10 +5,12 @@ import java.util.List;
|
||||
|
||||
import org.atriaSoft.etk.Color;
|
||||
import org.atriaSoft.etk.math.Matrix4f;
|
||||
import org.atriaSoft.etk.math.Vector3f;
|
||||
import org.atriaSoft.gale.backend3d.OpenGL;
|
||||
import org.atriaSoft.gale.resource.ResourceColored3DObject;
|
||||
import org.atriaSoft.gale.test.sample2.Log;
|
||||
import org.atriaSoft.gameEngine.Component;
|
||||
import org.atriaSoft.gameEngine.engines.EngineGravity;
|
||||
import org.atriaSoft.gameEngine.physics.PhysicCollisionAABB;
|
||||
import org.atriaSoft.gameEngine.physics.PhysicShape;
|
||||
|
||||
@ -16,12 +18,28 @@ import entities.Entity;
|
||||
|
||||
public class ComponentPhysics extends Component {
|
||||
private PhysicCollisionAABB aabb;
|
||||
private List<ComponentPhysics> aabbIntersection = new ArrayList<ComponentPhysics>();
|
||||
private List<PhysicShape> shapes = new ArrayList<PhysicShape>();
|
||||
private ComponentPosition position;
|
||||
private boolean manageGravity = false;
|
||||
public static float globalMaxSpeed = Float.MAX_VALUE;
|
||||
private float maxSpeed = globalMaxSpeed;
|
||||
// current speed of the object
|
||||
private Vector3f speed = new Vector3f(0,0,0);
|
||||
// current acceleration of the object
|
||||
private Vector3f acceleration = new Vector3f(0,0,0);
|
||||
// Applied static force on it
|
||||
private Vector3f staticForce = new Vector3f(0,0,0);
|
||||
// Apply dynamic force on it
|
||||
private Vector3f dynamicForce = new Vector3f(0,0,0);
|
||||
@Override
|
||||
public String getType() {
|
||||
return "physics";
|
||||
}
|
||||
|
||||
public ComponentPhysics(boolean manageGravity) {
|
||||
this.manageGravity = manageGravity;
|
||||
}
|
||||
@Override
|
||||
public void addFriendComponent(Component component) {
|
||||
if (component.getType().contentEquals("position")) {
|
||||
@ -46,16 +64,45 @@ public class ComponentPhysics extends Component {
|
||||
aabb = aabb_new;
|
||||
}
|
||||
|
||||
public PhysicCollisionAABB getcurrentAABB() {
|
||||
public PhysicCollisionAABB getAABB() {
|
||||
return aabb;
|
||||
}
|
||||
public void applyForces(float timeStep) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
public void applyForces(float timeStep, EngineGravity gravity) {
|
||||
// get the gravity at the specific position...
|
||||
Vector3f gravityForce;
|
||||
if (manageGravity == true) {
|
||||
gravityForce = gravity.getGravityAtPosition(position.getTransform().getPosition()).multiply_new(timeStep);
|
||||
} else {
|
||||
gravityForce = new Vector3f(0,0,0);
|
||||
}
|
||||
// apply this force on the Object
|
||||
Log.info("apply gravity: " + gravityForce);
|
||||
// relative to the object
|
||||
Vector3f staticForce = this.staticForce.multiply_new(timeStep);
|
||||
float globalMass = 0;
|
||||
for (PhysicShape shape : shapes) {
|
||||
globalMass += shape.getMass();
|
||||
}
|
||||
// note the acceleration is not real, it depend on the current delta time...
|
||||
this.acceleration = gravityForce.add(this.position.getTransform().getOrientation().multiply(staticForce)).add(this.position.getTransform().getOrientation().multiply(dynamicForce)).multiply(globalMass);
|
||||
this.dynamicForce = new Vector3f(0,0,0);
|
||||
this.speed.add(this.acceleration);
|
||||
limitWithMaxSpeed();
|
||||
Log.info("apply acceleration: " + this.acceleration);
|
||||
Log.info("apply speed: " + this.speed);
|
||||
this.position.getTransform().getPosition().add(this.speed.multiply_new(timeStep));
|
||||
}
|
||||
|
||||
public void renderDebug(ResourceColored3DObject debugDrawProperty) {
|
||||
Color displayColor;
|
||||
if (this.aabbIntersection.size() == 0) {
|
||||
displayColor = new Color(1,1,1,1);
|
||||
} else {
|
||||
displayColor = new Color(1,0,0,1);
|
||||
}
|
||||
if (aabb != null) {
|
||||
debugDrawProperty.drawCubeLine(aabb.getMin(), aabb.getMax(), new Color(1,1,1,1), Matrix4f.identity(), true, true);
|
||||
debugDrawProperty.drawCubeLine(aabb.getMin(), aabb.getMax(), displayColor, Matrix4f.identity(), true, true);
|
||||
//debugDrawProperty.drawCubeLine(new Vector3f(0,0,0), new Vector3f(32,32,32), new Color(1,0,1,1), Matrix4f.identity(), true, true);
|
||||
} else {
|
||||
Log.error("no AABB");
|
||||
@ -70,4 +117,29 @@ public class ComponentPhysics extends Component {
|
||||
public void clearShape() {
|
||||
shapes.clear();
|
||||
}
|
||||
public boolean isManageGravity() {
|
||||
return manageGravity;
|
||||
}
|
||||
public void setManageGravity(boolean manageGravity) {
|
||||
this.manageGravity = manageGravity;
|
||||
}
|
||||
private void limitWithMaxSpeed() {
|
||||
if (this.speed.length2() > this.maxSpeed*this.maxSpeed) {
|
||||
this.speed.safeNormalize().multiply(this.maxSpeed);
|
||||
}
|
||||
}
|
||||
public float getMaxSpeed() {
|
||||
return maxSpeed;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(float maxSpeed) {
|
||||
this.maxSpeed = maxSpeed;
|
||||
}
|
||||
|
||||
public void clearAABBIntersection() {
|
||||
this.aabbIntersection.clear();
|
||||
}
|
||||
public void addIntersection(ComponentPhysics component) {
|
||||
this.aabbIntersection.add(component);
|
||||
}
|
||||
}
|
||||
|
66
src/org/atriaSoft/gameEngine/engines/EngineGravity.java
Normal file
66
src/org/atriaSoft/gameEngine/engines/EngineGravity.java
Normal file
@ -0,0 +1,66 @@
|
||||
package org.atriaSoft.gameEngine.engines;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.atriaSoft.etk.math.Vector3f;
|
||||
import org.atriaSoft.gameEngine.Component;
|
||||
import org.atriaSoft.gameEngine.Engine;
|
||||
import org.atriaSoft.gameEngine.Environement;
|
||||
import org.atriaSoft.gameEngine.Light;
|
||||
import org.atriaSoft.gameEngine.Log;
|
||||
import org.atriaSoft.gameEngine.camera.Camera;
|
||||
import org.atriaSoft.gameEngine.components.ComponentAI;
|
||||
import org.atriaSoft.gameEngine.components.ComponentGravity;
|
||||
import org.atriaSoft.gameEngine.components.ComponentLight;
|
||||
import org.atriaSoft.gameEngine.components.ComponentLightSun;
|
||||
|
||||
public class EngineGravity extends Engine {
|
||||
public static final String ENGINE_NAME = "gravity";
|
||||
private Vector<ComponentGravity> components = new Vector<ComponentGravity>();
|
||||
public EngineGravity(Environement env) {
|
||||
super(env);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemove(Component ref) {
|
||||
components.remove(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentAdd(Component ref) {
|
||||
if (ref instanceof ComponentGravity == true) {
|
||||
components.add((ComponentGravity)ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long deltaMili) {
|
||||
// nothing to do ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long deltaMili, Camera camera) {
|
||||
// nothing to do ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDebug(long deltaMili, Camera camera) {
|
||||
// nothing to do ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
// TODO Auto-generated method stub
|
||||
return ENGINE_NAME;
|
||||
}
|
||||
public Vector3f getGravityAtPosition(Vector3f position) {
|
||||
Vector3f out = new Vector3f();
|
||||
for (ComponentGravity elem: components) {
|
||||
out.add(elem.getGravityAtPosition(position));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
@ -2,29 +2,29 @@ package org.atriaSoft.gameEngine.engines;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
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.gale.test.sample2.Log;
|
||||
import org.atriaSoft.gameEngine.Log;
|
||||
import org.atriaSoft.gameEngine.Component;
|
||||
import org.atriaSoft.gameEngine.Engine;
|
||||
import org.atriaSoft.gameEngine.Environement;
|
||||
import org.atriaSoft.gameEngine.camera.Camera;
|
||||
import org.atriaSoft.gameEngine.components.ComponentAI;
|
||||
import org.atriaSoft.gameEngine.components.ComponentPhysics;
|
||||
import org.atriaSoft.gameEngine.components.ComponentRender;
|
||||
import org.atriaSoft.gameEngine.physics.PhysicCollisionAABB;
|
||||
|
||||
public class EnginePhysics extends Engine {
|
||||
public static final String ENGINE_NAME = "physics";
|
||||
private float accumulator = 0;
|
||||
private static float TIME_STEP = 0.02f;
|
||||
private static float TIME_STEP = 0.005f;
|
||||
private EngineGravity gravity;
|
||||
private Vector<ComponentPhysics> components = new Vector<ComponentPhysics>();
|
||||
private ResourceColored3DObject debugDrawProperty = ResourceColored3DObject.create();
|
||||
|
||||
public EnginePhysics(Environement env) {
|
||||
super(env);
|
||||
// TODO Auto-generated constructor stub
|
||||
this.gravity = (EngineGravity)env.getEngine("gravity");
|
||||
if (this.gravity == null) {
|
||||
Log.critical("Must initialyse Gravity before physics...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,8 +47,9 @@ public class EnginePhysics extends Engine {
|
||||
// While there is enough accumulated time to take one or several physics steps
|
||||
while (accumulator >= TIME_STEP) {
|
||||
Log.info("update physic ... " + accumulator);
|
||||
applyForces(TIME_STEP);
|
||||
//applyForces(TIME_STEP);
|
||||
updateAABB(TIME_STEP);
|
||||
updateCollisionsAABB(TIME_STEP);
|
||||
updateCollisions(TIME_STEP);
|
||||
GenerateResultCollisionsForces(TIME_STEP);
|
||||
// Decrease the accumulated time
|
||||
@ -59,7 +60,7 @@ public class EnginePhysics extends Engine {
|
||||
|
||||
private void applyForces(float timeStep) {
|
||||
for (ComponentPhysics it: components) {
|
||||
it.applyForces(TIME_STEP);
|
||||
it.applyForces(TIME_STEP, gravity);
|
||||
}
|
||||
}
|
||||
private void updateAABB(float timeStep) {
|
||||
@ -67,6 +68,24 @@ public class EnginePhysics extends Engine {
|
||||
it.updateAABB();
|
||||
}
|
||||
}
|
||||
private void updateCollisionsAABB(float timeStep) {
|
||||
// clear all object intersection
|
||||
for (ComponentPhysics it: components) {
|
||||
it.clearAABBIntersection();
|
||||
}
|
||||
// update the current object intersection...
|
||||
for (int iii=0; iii< components.size(); iii++) {
|
||||
ComponentPhysics current = components.get(iii);
|
||||
PhysicCollisionAABB currentAABB = current.getAABB();
|
||||
for (int jjj=iii+1; jjj< components.size(); jjj++) {
|
||||
ComponentPhysics remote = components.get(jjj);
|
||||
if (currentAABB.intersect(components.get(jjj).getAABB()) == true) {
|
||||
current.addIntersection(remote);
|
||||
remote.addIntersection(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void updateCollisions(float timeStep) {
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class MapVoxel extends EngineMap {
|
||||
new Uri("DATA", "basicMaterial.vert"),
|
||||
new Uri("DATA", "basicMaterial.frag"),
|
||||
(EngineLight)env.getEngine(EngineLight.ENGINE_NAME)));
|
||||
ComponentPhysics physics = new ComponentPhysics();
|
||||
ComponentPhysics physics = new ComponentPhysics(false);
|
||||
PhysicMapVoxel box = new PhysicMapVoxel(tmpVoxelChunk);
|
||||
physics.addShape(box);
|
||||
tmpEntity.addComponent(physics);
|
||||
|
7
src/org/atriaSoft/gameEngine/physics/GravityMap.java
Normal file
7
src/org/atriaSoft/gameEngine/physics/GravityMap.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.atriaSoft.gameEngine.physics;
|
||||
|
||||
import org.atriaSoft.etk.math.Vector3f;
|
||||
|
||||
public abstract class GravityMap {
|
||||
public abstract Vector3f getGravityAtPosition(Vector3f position);
|
||||
}
|
@ -19,6 +19,9 @@ public class PhysicCollisionAABB {
|
||||
this.maxZ = maxZ;
|
||||
}
|
||||
public boolean intersect(PhysicCollisionAABB other) {
|
||||
if (this == other) {
|
||||
return false;
|
||||
}
|
||||
if (minX > other.maxX) {
|
||||
return false;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import org.atriaSoft.gameEngine.GameStatus;
|
||||
import org.atriaSoft.gameEngine.Light;
|
||||
import org.atriaSoft.gameEngine.Material;
|
||||
import org.atriaSoft.gameEngine.camera.Camera;
|
||||
import org.atriaSoft.gameEngine.components.ComponentGravityStatic;
|
||||
import org.atriaSoft.gameEngine.components.ComponentLight;
|
||||
import org.atriaSoft.gameEngine.components.ComponentLightSun;
|
||||
import org.atriaSoft.gameEngine.components.ComponentMaterial;
|
||||
@ -57,14 +58,21 @@ public class LoxelApplication extends Application {
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Context _context) {
|
||||
// set the system global max speed
|
||||
ComponentPhysics.globalMaxSpeed = 3;
|
||||
Gale.getContext().grabPointerEvents(true, new Vector2f(0,0));
|
||||
env = new Environement();
|
||||
this.canDraw = true;
|
||||
setSize(new Vector2f(800, 600));
|
||||
setTitle("Low Poly sample");
|
||||
setTitle("Loxel sample");
|
||||
map = new MapVoxel(this.env);
|
||||
this.env.addEngine(map);
|
||||
map.init();
|
||||
|
||||
// simple sun to have a global light ...
|
||||
Entity globalGravity = new Entity(this.env);
|
||||
globalGravity.addComponent(new ComponentGravityStatic(new Vector3f(0,0,-1)));
|
||||
env.addEntity(globalGravity);
|
||||
|
||||
// simple sun to have a global light ...
|
||||
Entity sun = new Entity(this.env);
|
||||
@ -105,10 +113,11 @@ public class LoxelApplication extends Application {
|
||||
new Uri("DATA", "basicMaterial.vert"),
|
||||
new Uri("DATA", "basicMaterial.frag"),
|
||||
(EngineLight)env.getEngine(EngineLight.ENGINE_NAME)));
|
||||
ComponentPhysics physics = new ComponentPhysics();
|
||||
ComponentPhysics physics = new ComponentPhysics(true);
|
||||
PhysicBox box = new PhysicBox();
|
||||
box.setSize(new Vector3f(0.6f,0.6f,1.8f));
|
||||
box.setOrigin(new Vector3f(0,0,0.9f));
|
||||
box.setMass(1);
|
||||
physics.addShape(box);
|
||||
player.addComponent(physics);
|
||||
env.addEntity(player);
|
||||
|
Loading…
Reference in New Issue
Block a user