[DEV] proto of map editor for future gane ==> state we need to externalize it
This commit is contained in:
parent
8d2e6305da
commit
f0c86f20de
17
samples/resources/mapFactory/data/basic.frag
Normal file
17
samples/resources/mapFactory/data/basic.frag
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#version 400 core
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in vec2 io_textureCoords;
|
||||||
|
|
||||||
|
uniform sampler2D in_textureBase;
|
||||||
|
|
||||||
|
// output:
|
||||||
|
out vec4 out_Color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
out_Color = texture(in_textureBase, io_textureCoords);
|
||||||
|
}
|
21
samples/resources/mapFactory/data/basic.vert
Normal file
21
samples/resources/mapFactory/data/basic.vert
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#version 400 core
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
layout (location = 0) in vec3 in_position;
|
||||||
|
layout (location = 1) in vec2 in_textureCoords;
|
||||||
|
uniform mat4 in_matrixTransformation;
|
||||||
|
uniform mat4 in_matrixProjection;
|
||||||
|
uniform mat4 in_matrixView;
|
||||||
|
|
||||||
|
// output:
|
||||||
|
out vec2 io_textureCoords;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gl_Position = in_matrixProjection * in_matrixView * in_matrixTransformation * vec4(in_position, 1.0);
|
||||||
|
io_textureCoords = in_textureCoords;
|
||||||
|
}
|
87
samples/resources/mapFactory/data/basicPalette.frag
Normal file
87
samples/resources/mapFactory/data/basicPalette.frag
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#version 400 core
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec3 color;
|
||||||
|
vec3 position;
|
||||||
|
vec3 attenuation;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const int MAX_LIGHT_NUMBER = 8;
|
||||||
|
|
||||||
|
|
||||||
|
in vec2 io_textureCoords;
|
||||||
|
in vec3 io_surfaceNormal;
|
||||||
|
in vec3 io_toCameraVector;
|
||||||
|
in vec3 io_toLightVector[MAX_LIGHT_NUMBER];
|
||||||
|
// FOW: Fog Of War result calculation
|
||||||
|
in float io_fowVisibility;
|
||||||
|
|
||||||
|
// texture properties
|
||||||
|
uniform sampler2D in_textureBase;
|
||||||
|
// Material
|
||||||
|
//uniform Material in_material;
|
||||||
|
// 2 light for suns and other for locals ...
|
||||||
|
uniform Light in_lights[MAX_LIGHT_NUMBER];
|
||||||
|
// global color of the sky ... needed to have a better color for the FOW
|
||||||
|
//uniform vec3 in_sky_color;
|
||||||
|
const vec3 in_sky_color = vec3(1.0,1.0,1.0);
|
||||||
|
|
||||||
|
// output:
|
||||||
|
out vec4 out_Color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// disable transparency elements in the texture ...
|
||||||
|
// Can be set at the start of the shader ...
|
||||||
|
/*
|
||||||
|
vec4 textureColour = texture(in_textureBase, io_textureCoords);
|
||||||
|
if (textureColour.a < 0.5) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//vec4 textureColour = vec4(1.0,1.0,1.0,1.0);
|
||||||
|
// keep material:
|
||||||
|
vec3 tex_ambientFactor = texture(in_textureBase, vec2(io_textureCoords.x, 4.5/8.0)).xyz;
|
||||||
|
//vec3 tex_diffuseFactor = texture(in_textureBase, vec2(io_textureCoords.x, 0.5/8.0)).xyz;
|
||||||
|
//vec4 textureColour = texture(in_textureBase, vec2(io_textureCoords.x, 0.5/8.0));
|
||||||
|
vec4 textureColour = texture(in_textureBase, io_textureCoords);
|
||||||
|
vec3 tex_specularFactor = texture(in_textureBase, vec2(io_textureCoords.x, 2.5/8.0)).xyz;
|
||||||
|
float tex_shininess = texture(in_textureBase, vec2(io_textureCoords.x, 6.5/8.0)).x;
|
||||||
|
|
||||||
|
vec3 unitNormal = normalize(io_surfaceNormal);
|
||||||
|
vec3 unitVectorToCamera = normalize(io_toCameraVector);
|
||||||
|
vec3 totalDiffuse = vec3(0.0);
|
||||||
|
vec3 totalSpecular = vec3(0.0);
|
||||||
|
for(int iii=0; iii<MAX_LIGHT_NUMBER; iii++) {
|
||||||
|
float distance = length(io_toLightVector[iii]);
|
||||||
|
float attenuationFactor = in_lights[iii].attenuation.x + (in_lights[iii].attenuation.y * distance) + (in_lights[iii].attenuation.z * distance * distance);
|
||||||
|
vec3 unitLightVector = normalize(io_toLightVector[iii]);
|
||||||
|
float nDot1 = dot(unitNormal, unitLightVector);
|
||||||
|
float brightness = max(nDot1, 0.0);
|
||||||
|
vec3 lightDirection = -unitLightVector;
|
||||||
|
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
|
||||||
|
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
|
||||||
|
specularFactor = max(specularFactor, 0.0);
|
||||||
|
float damperFactor = pow(specularFactor, tex_shininess);
|
||||||
|
vec3 diffuse = (brightness * in_lights[iii].color) / attenuationFactor;
|
||||||
|
vec3 finalSpecular = (damperFactor * tex_specularFactor.x * in_lights[iii].color) / attenuationFactor; // TODO: Remove the x ....
|
||||||
|
totalDiffuse = totalDiffuse + diffuse;
|
||||||
|
totalSpecular = totalSpecular + finalSpecular;
|
||||||
|
}
|
||||||
|
// the 0.2 represent the ambiant lightning ==> maybe set an uniform for this
|
||||||
|
//totalDiffuse = max(totalDiffuse, 1.0);
|
||||||
|
//totalDiffuse = min(totalDiffuse, 0.4);
|
||||||
|
|
||||||
|
//////out_Color = vec4(totalDiffuse,1.0) * textureColour + vec4(totalSpecular, 1.0);
|
||||||
|
out_Color = (vec4(totalDiffuse,1.0)*0.5+0.5) * textureColour;
|
||||||
|
/////out_Color = mix(vec4(in_sky_color,1.0), out_Color, io_fowVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
59
samples/resources/mapFactory/data/basicPalette.vert
Normal file
59
samples/resources/mapFactory/data/basicPalette.vert
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#version 400 core
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec3 color;
|
||||||
|
vec3 position;
|
||||||
|
vec3 attenuation;
|
||||||
|
};
|
||||||
|
const int MAX_LIGHT_NUMBER = 8;
|
||||||
|
|
||||||
|
// Input:
|
||||||
|
layout (location = 0) in vec3 in_position;
|
||||||
|
layout (location = 1) in vec2 in_textureCoords;
|
||||||
|
layout (location = 2) in vec3 in_normal;
|
||||||
|
// 2 light for suns and other for locals ...
|
||||||
|
uniform Light in_lights[MAX_LIGHT_NUMBER];
|
||||||
|
|
||||||
|
uniform mat4 in_matrixTransformation;
|
||||||
|
uniform mat4 in_matrixProjection;
|
||||||
|
uniform mat4 in_matrixView;
|
||||||
|
|
||||||
|
//uniform float in_numberOfRows;
|
||||||
|
//uniform vec2 in_offset;
|
||||||
|
const float in_numberOfRows = 1;
|
||||||
|
const vec2 in_offset = vec2(0.0,0.0);
|
||||||
|
|
||||||
|
// Configuration of the FOV ==> TODO: Set it in parameter uniform ...
|
||||||
|
const float c_density = 0.007;
|
||||||
|
const float c_gradient = 1.5;
|
||||||
|
|
||||||
|
// output:
|
||||||
|
out vec2 io_textureCoords;
|
||||||
|
out vec3 io_surfaceNormal;
|
||||||
|
out vec3 io_toCameraVector;
|
||||||
|
out vec3 io_toLightVector[MAX_LIGHT_NUMBER];
|
||||||
|
// FOW: Fog Of War result calculation
|
||||||
|
out float io_fowVisibility;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec4 worldPosition = in_matrixTransformation * vec4(in_position, 1.0);
|
||||||
|
vec4 positionRelativeToCam = in_matrixView * worldPosition;
|
||||||
|
gl_Position = in_matrixProjection * positionRelativeToCam;
|
||||||
|
io_textureCoords = (in_textureCoords/in_numberOfRows) + in_offset;
|
||||||
|
|
||||||
|
io_surfaceNormal = (in_matrixTransformation * vec4(in_normal, 0.0)).xyz;
|
||||||
|
for(int iii=0;iii<MAX_LIGHT_NUMBER;iii++) {
|
||||||
|
io_toLightVector[iii] = in_lights[iii].position - worldPosition.xyz;
|
||||||
|
}
|
||||||
|
io_toCameraVector = (inverse(in_matrixView) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
|
||||||
|
|
||||||
|
float distance = length(positionRelativeToCam.xyz);
|
||||||
|
|
||||||
|
io_fowVisibility = exp(-pow((distance*c_density),c_gradient));
|
||||||
|
io_fowVisibility = clamp(io_fowVisibility, 0.0, 1.0);
|
||||||
|
}
|
BIN
samples/resources/mapFactory/data/clay.png
Normal file
BIN
samples/resources/mapFactory/data/clay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
46
samples/resources/mapFactory/data/cube-one.obj
Normal file
46
samples/resources/mapFactory/data/cube-one.obj
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Blender v2.82 (sub 7) OBJ File: 'cube.blend'
|
||||||
|
# www.blender.org
|
||||||
|
mtllib cube.mtl
|
||||||
|
o Cube
|
||||||
|
v 0.5 0.5 -0.5
|
||||||
|
v 0.5 -0.5 -0.5
|
||||||
|
v 0.5 0.5 0.5
|
||||||
|
v 0.5 -0.5 0.5
|
||||||
|
v -0.5 0.5 -0.5
|
||||||
|
v -0.5 -0.5 -0.5
|
||||||
|
v -0.5 0.5 0.5
|
||||||
|
v -0.5 -0.5 0.5
|
||||||
|
vt 0.875000 0.500000
|
||||||
|
vt 0.625000 0.750000
|
||||||
|
vt 0.625000 0.500000
|
||||||
|
vt 0.375000 1.000000
|
||||||
|
vt 0.375000 0.750000
|
||||||
|
vt 0.625000 0.000000
|
||||||
|
vt 0.375000 0.250000
|
||||||
|
vt 0.375000 0.000000
|
||||||
|
vt 0.375000 0.500000
|
||||||
|
vt 0.125000 0.750000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.625000 0.250000
|
||||||
|
vt 0.875000 0.750000
|
||||||
|
vt 0.625000 1.000000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 1.0000
|
||||||
|
vn -1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 -1.0000 0.0000
|
||||||
|
vn 1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 -1.0000
|
||||||
|
usemtl Material
|
||||||
|
s off
|
||||||
|
f 5/1/1 3/2/1 1/3/1
|
||||||
|
f 3/2/2 8/4/2 4/5/2
|
||||||
|
f 7/6/3 6/7/3 8/8/3
|
||||||
|
f 2/9/4 8/10/4 6/11/4
|
||||||
|
f 1/3/5 4/5/5 2/9/5
|
||||||
|
f 5/12/6 2/9/6 6/7/6
|
||||||
|
f 5/1/1 7/13/1 3/2/1
|
||||||
|
f 3/2/2 7/14/2 8/4/2
|
||||||
|
f 7/6/3 5/12/3 6/7/3
|
||||||
|
f 2/9/4 4/5/4 8/10/4
|
||||||
|
f 1/3/5 3/2/5 4/5/5
|
||||||
|
f 5/12/6 1/3/6 2/9/6
|
41
samples/resources/mapFactory/data/palette_1.json
Normal file
41
samples/resources/mapFactory/data/palette_1.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"default": {
|
||||||
|
"Ns":225.000000,
|
||||||
|
"Ka":"1.000000 1.000000 1.000000",
|
||||||
|
"Kd":"0.346704 0.558341 0.090842",
|
||||||
|
"Ks":"0.500000 0.500000 0.500000",
|
||||||
|
"Ke":"0.000000 0.000000 0.000000",
|
||||||
|
"vNi":1.000000,
|
||||||
|
"d":1.000000,
|
||||||
|
"illum":2
|
||||||
|
},
|
||||||
|
"palette": {
|
||||||
|
"leaf_1":{
|
||||||
|
"Kd":"0.346704 0.558341 0.090842"
|
||||||
|
},
|
||||||
|
"leaf_2":{
|
||||||
|
"Kd":"0.278894 0.278894 0.023153"
|
||||||
|
},
|
||||||
|
"leaf_3":{
|
||||||
|
"Kd":"0.800000 0.800000 0.800000"
|
||||||
|
},
|
||||||
|
"trunk_1":{
|
||||||
|
"Kd":"0.25 0.13 0.07"
|
||||||
|
},
|
||||||
|
"trunk_2":{
|
||||||
|
"Kd":"0.057805 0.039546 0.013702"
|
||||||
|
},
|
||||||
|
"grass_1":{
|
||||||
|
"Kd":"0.057805 1.0 0.013702"
|
||||||
|
},
|
||||||
|
"grass_2":{
|
||||||
|
"Kd":"1.0 0.0 0.013702"
|
||||||
|
},
|
||||||
|
"grass_3":{
|
||||||
|
"Kd":"1.0 1.0 0.013702"
|
||||||
|
},
|
||||||
|
"grass_4":{
|
||||||
|
"Kd":"0.0 0.0 1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,5 +11,7 @@ open module sample.atriasoft.ege {
|
|||||||
exports sample.atriasoft.ege.s1_texturedCube;
|
exports sample.atriasoft.ege.s1_texturedCube;
|
||||||
|
|
||||||
requires org.atriasoft.ege;
|
requires org.atriasoft.ege;
|
||||||
requires org.atriasoft.ewol; // for map factory
|
requires org.atriasoft.ewol;
|
||||||
|
requires org.atriasoft.etk;
|
||||||
|
requires org.atriasoft.gale; // for map factory
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package sample.atriasoft.ege.mapFactory;
|
package sample.atriasoft.ege.mapFactory;
|
||||||
|
|
||||||
|
import org.atriasoft.ege.ControlCameraSimple;
|
||||||
|
import org.atriasoft.ege.ControlInterface;
|
||||||
import org.atriasoft.ege.Entity;
|
import org.atriasoft.ege.Entity;
|
||||||
import org.atriasoft.ege.components.ComponentMesh;
|
import org.atriasoft.ege.components.ComponentMesh;
|
||||||
import org.atriasoft.ege.components.ComponentPosition;
|
import org.atriasoft.ege.components.ComponentPosition;
|
||||||
@ -9,16 +11,23 @@ import org.atriasoft.ege.engines.EngineLight;
|
|||||||
import org.atriasoft.etk.Uri;
|
import org.atriasoft.etk.Uri;
|
||||||
import org.atriasoft.etk.math.Transform3D;
|
import org.atriasoft.etk.math.Transform3D;
|
||||||
import org.atriasoft.etk.math.Vector3f;
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.ewol.event.EventEntry;
|
||||||
|
import org.atriasoft.ewol.event.EventInput;
|
||||||
|
|
||||||
|
import sample.atriasoft.ege.mapFactory.model.Map;
|
||||||
|
import sample.atriasoft.ege.mapFactory.tools.MapToolInterface;
|
||||||
|
|
||||||
public class ApplScene extends EgeScene {
|
public class ApplScene extends EgeScene {
|
||||||
Ground ground = new Ground();
|
//Ground ground = new Ground();
|
||||||
|
Map map = new Map();
|
||||||
|
private ControlInterface simpleControl;
|
||||||
|
private MapToolInterface currentTool = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public ApplScene() {
|
public ApplScene() {
|
||||||
addGenericGird();
|
addGenericGird();
|
||||||
|
|
||||||
// test entity
|
// test entity
|
||||||
Entity groundEntity = new Entity(this.env);
|
Entity groundEntity = new Entity(this.env);
|
||||||
ComponentPosition objectPosition = new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0)));
|
ComponentPosition objectPosition = new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0)));
|
||||||
@ -26,98 +35,71 @@ public class ApplScene extends EgeScene {
|
|||||||
//this.materialCube = new Material();
|
//this.materialCube = new Material();
|
||||||
//basicTree.addComponent(new ComponentMaterial(this.materialCube));
|
//basicTree.addComponent(new ComponentMaterial(this.materialCube));
|
||||||
//groundEntity.addComponent(new ComponentMesh(new Uri("DATA", "tree1.emf", "plop")));
|
//groundEntity.addComponent(new ComponentMesh(new Uri("DATA", "tree1.emf", "plop")));
|
||||||
groundEntity.addComponent(new ComponentMesh(this.ground.createMesh()));
|
groundEntity.addComponent(new ComponentMesh(this.map.ground.createMesh()));
|
||||||
groundEntity.addComponent(new ComponentTexturePalette(new Uri("DATA", "palette_1.json")));
|
groundEntity.addComponent(new ComponentTexturePalette(new Uri("DATA", "palette_1.json")));
|
||||||
//basicTree.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
|
//basicTree.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
|
||||||
groundEntity
|
groundEntity
|
||||||
.addComponent(new ComponentRenderMeshPalette(new Uri("DATA", "basicPalette.vert"), new Uri("DATA", "basicPalette.frag"), (EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
|
.addComponent(new ComponentRenderMeshPalette(new Uri("DATA", "basicPalette.vert"), new Uri("DATA", "basicPalette.frag"), (EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
|
||||||
this.env.addEntity(groundEntity);
|
this.env.addEntity(groundEntity);
|
||||||
this.ground.updateMesh();
|
|
||||||
|
this.map.updateMesh();
|
||||||
|
this.simpleControl = new ControlCameraSimple(this.mainView);
|
||||||
|
this.env.addControlInterface(this.simpleControl);
|
||||||
|
|
||||||
|
// add a cube to test collision ...
|
||||||
|
// final Entity localBox = new Entity(this.env);
|
||||||
|
// localBox.addComponent(new ComponentStaticMesh(new Uri("DATA", "cube-one.obj")));
|
||||||
|
// localBox.addComponent(new ComponentTexture(new Uri("DATA", "clay.png")));
|
||||||
|
// //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"), new Uri("DATA", "basic.frag")));
|
||||||
|
// this.posRay = new ComponentPosition(new Transform3D(new Vector3f(0, 4, 2.5f)));
|
||||||
|
//
|
||||||
|
// localBox.addComponent(this.posRay);
|
||||||
|
// //final ComponentPhysics physics2 = new ComponentPhysics(this.env);
|
||||||
|
// //final PhysicBox box2 = new PhysicBox();
|
||||||
|
// //box2.setSize(new Vector3f(2.0f, 2.0f, 2.0f));
|
||||||
|
// //box2.setOrigin(new Vector3f(0, 0, 0));
|
||||||
|
// //box2.setMass(1);
|
||||||
|
// //physics2.addShape(box2);
|
||||||
|
// //localBox.addComponent(physics2);
|
||||||
|
// this.env.addEntity(localBox);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MapToolInterface getCurrentTool() {
|
||||||
|
return this.currentTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDrawScene() {
|
||||||
|
if (this.currentTool != null) {
|
||||||
|
this.currentTool.onDraw(this.map);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEventEntry(final EventEntry event) {
|
||||||
|
if (this.currentTool != null) {
|
||||||
|
if (this.currentTool.onEventEntry(event, this.map, this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onEventEntry(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEventInput(final EventInput event) {
|
||||||
|
if (this.currentTool != null) {
|
||||||
|
if (this.currentTool.onEventInput(event, this.map, this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onEventInput(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentTool(MapToolInterface currentTool) {
|
||||||
|
this.currentTool = currentTool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
private float angleLight = 0;
|
|
||||||
private Quaternion basicRotation = Quaternion.IDENTITY;
|
|
||||||
private Quaternion basicRotation2 = Quaternion.IDENTITY;
|
|
||||||
private ComponentPosition lightPosition;
|
|
||||||
private Material materialCube;
|
|
||||||
private ComponentPosition objectPosition;
|
|
||||||
private ControlCameraSimple simpleControl;
|
|
||||||
|
|
||||||
public LowPolyApplication() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(final GaleContext context) {
|
|
||||||
|
|
||||||
// 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(1.0f, 1.0f, 1.0f), new Vector3f(0, 0, 0), new Vector3f(1.0f, 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, 1)));
|
|
||||||
localLight.addComponent(this.lightPosition);
|
|
||||||
localLight.addComponent(new ComponentStaticMesh(new Uri("DATA", "cube-one.obj")));
|
|
||||||
localLight.addComponent(new ComponentTexture(new Uri("DATA", "grass.png")));
|
|
||||||
localLight.addComponent(new ComponentLight(new Light(new Color(0.0f, 0.0f, 2.0f), new Vector3f(0, 0, 0), new Vector3f(0.8f, 0.01f, 0.002f))));
|
|
||||||
localLight.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
|
|
||||||
this.env.addEntity(localLight);
|
|
||||||
|
|
||||||
// Simple Gird
|
|
||||||
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);
|
|
||||||
|
|
||||||
// test entity
|
|
||||||
Entity basicTree = new Entity(this.env);
|
|
||||||
this.objectPosition = new ComponentPosition(new Transform3D(new Vector3f(0, 0, 0)));
|
|
||||||
basicTree.addComponent(this.objectPosition);
|
|
||||||
//this.materialCube = new Material();
|
|
||||||
//basicTree.addComponent(new ComponentMaterial(this.materialCube));
|
|
||||||
basicTree.addComponent(new ComponentMesh(new Uri("DATA", "tree1.emf")));
|
|
||||||
basicTree.addComponent(new ComponentTexturePalette(new Uri("DATA", "palette_1.json")));
|
|
||||||
//basicTree.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
|
|
||||||
basicTree.addComponent(new ComponentRenderMeshPalette(new Uri("DATA", "basicPalette.vert"), new Uri("DATA", "basicPalette.frag"),
|
|
||||||
(EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
|
|
||||||
this.env.addEntity(basicTree);
|
|
||||||
|
|
||||||
|
|
||||||
basicTree = new Entity(this.env);
|
|
||||||
this.objectPosition = new ComponentPosition(new Transform3D(new Vector3f(3, 2, 0)));
|
|
||||||
basicTree.addComponent(this.objectPosition);
|
|
||||||
//this.materialCube = new Material();
|
|
||||||
//basicTree.addComponent(new ComponentMaterial(this.materialCube));
|
|
||||||
basicTree.addComponent(new ComponentMesh(new Uri("DATA", "tree2.emf")));
|
|
||||||
basicTree.addComponent(new ComponentTexturePalette(new Uri("DATA", "palette_1.json")));
|
|
||||||
//basicTree.addComponent(new ComponentRenderTexturedStaticMesh(new Uri("DATA", "basic.vert", "loxelEngine"), new Uri("DATA", "basic.frag", "loxelEngine")));
|
|
||||||
basicTree.addComponent(new ComponentRenderMeshPalette(new Uri("DATA", "basicPalette.vert"), new Uri("DATA", "basicPalette.frag"),
|
|
||||||
(EngineLight) this.env.getEngine(EngineLight.ENGINE_NAME)));
|
|
||||||
this.env.addEntity(basicTree);
|
|
||||||
|
|
||||||
this.simpleControl = new ControlCameraSimple(mainView);
|
|
||||||
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));
|
|
||||||
// ready to let Gale & Ege manage the display
|
|
||||||
Log.info("==> Init APPL (END)");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKeyboard(final KeySpecial special, final KeyKeyboard type, final Character value, final KeyStatus state) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
@ -3,16 +3,18 @@ package sample.atriasoft.ege.mapFactory;
|
|||||||
import org.atriasoft.ege.Entity;
|
import org.atriasoft.ege.Entity;
|
||||||
import org.atriasoft.ege.Environement;
|
import org.atriasoft.ege.Environement;
|
||||||
import org.atriasoft.ege.camera.Camera;
|
import org.atriasoft.ege.camera.Camera;
|
||||||
|
import org.atriasoft.ege.camera.ProjectionInterface;
|
||||||
|
import org.atriasoft.ege.camera.ProjectionPerspective;
|
||||||
import org.atriasoft.ege.components.ComponentPosition;
|
import org.atriasoft.ege.components.ComponentPosition;
|
||||||
import org.atriasoft.ege.components.ComponentRenderColoredStaticMesh;
|
import org.atriasoft.ege.components.ComponentRenderColoredStaticMesh;
|
||||||
import org.atriasoft.ege.components.ComponentStaticMesh;
|
import org.atriasoft.ege.components.ComponentStaticMesh;
|
||||||
import org.atriasoft.ege.tools.MeshGenerator;
|
import org.atriasoft.ege.tools.MeshGenerator;
|
||||||
import org.atriasoft.esignal.Connection;
|
import org.atriasoft.esignal.Connection;
|
||||||
import org.atriasoft.etk.Uri;
|
import org.atriasoft.etk.Uri;
|
||||||
import org.atriasoft.etk.math.Matrix4f;
|
|
||||||
import org.atriasoft.etk.math.Transform3D;
|
import org.atriasoft.etk.math.Transform3D;
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
import org.atriasoft.etk.math.Vector3f;
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.ewol.event.EventEntry;
|
||||||
import org.atriasoft.ewol.event.EventInput;
|
import org.atriasoft.ewol.event.EventInput;
|
||||||
import org.atriasoft.ewol.event.EventTime;
|
import org.atriasoft.ewol.event.EventTime;
|
||||||
import org.atriasoft.ewol.widget.Widget;
|
import org.atriasoft.ewol.widget.Widget;
|
||||||
@ -35,6 +37,11 @@ public class EgeScene extends Widget {
|
|||||||
self.markToRedraw();
|
self.markToRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widget display camera
|
||||||
|
public Camera mainView;
|
||||||
|
// Widget view mode
|
||||||
|
public ProjectionInterface projection;
|
||||||
|
// Environment model system.
|
||||||
protected Environement env;
|
protected Environement env;
|
||||||
|
|
||||||
/// Periodic call handle to remove it when needed
|
/// Periodic call handle to remove it when needed
|
||||||
@ -51,10 +58,12 @@ public class EgeScene extends Widget {
|
|||||||
this.env = new Environement();
|
this.env = new Environement();
|
||||||
|
|
||||||
// default camera....
|
// default camera....
|
||||||
final Camera mainView = new Camera();
|
this.mainView = new Camera();
|
||||||
this.env.addCamera("default", mainView);
|
this.env.addCamera("default", this.mainView);
|
||||||
mainView.setPitch((float) Math.PI * -0.25f);
|
this.mainView.setPitch((float) Math.PI * -0.25f);
|
||||||
mainView.setPosition(new Vector3f(4, -5, 5));
|
this.mainView.setPosition(new Vector3f(4, -5, 5));
|
||||||
|
|
||||||
|
this.projection = new ProjectionPerspective();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,22 +86,26 @@ public class EgeScene extends Widget {
|
|||||||
Log.error("min size = " + this.minSize);
|
Log.error("min size = " + this.minSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getAspectRatio() {
|
protected float getAspectRatio() {
|
||||||
return this.size.x() / this.size.y();
|
return this.size.x() / this.size.y();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChangeSize() {
|
||||||
|
super.onChangeSize();
|
||||||
|
// update the projection matrix on the view size;
|
||||||
|
this.projection.updateMatrix(getSize());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw() {
|
protected void onDraw() {
|
||||||
//Log.info("==> appl Draw ...");
|
|
||||||
final Vector2f size = getSize();
|
|
||||||
// Store openGl context.
|
// Store openGl context.
|
||||||
OpenGL.push();
|
OpenGL.push();
|
||||||
// set projection matrix:
|
// set projection matrix:
|
||||||
final Matrix4f tmpProjection = Matrix4f.createMatrixPerspective(3.14f * 0.5f, getAspectRatio(), 0.1f, 50000);
|
OpenGL.setMatrix(this.projection.getMatrix());
|
||||||
OpenGL.setMatrix(tmpProjection);
|
|
||||||
|
|
||||||
// set the basic openGL view port: (Draw in all the windows...)
|
// set the basic openGL view port: (Draw in all the windows...)
|
||||||
OpenGL.setViewPort(new Vector2f(0, 0), size);
|
OpenGL.setViewPort(new Vector2f(0, 0), getSize());
|
||||||
|
|
||||||
// clear background
|
// clear background
|
||||||
//final Color bgColor = new Color(0.0f, 1.0f, 0.0f, 1.0f);
|
//final Color bgColor = new Color(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
@ -102,6 +115,7 @@ public class EgeScene extends Widget {
|
|||||||
OpenGL.clear(OpenGL.ClearFlag.clearFlag_depthBuffer);
|
OpenGL.clear(OpenGL.ClearFlag.clearFlag_depthBuffer);
|
||||||
OpenGL.enable(Flag.flag_depthTest);
|
OpenGL.enable(Flag.flag_depthTest);
|
||||||
this.env.render(20, "default");
|
this.env.render(20, "default");
|
||||||
|
onDrawScene();
|
||||||
OpenGL.disable(Flag.flag_depthTest);
|
OpenGL.disable(Flag.flag_depthTest);
|
||||||
OpenGL.clear(OpenGL.ClearFlag.clearFlag_depthBuffer);
|
OpenGL.clear(OpenGL.ClearFlag.clearFlag_depthBuffer);
|
||||||
|
|
||||||
@ -109,11 +123,24 @@ public class EgeScene extends Widget {
|
|||||||
OpenGL.pop();
|
OpenGL.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onDrawScene() {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEventEntry(final EventEntry event) {
|
||||||
|
this.env.onKeyboard(event.specialKey(), event.type(), event.getChar(), event.status());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onEventInput(final EventInput event) {
|
public boolean onEventInput(final EventInput event) {
|
||||||
|
keepFocus();
|
||||||
Vector2f relPos = relativePosition(event.pos());
|
Vector2f relPos = relativePosition(event.pos());
|
||||||
Log.warning("Event on Input ... " + event + " relPos = " + relPos);
|
//Log.warning("Event on Input ... " + event + " relPos = " + relPos);
|
||||||
return false;
|
this.env.onPointer(event.specialKey(), event.type(), event.inputId(), relPos, event.status());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
package sample.atriasoft.ege.mapFactory;
|
package sample.atriasoft.ege.mapFactory;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import org.atriasoft.etk.Color;
|
||||||
|
import org.atriasoft.etk.math.Transform3D;
|
||||||
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
import org.atriasoft.etk.math.Vector4f;
|
import org.atriasoft.etk.math.Vector4f;
|
||||||
|
import org.atriasoft.gale.resource.ResourceColored3DObject;
|
||||||
import org.atriasoft.loader3d.model.Material;
|
import org.atriasoft.loader3d.model.Material;
|
||||||
import org.atriasoft.loader3d.resources.ResourceMeshHeightMap;
|
import org.atriasoft.loader3d.resources.ResourceMeshHeightMap;
|
||||||
|
|
||||||
|
import toolbox.Maths;
|
||||||
|
|
||||||
public class Ground {
|
public class Ground {
|
||||||
int sizeX = 16;
|
int sizeX = 16;
|
||||||
int sizeY = 16;
|
int sizeY = 16;
|
||||||
@ -30,11 +38,46 @@ public class Ground {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeHeightOfElement(Vector3f position, float distance, BiFunction<Float, Float, Float> applyer) {
|
||||||
|
for (int yyy = 0; yyy < this.sizeY; yyy++) {
|
||||||
|
for (int xxx = 0; xxx < this.sizeX; xxx++) {
|
||||||
|
float offset = 0.0f;
|
||||||
|
if (xxx % 2 == 1) {
|
||||||
|
offset = 0.5f;
|
||||||
|
}
|
||||||
|
float dist2 = position.less(xxx, yyy + offset, 0).length2();
|
||||||
|
if (dist2 < distance * distance) {
|
||||||
|
this.heightMap[yyy][xxx] = applyer.apply(this.heightMap[yyy][xxx], Maths.sqrt(dist2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateMesh();
|
||||||
|
}
|
||||||
|
|
||||||
public ResourceMeshHeightMap createMesh() {
|
public ResourceMeshHeightMap createMesh() {
|
||||||
return this.mesh;
|
return this.mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void drawDynamicElement(ResourceColored3DObject dynamicElement, Vector3f position, float distance) {
|
||||||
|
for (int yyy = 0; yyy < this.sizeY; yyy++) {
|
||||||
|
for (int xxx = 0; xxx < this.sizeX; xxx++) {
|
||||||
|
float dist2 = position.less(xxx, yyy, 0).length2();
|
||||||
|
if (dist2 < distance * distance) {
|
||||||
|
float coneHeight = 0.6f;
|
||||||
|
float offset = 0.0f;
|
||||||
|
if (xxx % 2 == 1) {
|
||||||
|
offset = 0.5f;
|
||||||
|
}
|
||||||
|
Transform3D tmpTransform = new Transform3D(new Vector3f(xxx, yyy + offset, this.heightMap[yyy][xxx] + coneHeight * 0.5f));
|
||||||
|
dynamicElement.drawCone(coneHeight * 0.5f, coneHeight, 10, 3, tmpTransform.getOpenGLMatrix(), Color.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void updateMesh() {
|
public void updateMesh() {
|
||||||
|
this.mesh.clearData();
|
||||||
Material mat = new Material();
|
Material mat = new Material();
|
||||||
this.mesh.addMaterial(this.baseNamePalette, mat);
|
this.mesh.addMaterial(this.baseNamePalette, mat);
|
||||||
mat.setAmbientFactor(new Vector4f(1, 0, 0, 1.0f));
|
mat.setAmbientFactor(new Vector4f(1, 0, 0, 1.0f));
|
||||||
|
@ -6,6 +6,8 @@ import org.atriasoft.ewol.widget.Sizer;
|
|||||||
import org.atriasoft.ewol.widget.Sizer.DisplayMode;
|
import org.atriasoft.ewol.widget.Sizer.DisplayMode;
|
||||||
import org.atriasoft.ewol.widget.Windows;
|
import org.atriasoft.ewol.widget.Windows;
|
||||||
|
|
||||||
|
import sample.atriasoft.ege.mapFactory.tools.ToolMapHeight;
|
||||||
|
|
||||||
public class MainWindows extends Windows {
|
public class MainWindows extends Windows {
|
||||||
|
|
||||||
public static void eventButtonIncrease(final MainWindows self) {
|
public static void eventButtonIncrease(final MainWindows self) {
|
||||||
@ -18,7 +20,20 @@ public class MainWindows extends Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void eventButtonTool(final MainWindows self) {
|
||||||
|
//Vector2b state = self.testWidget.getPropertyFill();
|
||||||
|
//self.testWidget.setPropertyFill(state.withY(!state.y()));
|
||||||
|
if (self.toolButton.getPropertyValue() == "Brush") {
|
||||||
|
self.toolButton.setPropertyValue("Heigher");
|
||||||
|
self.scene.setCurrentTool(new ToolMapHeight());
|
||||||
|
} else {
|
||||||
|
self.toolButton.setPropertyValue("Brush");
|
||||||
|
self.scene.setCurrentTool(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Button heightButton;
|
Button heightButton;
|
||||||
|
Button toolButton;
|
||||||
ApplScene scene;
|
ApplScene scene;
|
||||||
|
|
||||||
public MainWindows() {
|
public MainWindows() {
|
||||||
@ -40,12 +55,23 @@ public class MainWindows extends Windows {
|
|||||||
sizerMenu.setPropertyFill(Vector2b.TRUE_TRUE);
|
sizerMenu.setPropertyFill(Vector2b.TRUE_TRUE);
|
||||||
sizerHoryMain.subWidgetAdd(sizerMenu);
|
sizerHoryMain.subWidgetAdd(sizerMenu);
|
||||||
|
|
||||||
|
this.toolButton = new Button();
|
||||||
|
this.toolButton.setPropertyValue("Heigher");
|
||||||
|
this.toolButton.setPropertyExpand(Vector2b.TRUE_FALSE);
|
||||||
|
this.toolButton.setPropertyFill(Vector2b.TRUE_TRUE);
|
||||||
|
sizerMenu.subWidgetAdd(this.toolButton);
|
||||||
|
this.toolButton.signalClick.connectAuto(this, MainWindows::eventButtonTool);
|
||||||
|
|
||||||
this.heightButton = new Button();
|
this.heightButton = new Button();
|
||||||
this.heightButton.setPropertyValue("Increase");
|
this.heightButton.setPropertyValue("Increase");
|
||||||
this.heightButton.setPropertyExpand(Vector2b.TRUE_FALSE);
|
this.heightButton.setPropertyExpand(Vector2b.TRUE_FALSE);
|
||||||
this.heightButton.setPropertyFill(Vector2b.TRUE_TRUE);
|
this.heightButton.setPropertyFill(Vector2b.TRUE_TRUE);
|
||||||
sizerMenu.subWidgetAdd(this.heightButton);
|
sizerMenu.subWidgetAdd(this.heightButton);
|
||||||
this.heightButton.signalClick.connectAuto(this, MainWindows::eventButtonIncrease);
|
this.heightButton.signalClick.connectAuto(this, MainWindows::eventButtonIncrease);
|
||||||
|
|
||||||
|
// set default tools:
|
||||||
|
this.scene.setCurrentTool(new ToolMapHeight());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -11,10 +11,10 @@ public class MapFactoryMain {
|
|||||||
Ewol.init();
|
Ewol.init();
|
||||||
Ege.init();
|
Ege.init();
|
||||||
Uri.setGroup("DATA", "data/");
|
Uri.setGroup("DATA", "data/");
|
||||||
Uri.setGroup("RES", "res");
|
//Uri.setGroup("RES", "res");
|
||||||
//Uri.addLibrary("loxelEngine", MainCollisionTest.class, "testDataLoxelEngine/");
|
//Uri.addLibrary("loxelEngine", MapFactoryMain.class, "testDataLoxelEngine/");
|
||||||
//Uri.addLibrary("plop", Appl.class, "resources/mapFactory/");
|
//Uri.addLibrary("plop", Appl.class, "resources/mapFactory/");
|
||||||
Uri.setApplication(Appl.class, "lowPoly");//, "resources/mapFactory/");
|
Uri.setApplication(Appl.class, "mapFactory");//, "resources/mapFactory/");
|
||||||
Ewol.run(new Appl(), args);
|
Ewol.run(new Appl(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
samples/src/sample/atriasoft/ege/mapFactory/model/Map.java
Normal file
12
samples/src/sample/atriasoft/ege/mapFactory/model/Map.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package sample.atriasoft.ege.mapFactory.model;
|
||||||
|
|
||||||
|
import sample.atriasoft.ege.mapFactory.Ground;
|
||||||
|
|
||||||
|
public class Map {
|
||||||
|
public Ground ground = new Ground();
|
||||||
|
|
||||||
|
public void updateMesh() {
|
||||||
|
this.ground.updateMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package sample.atriasoft.ege.mapFactory.tools;
|
||||||
|
|
||||||
|
import org.atriasoft.ewol.event.EventEntry;
|
||||||
|
import org.atriasoft.ewol.event.EventInput;
|
||||||
|
|
||||||
|
import sample.atriasoft.ege.mapFactory.EgeScene;
|
||||||
|
import sample.atriasoft.ege.mapFactory.model.Map;
|
||||||
|
|
||||||
|
public interface MapToolInterface {
|
||||||
|
void onDraw(Map map);
|
||||||
|
|
||||||
|
boolean onEventEntry(final EventEntry event, Map map, EgeScene widget);
|
||||||
|
|
||||||
|
boolean onEventInput(final EventInput event, Map relPos, EgeScene widget);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package sample.atriasoft.ege.mapFactory.tools;
|
||||||
|
|
||||||
|
import org.atriasoft.ege.geometry.Ray;
|
||||||
|
import org.atriasoft.etk.Color;
|
||||||
|
import org.atriasoft.etk.math.Transform3D;
|
||||||
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.ewol.event.EventEntry;
|
||||||
|
import org.atriasoft.ewol.event.EventInput;
|
||||||
|
import org.atriasoft.gale.key.KeyStatus;
|
||||||
|
import org.atriasoft.gale.resource.ResourceColored3DObject;
|
||||||
|
|
||||||
|
import sample.atriasoft.ege.mapFactory.EgeScene;
|
||||||
|
import sample.atriasoft.ege.mapFactory.Log;
|
||||||
|
import sample.atriasoft.ege.mapFactory.model.Map;
|
||||||
|
import toolbox.Maths;
|
||||||
|
|
||||||
|
public class ToolMapHeight implements MapToolInterface {
|
||||||
|
Vector3f positionRay = null;
|
||||||
|
float widthBrush = 3.0f;
|
||||||
|
float maxBrush = 10.0f;
|
||||||
|
float minBrush = -10.0f;
|
||||||
|
ResourceColored3DObject dynamicElement;
|
||||||
|
|
||||||
|
public ToolMapHeight() {
|
||||||
|
this.dynamicElement = ResourceColored3DObject.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(Map map) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
if (this.positionRay != null) {
|
||||||
|
map.ground.drawDynamicElement(this.dynamicElement, this.positionRay, this.widthBrush);
|
||||||
|
float size = this.maxBrush - this.minBrush;
|
||||||
|
Transform3D tmpTransform = new Transform3D(this.positionRay.add(new Vector3f(0.0f, 0.0f, this.minBrush + size * 0.5f)));
|
||||||
|
this.dynamicElement.drawCylinder(this.widthBrush, size, 10, 22, tmpTransform.getOpenGLMatrix(), Color.AZURE.withA(0.5f), false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEventEntry(EventEntry event, Map map, EgeScene widget) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEventInput(EventInput event, Map map, EgeScene widget) {
|
||||||
|
Vector2f relPos = widget.relativePosition(event.pos());
|
||||||
|
// simple ray-cast on the ground
|
||||||
|
Ray mouseRay = widget.mainView.getRayFromScreen(widget.projection, widget.getSize(), relPos);
|
||||||
|
this.positionRay = mouseRay.intersectPlane(new Vector3f(0.0f, 0.0f, 1.0f), 0.0f);
|
||||||
|
/*
|
||||||
|
if (this.positionRay != null) {
|
||||||
|
this.posRay.setTransform(this.posRay.getTransform().withPosition(this.positionRay));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (event.inputId() == 1 && (event.status() == KeyStatus.move || event.status() == KeyStatus.down)) {
|
||||||
|
if (this.positionRay != null) {
|
||||||
|
map.ground.changeHeightOfElement(this.positionRay, this.widthBrush, (value, distance) -> {
|
||||||
|
if (value > this.maxBrush) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value < this.minBrush) {
|
||||||
|
return Maths.avg(-128.0f, value + 0.1f, this.maxBrush);
|
||||||
|
}
|
||||||
|
return Maths.avg(this.minBrush, value + 0.1f, this.maxBrush);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event.inputId() == 3 && (event.status() == KeyStatus.move || event.status() == KeyStatus.down)) {
|
||||||
|
if (this.positionRay != null) {
|
||||||
|
map.ground.changeHeightOfElement(this.positionRay, this.widthBrush, (value, distance) -> {
|
||||||
|
if (value < this.minBrush) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value > this.maxBrush) {
|
||||||
|
return Maths.avg(this.minBrush, value - 0.1f, 128.0f);
|
||||||
|
}
|
||||||
|
return Maths.avg(this.minBrush, value - 0.1f, this.maxBrush);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// max brush
|
||||||
|
if (event.inputId() == 4 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getAltLeft() && event.specialKey().getCtrlLeft())) {
|
||||||
|
this.maxBrush = Maths.avg(this.minBrush + 0.1f, this.maxBrush + 0.1f, 128.0f);
|
||||||
|
Log.warning(" values: " + this.minBrush + " / " + this.maxBrush);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event.inputId() == 5 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getAltLeft() && event.specialKey().getCtrlLeft())) {
|
||||||
|
this.maxBrush = Maths.avg(this.minBrush + 0.1f, this.maxBrush - 0.1f, 128.0f);
|
||||||
|
Log.warning(" values: " + this.minBrush + " / " + this.maxBrush);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// min brush
|
||||||
|
if (event.inputId() == 4 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getAltLeft())) {
|
||||||
|
this.minBrush = Maths.avg(-128.0f, this.minBrush + 0.1f, this.maxBrush - 0.1f);
|
||||||
|
Log.warning(" values: " + this.minBrush + " / " + this.maxBrush);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event.inputId() == 5 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getAltLeft())) {
|
||||||
|
this.minBrush = Maths.avg(-128.0f, this.minBrush - 0.1f, this.maxBrush - 0.1f);
|
||||||
|
Log.warning(" values: " + this.minBrush + " / " + this.maxBrush);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// width brush
|
||||||
|
if (event.inputId() == 4 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getCtrlLeft())) {
|
||||||
|
this.widthBrush = Maths.avg(0.1f, this.widthBrush + 0.1f, 30.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event.inputId() == 5 && event.status() == KeyStatus.down && (event.specialKey() != null && event.specialKey().getCtrlLeft())) {
|
||||||
|
this.widthBrush = Maths.avg(0.1f, this.widthBrush - 0.1f, 30.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,9 +12,6 @@ import org.atriasoft.gale.key.KeyStatus;
|
|||||||
|
|
||||||
public class ControlCameraSimple implements ControlInterface {
|
public class ControlCameraSimple implements ControlInterface {
|
||||||
private final Camera camera;
|
private final Camera camera;
|
||||||
private float distanceFromCenter = 20;
|
|
||||||
private float angleZ = 0;
|
|
||||||
private float pitch = 0;
|
|
||||||
private Vector2f lastMousePosition = null;
|
private Vector2f lastMousePosition = null;
|
||||||
private boolean moveUp = false;
|
private boolean moveUp = false;
|
||||||
private boolean moveLeft = false;
|
private boolean moveLeft = false;
|
||||||
@ -44,10 +41,10 @@ public class ControlCameraSimple implements ControlInterface {
|
|||||||
if (event.type() == KeyKeyboard.LEFT) {
|
if (event.type() == KeyKeyboard.LEFT) {
|
||||||
this.moveLeft = getState(event.status(), this.moveLeft);
|
this.moveLeft = getState(event.status(), this.moveLeft);
|
||||||
}
|
}
|
||||||
if (!event.specialKey().getCtrl() && event.type() == KeyKeyboard.RIGHT) {
|
if (event.type() == KeyKeyboard.RIGHT) {
|
||||||
this.moveRight = getState(event.status(), this.moveRight);
|
this.moveRight = getState(event.status(), this.moveRight);
|
||||||
}
|
}
|
||||||
if (!event.specialKey().getCtrl() && event.type() == KeyKeyboard.DOWN) {
|
if (event.type() == KeyKeyboard.DOWN) {
|
||||||
this.moveDown = getState(event.status(), this.moveDown);
|
this.moveDown = getState(event.status(), this.moveDown);
|
||||||
}
|
}
|
||||||
this.ctrlIsSet = event.specialKey().getCtrl();
|
this.ctrlIsSet = event.specialKey().getCtrl();
|
||||||
@ -56,17 +53,20 @@ public class ControlCameraSimple implements ControlInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onEventInput(final EventInput event, final Vector2f relativePosition) {
|
public boolean onEventInput(final EventInput event, final Vector2f relativePosition) {
|
||||||
Log.info("" + event);
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
if (event.inputId() == 4) {
|
if (event.inputId() == 4) {
|
||||||
|
Vector3f delta = this.camera.getConvertionMatrix().transpose().multiply(new Vector3f(0,0,-1));
|
||||||
if (event.status() == KeyStatus.down) {
|
if (event.status() == KeyStatus.down) {
|
||||||
this.distanceFromCenter -= 1;
|
this.camera.setPosition(this.camera.getPosition().add(delta.multiply(1.0f)));
|
||||||
}
|
}
|
||||||
} else if (event.inputId() == 5) {
|
}
|
||||||
|
if (event.inputId() == 5) {
|
||||||
|
Vector3f delta = this.camera.getConvertionMatrix().transpose().multiply(new Vector3f(0,0,-1));
|
||||||
if (event.status() == KeyStatus.down) {
|
if (event.status() == KeyStatus.down) {
|
||||||
this.distanceFromCenter += 1;
|
this.camera.setPosition(this.camera.getPosition().add(delta.multiply(-1.0f)));
|
||||||
}
|
}
|
||||||
} else if (event.inputId() == 2) {
|
}
|
||||||
|
if (event.inputId() == 2) {
|
||||||
if (event.status() == KeyStatus.down) {
|
if (event.status() == KeyStatus.down) {
|
||||||
this.lastMousePosition = event.pos();
|
this.lastMousePosition = event.pos();
|
||||||
} else if (event.status() == KeyStatus.move) {
|
} else if (event.status() == KeyStatus.move) {
|
||||||
@ -83,7 +83,6 @@ public class ControlCameraSimple implements ControlInterface {
|
|||||||
this.camera.setPitch((float) -Math.PI);
|
this.camera.setPitch((float) -Math.PI);
|
||||||
}
|
}
|
||||||
this.camera.setRoll(this.camera.getRoll() + (float) Math.toRadians(delta.x()));
|
this.camera.setRoll(this.camera.getRoll() + (float) Math.toRadians(delta.x()));
|
||||||
Log.info("Change camera: " + this.camera.getYaw() + " " + this.camera.getPitch());
|
|
||||||
if (this.camera.getRoll() > Math.PI) {
|
if (this.camera.getRoll() > Math.PI) {
|
||||||
this.camera.setRoll(this.camera.getRoll() - (float) Math.PI * 2.0f);
|
this.camera.setRoll(this.camera.getRoll() - (float) Math.PI * 2.0f);
|
||||||
}
|
}
|
||||||
@ -97,24 +96,26 @@ public class ControlCameraSimple implements ControlInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void periodicCall(final EventTime event) {
|
public void periodicCall(final EventTime event) {
|
||||||
|
float roll = this.camera.getRoll();
|
||||||
if (this.moveLeft != this.moveRight) {
|
if (this.moveLeft != this.moveRight) {
|
||||||
|
Vector3f orientation = new Vector3f(-(float)Math.cos(roll), (float)Math.sin(roll), 0);
|
||||||
if (this.moveRight) {
|
if (this.moveRight) {
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0.1f, 0, 0)));
|
this.camera.setPosition(this.camera.getPosition().add(orientation.multiply(-0.1f)));
|
||||||
} else {
|
} else {
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(-0.1f, 0, 0)));
|
this.camera.setPosition(this.camera.getPosition().add(orientation.multiply(0.1f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.ctrlIsSet) {
|
if (!this.ctrlIsSet) {
|
||||||
if (this.moveUp != this.moveDown) {
|
if (this.moveUp != this.moveDown) {
|
||||||
|
Vector3f orientation = new Vector3f((float)Math.sin(roll), (float)Math.cos(roll), 0);
|
||||||
if (this.moveUp) {
|
if (this.moveUp) {
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, 0.1f, 0)));
|
this.camera.setPosition(this.camera.getPosition().add(orientation.multiply(0.1f)));
|
||||||
} else {
|
} else {
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, -0.1f, 0)));
|
this.camera.setPosition(this.camera.getPosition().add(orientation.multiply(-0.1f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.moveUp != this.moveDown) {
|
} else if (this.moveUp != this.moveDown) {
|
||||||
if (this.moveUp) {
|
if (this.moveUp) {
|
||||||
|
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, 0, 0.1f)));
|
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, 0, 0.1f)));
|
||||||
} else {
|
} else {
|
||||||
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, 0, -0.1f)));
|
this.camera.setPosition(this.camera.getPosition().add(new Vector3f(0, 0, -0.1f)));
|
||||||
|
@ -71,7 +71,6 @@ public class Environement {
|
|||||||
addEngine(new EngineAI(this));
|
addEngine(new EngineAI(this));
|
||||||
addEngine(new EngineDynamicMeshs(this));
|
addEngine(new EngineDynamicMeshs(this));
|
||||||
addEngine(new EngineRender(this));
|
addEngine(new EngineRender(this));
|
||||||
//addEngine(new EnginePhysics(this));
|
|
||||||
addEngine(new EnginePhysics(this));
|
addEngine(new EnginePhysics(this));
|
||||||
addEngine(new EngineParticle(this));
|
addEngine(new EngineParticle(this));
|
||||||
addEngine(new EngineLight(this));
|
addEngine(new EngineLight(this));
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package org.atriasoft.ege.camera;
|
package org.atriasoft.ege.camera;
|
||||||
|
|
||||||
|
import org.atriasoft.ege.camera.ProjectionInterface.ValueLine;
|
||||||
|
import org.atriasoft.ege.geometry.Ray;
|
||||||
import org.atriasoft.etk.math.Matrix4f;
|
import org.atriasoft.etk.math.Matrix4f;
|
||||||
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
import org.atriasoft.etk.math.Vector3f;
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.etk.math.Vector4f;
|
||||||
//import entities.Player;
|
|
||||||
//import renderEngine.DisplayManager;
|
|
||||||
|
|
||||||
public class Camera {
|
public class Camera {
|
||||||
private float pitch = 0;
|
private float pitch = 0;
|
||||||
private Vector3f position = new Vector3f(0, 0, 2);
|
private Vector3f position = new Vector3f(0, 0, 0);
|
||||||
private float roll = 0;
|
private float roll = 0;
|
||||||
private float yaw = 0;
|
private float yaw = 0;
|
||||||
|
|
||||||
@ -22,12 +23,6 @@ public class Camera {
|
|||||||
matrix = matrix.rotate(new Vector3f(0, 1, 0), getYaw());
|
matrix = matrix.rotate(new Vector3f(0, 1, 0), getYaw());
|
||||||
matrix = matrix.rotate(new Vector3f(0, 0, 1), getRoll());
|
matrix = matrix.rotate(new Vector3f(0, 0, 1), getRoll());
|
||||||
matrix = matrix.translate(new Vector3f(-this.position.x(), -this.position.y(), -this.position.z()));
|
matrix = matrix.translate(new Vector3f(-this.position.x(), -this.position.y(), -this.position.z()));
|
||||||
/*
|
|
||||||
matrix = matrix.rotate(new Vector3f(1, 0, 0), 0.0f);
|
|
||||||
matrix = matrix.rotate(new Vector3f(0, 1, 0), 0.0f);
|
|
||||||
matrix = matrix.rotate(new Vector3f(0, 0, 1), 0.75f);
|
|
||||||
matrix = matrix.translate(new Vector3f(0, 0, -7));
|
|
||||||
*/
|
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,4 +58,17 @@ public class Camera {
|
|||||||
this.yaw = yaw;
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ValueLine reverseTransform(ValueLine basicValues) {
|
||||||
|
Matrix4f cameraMatrix = getConvertionMatrix().transpose();
|
||||||
|
// invert Matrix:
|
||||||
|
Matrix4f cameraMatrixInverted = cameraMatrix.invert();
|
||||||
|
|
||||||
|
return new ValueLine(cameraMatrixInverted.multiply(basicValues.near()), // compute near
|
||||||
|
cameraMatrixInverted.multiply(basicValues.far())); // compute far
|
||||||
|
}
|
||||||
|
public Ray getRayFromScreen(ProjectionInterface projection, Vector2f diplaySize, Vector2f mousePosition) {
|
||||||
|
ValueLine elem = projection.reverseTransform(diplaySize, mousePosition);
|
||||||
|
ValueLine result = reverseTransform(elem);
|
||||||
|
return Ray.createFromPoint(result.near(), result.far());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
src/org/atriasoft/ege/camera/ProjectionInterface.java
Normal file
14
src/org/atriasoft/ege/camera/ProjectionInterface.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.atriasoft.ege.camera;
|
||||||
|
|
||||||
|
import org.atriasoft.etk.math.Matrix4f;
|
||||||
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
|
||||||
|
|
||||||
|
public interface ProjectionInterface {
|
||||||
|
public record ValueLine(Vector3f near, Vector3f far) {};
|
||||||
|
Matrix4f getMatrix();
|
||||||
|
Matrix4f updateMatrix(Vector2f diplaySize);
|
||||||
|
ValueLine reverseTransform(Vector2f diplaySize, Vector2f mousePosition);
|
||||||
|
|
||||||
|
}
|
69
src/org/atriasoft/ege/camera/ProjectionOrthogonal.java
Normal file
69
src/org/atriasoft/ege/camera/ProjectionOrthogonal.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package org.atriasoft.ege.camera;
|
||||||
|
|
||||||
|
import org.atriasoft.etk.math.Matrix4f;
|
||||||
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.etk.math.Vector4f;
|
||||||
|
|
||||||
|
public class ProjectionOrthogonal implements ProjectionInterface {
|
||||||
|
|
||||||
|
Matrix4f lastMatrix = Matrix4f.IDENTITY;
|
||||||
|
float angleViewRad = 3.14f * 0.5f;
|
||||||
|
float nearView = 0.1f;
|
||||||
|
float farView = 5000.0f;
|
||||||
|
|
||||||
|
protected float getAspectRatio(Vector2f size) {
|
||||||
|
return size.x() / size.y();
|
||||||
|
}
|
||||||
|
public void setAngleViewRad(float angle) {
|
||||||
|
this.angleViewRad = angle;
|
||||||
|
}
|
||||||
|
public float getAngleViewRad() {
|
||||||
|
return this.angleViewRad;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Matrix4f getMatrix() {
|
||||||
|
return lastMatrix;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Matrix4f updateMatrix(Vector2f diplaySize) {
|
||||||
|
lastMatrix = Matrix4f.createMatrixOrtho(
|
||||||
|
diplaySize.x() * -0.5f, diplaySize.x() * 0.5f, // width
|
||||||
|
diplaySize.y() * -0.5f, diplaySize.y() * 0.5f, // height
|
||||||
|
nearView, farView);;
|
||||||
|
return lastMatrix;
|
||||||
|
}
|
||||||
|
public float getNear() {
|
||||||
|
return nearView;
|
||||||
|
}
|
||||||
|
public void setNear(float nearView) {
|
||||||
|
this.nearView = nearView;
|
||||||
|
}
|
||||||
|
public float getFar() {
|
||||||
|
return farView;
|
||||||
|
}
|
||||||
|
public void setFar(float farView) {
|
||||||
|
this.farView = farView;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ValueLine reverseTransform(Vector2f diplaySize, Vector2f mousePosition) {
|
||||||
|
float mouse_pos_x_clip = mousePosition.x() / diplaySize.x() * 2.0f - 1.0f;
|
||||||
|
float mouse_pos_y_clip = mousePosition.y() / diplaySize.y() * 2.0f - 1.0f;
|
||||||
|
Vector4f mouse_pos_near_clip = new Vector4f(mouse_pos_x_clip, mouse_pos_y_clip, -1.0f, 1.0f);
|
||||||
|
Vector4f mouse_pos_far_clip = new Vector4f(mouse_pos_x_clip, mouse_pos_y_clip, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
Matrix4f projectionMatrix = getMatrix().transpose();
|
||||||
|
// invert Matrix:
|
||||||
|
Matrix4f projectionMatrixInverted = projectionMatrix.invert();
|
||||||
|
|
||||||
|
Vector4f mouse_pos_near_view = projectionMatrixInverted.multiply(mouse_pos_near_clip);
|
||||||
|
Vector4f mouse_pos_far_view = projectionMatrixInverted.multiply(mouse_pos_far_clip);
|
||||||
|
// only for perspective
|
||||||
|
//mouse_pos_near_view = mouse_pos_near_view.divide(mouse_pos_near_view.w());
|
||||||
|
//mouse_pos_far_view = mouse_pos_far_view.divide(mouse_pos_far_view.w());
|
||||||
|
|
||||||
|
return new ValueLine(new Vector3f(mouse_pos_near_view.x(), mouse_pos_near_view.y(), mouse_pos_near_view.z()),
|
||||||
|
new Vector3f(mouse_pos_far_view.x(), mouse_pos_far_view.y(), mouse_pos_far_view.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
src/org/atriasoft/ege/camera/ProjectionPerspective.java
Normal file
55
src/org/atriasoft/ege/camera/ProjectionPerspective.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package org.atriasoft.ege.camera;
|
||||||
|
|
||||||
|
import org.atriasoft.etk.math.Matrix4f;
|
||||||
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
import org.atriasoft.etk.math.Vector4f;
|
||||||
|
|
||||||
|
public class ProjectionPerspective implements ProjectionInterface {
|
||||||
|
Matrix4f lastMatrix = Matrix4f.IDENTITY;
|
||||||
|
float angleViewRad = 3.14f * 0.5f;
|
||||||
|
float nearView = 0.1f;
|
||||||
|
float farView = 5000.0f;
|
||||||
|
|
||||||
|
protected float getAspectRatio(Vector2f size) {
|
||||||
|
return size.x() / size.y();
|
||||||
|
}
|
||||||
|
public void setAngleViewRad(float angle) {
|
||||||
|
this.angleViewRad = angle;
|
||||||
|
}
|
||||||
|
public float getAngleViewRad() {
|
||||||
|
return this.angleViewRad;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Matrix4f getMatrix() {
|
||||||
|
return lastMatrix;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Matrix4f updateMatrix(Vector2f diplaySize) {
|
||||||
|
lastMatrix = Matrix4f.createMatrixPerspective(getAngleViewRad(), getAspectRatio(diplaySize), nearView, farView);;
|
||||||
|
return lastMatrix;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ValueLine reverseTransform(Vector2f diplaySize, Vector2f mousePosition) {
|
||||||
|
|
||||||
|
float mouse_pos_x_clip = mousePosition.x() / diplaySize.x() * 2.0f - 1.0f;
|
||||||
|
float mouse_pos_y_clip = mousePosition.y() / diplaySize.y() * 2.0f - 1.0f;
|
||||||
|
Vector4f mouse_pos_near_clip = new Vector4f(mouse_pos_x_clip, mouse_pos_y_clip, -1.0f, 1.0f);
|
||||||
|
Vector4f mouse_pos_far_clip = new Vector4f(mouse_pos_x_clip, mouse_pos_y_clip, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
Matrix4f projectionMatrix = getMatrix().transpose();
|
||||||
|
// invert Matrix:
|
||||||
|
Matrix4f projectionMatrixInverted = projectionMatrix.invert();
|
||||||
|
|
||||||
|
Vector4f mouse_pos_near_view = projectionMatrixInverted.multiply(mouse_pos_near_clip);
|
||||||
|
Vector4f mouse_pos_far_view = projectionMatrixInverted.multiply(mouse_pos_far_clip);
|
||||||
|
// only for perspective
|
||||||
|
mouse_pos_near_view = mouse_pos_near_view.divide(mouse_pos_near_view.w());
|
||||||
|
mouse_pos_far_view = mouse_pos_far_view.divide(mouse_pos_far_view.w());
|
||||||
|
|
||||||
|
return new ValueLine(new Vector3f(mouse_pos_near_view.x(), mouse_pos_near_view.y(), mouse_pos_near_view.z()),
|
||||||
|
new Vector3f(mouse_pos_far_view.x(), mouse_pos_far_view.y(), mouse_pos_far_view.z()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -97,7 +97,6 @@ public class EnginePhysics extends Engine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderDebug(long deltaMili, Camera camera) {
|
public void renderDebug(long deltaMili, Camera camera) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
DebugDisplay.onDraw();
|
DebugDisplay.onDraw();
|
||||||
DebugDisplay.clear();
|
DebugDisplay.clear();
|
||||||
}
|
}
|
||||||
@ -113,7 +112,7 @@ public class EnginePhysics extends Engine {
|
|||||||
applyForces(TIME_STEP);
|
applyForces(TIME_STEP);
|
||||||
// update AABB after because in rotation force, the Bounding box change...
|
// update AABB after because in rotation force, the Bounding box change...
|
||||||
updateAABB(TIME_STEP);
|
updateAABB(TIME_STEP);
|
||||||
// update the colision tree between each object in the room
|
// update the collision tree between each object in the room
|
||||||
updateCollisionsAABB(TIME_STEP);
|
updateCollisionsAABB(TIME_STEP);
|
||||||
updateCollisionsNarrowPhase(TIME_STEP);
|
updateCollisionsNarrowPhase(TIME_STEP);
|
||||||
generateResultCollisionsForces(TIME_STEP);
|
generateResultCollisionsForces(TIME_STEP);
|
||||||
|
@ -2,20 +2,15 @@ package org.atriasoft.ege.geometry;
|
|||||||
|
|
||||||
import org.atriasoft.etk.math.Vector3f;
|
import org.atriasoft.etk.math.Vector3f;
|
||||||
|
|
||||||
public class Ray {
|
import toolbox.Maths;
|
||||||
|
|
||||||
|
public record Ray(Vector3f origin, Vector3f direction) {
|
||||||
public static Ray createFromPoint(final Vector3f origin, final Vector3f destination) {
|
public static Ray createFromPoint(final Vector3f origin, final Vector3f destination) {
|
||||||
Ray out = new Ray(origin, destination.less(origin));
|
return new Ray(origin, destination.less(origin).safeNormalize());
|
||||||
out.normalizeDirection();
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f origin;
|
|
||||||
|
|
||||||
public Vector3f direction;
|
|
||||||
|
|
||||||
public Ray() {
|
public Ray() {
|
||||||
this.origin = Vector3f.ZERO;
|
this(Vector3f.ZERO, new Vector3f(0.0f, 0.0f, 1.0f));
|
||||||
this.direction = new Vector3f(0.0f, 0.0f, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ray(final Vector3f origin, final Vector3f direction) {
|
public Ray(final Vector3f origin, final Vector3f direction) {
|
||||||
@ -23,12 +18,160 @@ public class Ray {
|
|||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void normalizeDirection() {
|
|
||||||
this.direction = this.direction.safeNormalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Ray [origin=" + this.origin + ", direction=" + this.direction + "]";
|
return "Ray [origin=" + this.origin + ", direction=" + this.direction + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the position on the top or bottom plane describe in parameters.
|
||||||
|
* @param normalPlane Normal description of the plane.
|
||||||
|
* @param distancePlane distance to define the plane position.
|
||||||
|
* @return position on the plane intersection (null if not collide).
|
||||||
|
*/
|
||||||
|
public Vector3f intersectPlane(Vector3f normalPlane, float distancePlane) {
|
||||||
|
float denom = normalPlane.dot(this.direction);
|
||||||
|
// Prevent divide by zero:
|
||||||
|
if (Math.abs(denom) <= 1e-4f) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
float t = -(normalPlane.dot(this.origin) + distancePlane) / normalPlane.dot(this.direction);
|
||||||
|
|
||||||
|
// Use pointy end of the ray.
|
||||||
|
// It is technically correct to compare t < 0,
|
||||||
|
// but that may be undesirable in a raytracer.
|
||||||
|
if (t <= 1e-4) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.origin.add(this.direction.multiply(t));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the position on the top plane describe in parameters.
|
||||||
|
* @param normalPlane Normal description of the plane.
|
||||||
|
* @param distancePlane distance to define the plane position.
|
||||||
|
* @return position on the plane intersection (null if not collide).
|
||||||
|
*/
|
||||||
|
public Vector3f intersectPlaneTop(Vector3f normalPlane, float distancePlane) {
|
||||||
|
float denom = normalPlane.dot(this.direction);
|
||||||
|
|
||||||
|
if (-denom <= 1e-4f) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float t = -(normalPlane.dot(this.origin) + distancePlane) / normalPlane.dot(this.direction);
|
||||||
|
|
||||||
|
// Use pointy end of the ray.
|
||||||
|
// It is technically correct to compare t < 0,
|
||||||
|
// but that may be undesirable in a raytracer.
|
||||||
|
if (t <= 1e-4) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.origin.add(this.direction.multiply(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean intersectSphere(Vector3f sphereCenter, float sphereSize) {
|
||||||
|
//solve for tc
|
||||||
|
Vector3f L = sphereCenter.less(this.origin);
|
||||||
|
float tc = L.dot(this.direction);
|
||||||
|
if ( tc < 0.0f ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
float d2 = tc*tc - L.length2();
|
||||||
|
float radius2 = sphereSize * sphereSize;
|
||||||
|
if ( d2 > radius2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public record ReturnIntersectSphere(Vector3f pos1, Vector3f pos2) {};
|
||||||
|
|
||||||
|
public ReturnIntersectSphere intersectSpherePos(Vector3f sphereCenter, float sphereSize) {
|
||||||
|
//solve for tc
|
||||||
|
Vector3f L = sphereCenter.less(this.origin);
|
||||||
|
float tc = L.dot(this.direction);
|
||||||
|
if ( tc < 0.0f ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
float d2 = tc*tc - L.length2();
|
||||||
|
|
||||||
|
float radius2 = sphereSize * sphereSize;
|
||||||
|
if ( d2 > radius2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//solve for t1c
|
||||||
|
float t1c = (float) Math.sqrt( radius2 - d2 );
|
||||||
|
|
||||||
|
//solve for intersection points
|
||||||
|
float t1 = tc - t1c;
|
||||||
|
float t2 = tc + t1c;
|
||||||
|
|
||||||
|
return new ReturnIntersectSphere(this.origin.add(this.direction().multiply(t1)),
|
||||||
|
this.origin.add(this.direction().multiply(t2)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f intersectTriangle(
|
||||||
|
Vector3f orig, Vector3f dir,
|
||||||
|
Vector3f v0, Vector3f v1, Vector3f v2) {
|
||||||
|
float t = 0; // output distance.
|
||||||
|
// compute plane's normal
|
||||||
|
Vector3f v0v1 = v1.less(v0);
|
||||||
|
Vector3f v0v2 = v2.less(v0);
|
||||||
|
// no need to normalize
|
||||||
|
Vector3f N = v0v1.cross(v0v2); // N
|
||||||
|
float area2 = N.length();
|
||||||
|
|
||||||
|
// Step 1: finding P
|
||||||
|
|
||||||
|
// check if ray and plane are parallel ?
|
||||||
|
float NdotRayDirection = N.dot(dir);
|
||||||
|
if (Math.abs(NdotRayDirection) < 0.0000001) // almost 0
|
||||||
|
return null; // they are parallel so they don't intersect !
|
||||||
|
|
||||||
|
// compute d parameter using equation 2
|
||||||
|
float d = -N.dot(v0);
|
||||||
|
|
||||||
|
// compute t (equation 3)
|
||||||
|
t = -(N.dot(orig) + d) / NdotRayDirection;
|
||||||
|
|
||||||
|
// check if the triangle is in behind the ray
|
||||||
|
if (t < 0) {
|
||||||
|
return null; // the triangle is behind
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the intersection point using equation 1
|
||||||
|
Vector3f P = orig.add(dir.multiply(t));
|
||||||
|
|
||||||
|
// Step 2: inside-outside test
|
||||||
|
Vector3f C; // vector perpendicular to triangle's plane
|
||||||
|
|
||||||
|
// edge 0
|
||||||
|
Vector3f edge0 = v1.less(v0);
|
||||||
|
Vector3f vp0 = P.less(v0);
|
||||||
|
C = edge0.cross(vp0);
|
||||||
|
if (N.dot(C) < 0) {
|
||||||
|
return null; // P is on the right side
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge 1
|
||||||
|
Vector3f edge1 = v2.less(v1);
|
||||||
|
Vector3f vp1 = P.less(v1);
|
||||||
|
C = edge1.cross(vp1);
|
||||||
|
if (N.dot(C) < 0) {
|
||||||
|
return null; // P is on the right side
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge 2
|
||||||
|
Vector3f edge2 = v0.less(v2);
|
||||||
|
Vector3f vp2 = P.less(v2);
|
||||||
|
C = edge2.cross(vp2);
|
||||||
|
if (N.dot(C) < 0) {
|
||||||
|
return null; // P is on the right side;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.origin.add(this.direction().multiply(t)); // this ray hits the triangle
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,10 @@ import org.atriasoft.phyligram.ColisionPoint;
|
|||||||
import org.atriasoft.phyligram.PhysicSphere;
|
import org.atriasoft.phyligram.PhysicSphere;
|
||||||
import org.atriasoft.phyligram.PhysicTriangle;
|
import org.atriasoft.phyligram.PhysicTriangle;
|
||||||
|
|
||||||
|
import toolbox.Maths;
|
||||||
|
|
||||||
// https://realtimecollisiondetection.net/blog/?p=103
|
// https://realtimecollisiondetection.net/blog/?p=103
|
||||||
public class ToolCollisionSphereWithTriangle {
|
public class ToolCollisionSphereWithTriangle {
|
||||||
public static float clamp(float val, float min, float max) {
|
|
||||||
return Math.max(min, Math.min(max, val));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3f getClosestPointOnFiniteLine(Vector3f point, Vector3f lineStart, Vector3f lineEnd) {
|
|
||||||
Vector3f lineDirection = lineEnd.less(lineStart);
|
|
||||||
float lineLength = lineDirection.length();
|
|
||||||
lineDirection = lineDirection.normalize();
|
|
||||||
float position = point.less(lineStart).dot(lineDirection);
|
|
||||||
float ProjectionLength = clamp(position, 0, lineLength);
|
|
||||||
return lineStart.add(lineDirection.multiply(ProjectionLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ColisionPoint getCollisionPoint(PhysicSphere sphere1, PhysicTriangle shapeReference) {
|
public static ColisionPoint getCollisionPoint(PhysicSphere sphere1, PhysicTriangle shapeReference) {
|
||||||
Plane plane = new Plane(shapeReference.getTriangleGlobalPos());
|
Plane plane = new Plane(shapeReference.getTriangleGlobalPos());
|
||||||
@ -66,13 +56,13 @@ public class ToolCollisionSphereWithTriangle {
|
|||||||
System.out.println("Not in center");
|
System.out.println("Not in center");
|
||||||
|
|
||||||
// now we need to check if we have a collision with the border.
|
// now we need to check if we have a collision with the border.
|
||||||
Vector3f nearestPointP1 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p1, shapeReference.getTriangleGlobalPos().p2);
|
Vector3f nearestPointP1 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p1, shapeReference.getTriangleGlobalPos().p2);
|
||||||
float distanceP1Square = Vector3f.length2(nearestPointP1, sphere1.narrowPhaseGlobalPos);
|
float distanceP1Square = Vector3f.length2(nearestPointP1, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP1Square=" + distanceP1Square);
|
System.out.println("distanceP1Square=" + distanceP1Square);
|
||||||
Vector3f nearestPointP2 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p2, shapeReference.getTriangleGlobalPos().p3);
|
Vector3f nearestPointP2 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p2, shapeReference.getTriangleGlobalPos().p3);
|
||||||
float distanceP2Square = Vector3f.length2(nearestPointP2, sphere1.narrowPhaseGlobalPos);
|
float distanceP2Square = Vector3f.length2(nearestPointP2, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP2Square=" + distanceP2Square);
|
System.out.println("distanceP2Square=" + distanceP2Square);
|
||||||
Vector3f nearestPointP3 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p3, shapeReference.getTriangleGlobalPos().p1);
|
Vector3f nearestPointP3 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p3, shapeReference.getTriangleGlobalPos().p1);
|
||||||
float distanceP3Square = Vector3f.length2(nearestPointP3, sphere1.narrowPhaseGlobalPos);
|
float distanceP3Square = Vector3f.length2(nearestPointP3, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP3Square=" + distanceP3Square);
|
System.out.println("distanceP3Square=" + distanceP3Square);
|
||||||
float distanceFinal;
|
float distanceFinal;
|
||||||
@ -133,19 +123,19 @@ public class ToolCollisionSphereWithTriangle {
|
|||||||
System.out.println("Not in center");
|
System.out.println("Not in center");
|
||||||
|
|
||||||
// now we need to check if we have a collision with the border.
|
// now we need to check if we have a collision with the border.
|
||||||
Vector3f nearestPointP1 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p1, shapeReference.getTriangleGlobalPos().p2);
|
Vector3f nearestPointP1 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p1, shapeReference.getTriangleGlobalPos().p2);
|
||||||
float distanceP1Square = Vector3f.length2(nearestPointP1, sphere1.narrowPhaseGlobalPos);
|
float distanceP1Square = Vector3f.length2(nearestPointP1, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP1Square=" + distanceP1Square);
|
System.out.println("distanceP1Square=" + distanceP1Square);
|
||||||
if (distanceP1Square < distance2) {
|
if (distanceP1Square < distance2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Vector3f nearestPointP2 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p2, shapeReference.getTriangleGlobalPos().p3);
|
Vector3f nearestPointP2 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p2, shapeReference.getTriangleGlobalPos().p3);
|
||||||
float distanceP2Square = Vector3f.length2(nearestPointP2, sphere1.narrowPhaseGlobalPos);
|
float distanceP2Square = Vector3f.length2(nearestPointP2, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP2Square=" + distanceP2Square);
|
System.out.println("distanceP2Square=" + distanceP2Square);
|
||||||
if (distanceP2Square < distance2) {
|
if (distanceP2Square < distance2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Vector3f nearestPointP3 = getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p3, shapeReference.getTriangleGlobalPos().p1);
|
Vector3f nearestPointP3 = Maths.getClosestPointOnFiniteLine(sphere1.narrowPhaseGlobalPos, shapeReference.getTriangleGlobalPos().p3, shapeReference.getTriangleGlobalPos().p1);
|
||||||
float distanceP3Square = Vector3f.length2(nearestPointP3, sphere1.narrowPhaseGlobalPos);
|
float distanceP3Square = Vector3f.length2(nearestPointP3, sphere1.narrowPhaseGlobalPos);
|
||||||
System.out.println("distanceP3Square=" + distanceP3Square);
|
System.out.println("distanceP3Square=" + distanceP3Square);
|
||||||
if (distanceP3Square < distance2) {
|
if (distanceP3Square < distance2) {
|
||||||
|
@ -50,4 +50,32 @@ public class Maths {
|
|||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float clamp(float val, float min, float max) {
|
||||||
|
return Math.max(min, Math.min(max, val));
|
||||||
|
}
|
||||||
|
public static float avg(float min, float val, float max) {
|
||||||
|
return Math.max(min, Math.min(max, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3f getClosestPointOnFiniteLine(Vector3f point, Vector3f lineStart, Vector3f lineEnd) {
|
||||||
|
Vector3f lineDirection = lineEnd.less(lineStart);
|
||||||
|
float lineLength = lineDirection.length();
|
||||||
|
lineDirection = lineDirection.normalize();
|
||||||
|
float position = point.less(lineStart).dot(lineDirection);
|
||||||
|
float ProjectionLength = clamp(position, 0, lineLength);
|
||||||
|
return lineStart.add(lineDirection.multiply(ProjectionLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3f getClosestPointOnInfiniteLine(Vector3f point, Vector3f lineStart, Vector3f lineEnd) {
|
||||||
|
Vector3f lineDirection = lineEnd.less(lineStart);
|
||||||
|
lineDirection = lineDirection.normalize();
|
||||||
|
float position = point.less(lineStart).dot(lineDirection);
|
||||||
|
return lineStart.add(lineDirection.multiply(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sqrt(float dist2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return (float)Math.sqrt(dist2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user