tree model debug menu
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-09-23 00:26:01 -04:00
parent cd0452a77c
commit 63f0f3338c
18 changed files with 879 additions and 304 deletions

View File

@ -29,6 +29,15 @@
"growthModel": { "growthModel": {
"growthRate" : 0.001 "growthRate" : 0.001
}, },
"ambientAudio": {
"responseWindAudioFilePath": "Audio/ambienceWind1SeamlessMono.ogg",
"responseWindLoops": true,
"randomizeOffset": true,
"gainMultiplier": 0.9,
"emitterSpatialOffset": [0,3,0]
},
"graphicsTemplate": {
"proceduralModel": {
"treeModel": { "treeModel": {
"limbScalarFalloffFactor": 0.3, "limbScalarFalloffFactor": 0.3,
"minimumLimbScalar": 0.25, "minimumLimbScalar": 0.25,
@ -71,15 +80,9 @@
"offsetY" : 1.5, "offsetY" : 1.5,
"offsetZ" : 0 "offsetZ" : 0
} }
}, }
"ambientAudio": { }
"responseWindAudioFilePath": "Audio/ambienceWind1SeamlessMono.ogg", }
"responseWindLoops": true,
"randomizeOffset": true,
"gainMultiplier": 0.9,
"emitterSpatialOffset": [0,3,0]
},
"modelPath" : "Models/foliage/proceduralTree2/proceduralTree2v2.fbx"
} }
] ]

View File

@ -1,39 +1,73 @@
#version 330 core #version 450 core
//colorshift.fs //colorshift.fs
#define NR_POINT_LIGHTS 10 /**
Bind points for different SSBOs
*/
#define CLUSTER_SSBO_BIND_POINT 1
#define POINT_LIGHT_SSBO_BIND_POINT 2
#define DIRECT_LIGHT_SSBO_BIND_POINT 3
#define SMALL_EPSILON 0.0001
/**
Maximum number of point lights
*/
#define MAX_POINT_LIGHTS 512
/**
Maximum number of lights per cluster
*/
#define MAX_LIGHTS_PER_CLUSTER 100
/**
transparency
*/
#define SMALL_EPSILON 0.001
/**
The direct global light
*/
struct DirectLight {
vec3 direction;
vec3 color;
};
/**
A point light
*/
struct PointLight {
vec4 position;
vec4 color;
float constant;
float linear;
float quadratic;
float radius;
};
/**
A light cluster
*/
struct Cluster {
vec4 minPoint;
vec4 maxPoint;
uint count;
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
};
out vec4 FragColor; out vec4 FragColor;
layout (std140) uniform Lights { layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
// this is how many because we have to align Cluster clusters[];
// bytes it SHOULD in multiples of 16, this };
// take it where it ACTUALLY is
//
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
//
// base alignment aligned offset
//direct light
vec3 dLDirection; // 16 0
vec3 dLAmbient; // 16 16
vec3 dLDiffuse; // 16 32
vec3 dLSpecular; // 16 48
//point light layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64 PointLight pointLight[];
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224 };
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
//for a total size of 1184
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
DirectLight directLight;
}; };
struct Material { struct Material {
@ -43,6 +77,7 @@ struct Material {
}; };
in vec3 FragPos; in vec3 FragPos;
in vec3 ViewFragPos;
in vec3 Normal; in vec3 Normal;
in vec2 TexCoord; in vec2 TexCoord;
in vec4 FragPosLightSpace; in vec4 FragPosLightSpace;
@ -63,11 +98,19 @@ uniform int hasTransparency;
//light depth map //light depth map
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
/**
Used for light cluster calculation
*/
uniform float zNear;
uniform float zFar;
uniform uvec3 gridSize;
uniform uvec2 screenDimensions;
uniform mat4 view;
// function prototypes // function prototypes
// vec3 CalcDirLight(vec3 normal, vec3 viewDir); uint findCluster(vec3 FragPos, float zNear, float zFar);
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir); vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
float calcLightIntensityTotal(vec3 normal); float calcLightIntensityTotal(vec3 normal);
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
@ -77,7 +120,7 @@ void main(){
vec3 viewDir = normalize(viewPos - FragPos); vec3 viewDir = normalize(viewPos - FragPos);
//grab light intensity //grab light intensity
float lightIntensity = calcLightIntensityTotal(norm); vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
if(texture(material.diffuse, TexCoord).a < SMALL_EPSILON){ if(texture(material.diffuse, TexCoord).a < SMALL_EPSILON){
discard; discard;
@ -92,10 +135,25 @@ void main(){
); );
//shadow //shadow
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm); float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
//
//point light calculations
uint clusterIndex = findCluster(ViewFragPos, zNear, zFar);
uint pointLightCount = clusters[clusterIndex].count;
for(int i = 0; i < pointLightCount; i++){
uint pointLightIndex = clusters[clusterIndex].lightIndices[i];
PointLight pointLight = pointLight[pointLightIndex];
lightIntensity = lightIntensity + CalcPointLight(pointLight, norm, FragPos, viewDir);
}
//error checking on light clusters
if(pointLightCount > MAX_LIGHTS_PER_CLUSTER){
FragColor = vec4(1.0f,0.0f,0.0f,1);
return;
}
//calculate final color //calculate final color
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4); vec3 finalColor = textureColor * lightIntensity;
// vec3 lightAmount = CalcDirLight(norm, viewDir); // vec3 lightAmount = CalcDirLight(norm, viewDir);
// for(int i = 0; i < NR_POINT_LIGHTS; i++){ // for(int i = 0; i < NR_POINT_LIGHTS; i++){
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir); // lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
@ -127,13 +185,13 @@ void main(){
// //
float calcLightIntensityAmbient(){ float calcLightIntensityAmbient(){
//calculate average of ambient light //calculate average of ambient light
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0; float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
return avg; return avg;
} }
// //
float calcLightIntensityDir(vec3 normal){ float calcLightIntensityDir(vec3 normal){
vec3 lightDir = normalize(-dLDirection); vec3 lightDir = normalize(-directLight.direction);
// diffuse shading // diffuse shading
float diff = max(dot(normal, lightDir), 0.0); float diff = max(dot(normal, lightDir), 0.0);
@ -156,63 +214,53 @@ float calcLightIntensityTotal(vec3 normal){
// //
vec3 getTotalLightColor(vec3 normal){ vec3 getTotalLightColor(vec3 normal){
//get the direct light color adjusted for intensity //get the direct light color adjusted for intensity
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal); vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
//sum light colors //sum light colors
vec3 totalLightColor = diffuseLightColor; vec3 totalLightColor = diffuseLightColor;
return totalLightColor; return totalLightColor;
} }
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
vec3 lightDir = normalize(pLposition[i] - fragPos); vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
// diffuse shading // diffuse shading
float diff = max(dot(normal, lightDir), 0.0); float diff = max(dot(normal, lightDir), 0.0);
// specular shading // specular shading
// vec3 reflectDir = reflect(-lightDir, normal); // vec3 reflectDir = reflect(-lightDir, normal);
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation // attenuation
float distance = length(pLposition[i] - fragPos); float distance = length(pointLight.position.xyz - fragPos);
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance)); float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
if(distance > pointLight.radius){
attenuation = 0;
}
// combine results // combine results
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz; vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz; vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz; // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
ambient *= attenuation; ambient = ambient * attenuation;
diffuse *= attenuation; diffuse = diffuse * attenuation;
// specular *= attenuation; // specular *= attenuation;
vec3 specular = vec3(0,0,0); vec3 specular = vec3(0,0,0);
vec3 finalValue = (ambient + diffuse + specular); vec3 finalValue = vec3(0);
if(distance < pointLight.radius){
finalValue = (ambient + diffuse + specular);
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0)); finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
}
return finalValue; return finalValue;
} }
// // calculates the color when using a point light. /**
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ Finds the light cluster this fragment belongs to
// vec3 lightDir = normalize(pLposition[i] - fragPos); */
// // diffuse shading uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){
// float diff = max(dot(normal, lightDir), 0.0); uint zTile = uint((log(abs(viewspaceFragPos.z) / zNear) * gridSize.z) / log(zFar / zNear));
// // specular shading vec2 tileSize = screenDimensions / gridSize.xy;
// // vec3 reflectDir = reflect(-lightDir, normal); uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
// // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
// // attenuation }
// float distance = length(pLposition[i] - fragPos);
// float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
// // combine results
// vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
// vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
// // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
// ambient *= attenuation;
// diffuse *= attenuation;
// // specular *= attenuation;
// vec3 specular = vec3(0,0,0);
// vec3 finalValue = (ambient + diffuse + specular);
// finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
// return finalValue;
// }
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){ float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){

View File

@ -26,6 +26,7 @@ uniform mat4 lightSpaceMatrix;
//output buffers //output buffers
out vec3 Normal; out vec3 Normal;
out vec3 FragPos; out vec3 FragPos;
out vec3 ViewFragPos;
out vec2 TexCoord; out vec2 TexCoord;
out vec4 FragPosLightSpace; out vec4 FragPosLightSpace;
out vec3 colorShiftValue; out vec3 colorShiftValue;
@ -49,6 +50,7 @@ void main() {
//push frag, normal, and texture positions to fragment shader //push frag, normal, and texture positions to fragment shader
FragPos = vec3(model * FinalVertex); FragPos = vec3(model * FinalVertex);
ViewFragPos = vec3(view * model * FinalVertex);
Normal = mat3(transpose(inverse(model))) * aNormal; Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTex; TexCoord = aTex;

View File

@ -1,37 +1,68 @@
#version 330 core #version 450 core
//proceduraltree.fs //proceduraltree.fs
#define NR_POINT_LIGHTS 10 /**
Bind points for different SSBOs
*/
#define CLUSTER_SSBO_BIND_POINT 1
#define POINT_LIGHT_SSBO_BIND_POINT 2
#define DIRECT_LIGHT_SSBO_BIND_POINT 3
/**
Maximum number of point lights
*/
#define MAX_POINT_LIGHTS 512
/**
Maximum number of lights per cluster
*/
#define MAX_LIGHTS_PER_CLUSTER 100
/**
The direct global light
*/
struct DirectLight {
vec3 direction;
vec3 color;
};
/**
A point light
*/
struct PointLight {
vec4 position;
vec4 color;
float constant;
float linear;
float quadratic;
float radius;
};
/**
A light cluster
*/
struct Cluster {
vec4 minPoint;
vec4 maxPoint;
uint count;
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
};
out vec4 FragColor; out vec4 FragColor;
layout (std140) uniform Lights { layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
// this is how many because we have to align Cluster clusters[];
// bytes it SHOULD in multiples of 16, this };
// take it where it ACTUALLY is
//
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
//
// base alignment aligned offset
//direct light
vec3 dLDirection; // 16 0
vec3 dLAmbient; // 16 16
vec3 dLDiffuse; // 16 32
vec3 dLSpecular; // 16 48
//point light layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64 PointLight pointLight[];
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224 };
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
//for a total size of 1184
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
DirectLight directLight;
}; };
struct Material { struct Material {
@ -41,6 +72,7 @@ struct Material {
}; };
in vec3 FragPos; in vec3 FragPos;
in vec3 ViewFragPos;
in vec3 Normal; in vec3 Normal;
in vec2 TexCoord; in vec2 TexCoord;
in vec4 FragPosLightSpace; in vec4 FragPosLightSpace;
@ -60,11 +92,19 @@ uniform int hasTransparency;
//light depth map //light depth map
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
/**
Used for light cluster calculation
*/
uniform float zNear;
uniform float zFar;
uniform uvec3 gridSize;
uniform uvec2 screenDimensions;
uniform mat4 view;
// function prototypes // function prototypes
// vec3 CalcDirLight(vec3 normal, vec3 viewDir); uint findCluster(vec3 FragPos, float zNear, float zFar);
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir); vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
float calcLightIntensityTotal(vec3 normal); float calcLightIntensityTotal(vec3 normal);
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
@ -73,16 +113,31 @@ void main(){
vec3 viewDir = normalize(viewPos - FragPos); vec3 viewDir = normalize(viewPos - FragPos);
//grab light intensity //grab light intensity
float lightIntensity = calcLightIntensityTotal(norm); vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
//get color of base texture //get color of base texture
vec3 textureColor = texture(material.diffuse, TexCoord).rgb; vec3 textureColor = texture(material.diffuse, TexCoord).rgb;
//shadow //shadow
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm); float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
//
//point light calculations
uint clusterIndex = findCluster(ViewFragPos, zNear, zFar);
uint pointLightCount = clusters[clusterIndex].count;
for(int i = 0; i < pointLightCount; i++){
uint pointLightIndex = clusters[clusterIndex].lightIndices[i];
PointLight pointLight = pointLight[pointLightIndex];
lightIntensity = lightIntensity + CalcPointLight(pointLight, norm, FragPos, viewDir);
}
//error checking on light clusters
if(pointLightCount > MAX_LIGHTS_PER_CLUSTER){
FragColor = vec4(1.0f,0.0f,0.0f,1);
return;
}
//calculate final color //calculate final color
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4); vec3 finalColor = textureColor * lightIntensity;
// vec3 lightAmount = CalcDirLight(norm, viewDir); // vec3 lightAmount = CalcDirLight(norm, viewDir);
// for(int i = 0; i < NR_POINT_LIGHTS; i++){ // for(int i = 0; i < NR_POINT_LIGHTS; i++){
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir); // lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
@ -114,13 +169,13 @@ void main(){
// //
float calcLightIntensityAmbient(){ float calcLightIntensityAmbient(){
//calculate average of ambient light //calculate average of ambient light
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0; float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
return avg; return avg;
} }
// //
float calcLightIntensityDir(vec3 normal){ float calcLightIntensityDir(vec3 normal){
vec3 lightDir = normalize(-dLDirection); vec3 lightDir = normalize(-directLight.direction);
// diffuse shading // diffuse shading
float diff = max(dot(normal, lightDir), 0.0); float diff = max(dot(normal, lightDir), 0.0);
@ -143,63 +198,53 @@ float calcLightIntensityTotal(vec3 normal){
// //
vec3 getTotalLightColor(vec3 normal){ vec3 getTotalLightColor(vec3 normal){
//get the direct light color adjusted for intensity //get the direct light color adjusted for intensity
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal); vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
//sum light colors //sum light colors
vec3 totalLightColor = diffuseLightColor; vec3 totalLightColor = diffuseLightColor;
return totalLightColor; return totalLightColor;
} }
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
vec3 lightDir = normalize(pLposition[i] - fragPos); vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
// diffuse shading // diffuse shading
float diff = max(dot(normal, lightDir), 0.0); float diff = max(dot(normal, lightDir), 0.0);
// specular shading // specular shading
// vec3 reflectDir = reflect(-lightDir, normal); // vec3 reflectDir = reflect(-lightDir, normal);
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation // attenuation
float distance = length(pLposition[i] - fragPos); float distance = length(pointLight.position.xyz - fragPos);
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance)); float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
if(distance > pointLight.radius){
attenuation = 0;
}
// combine results // combine results
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz; vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz; vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz; // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
ambient *= attenuation; ambient = ambient * attenuation;
diffuse *= attenuation; diffuse = diffuse * attenuation;
// specular *= attenuation; // specular *= attenuation;
vec3 specular = vec3(0,0,0); vec3 specular = vec3(0,0,0);
vec3 finalValue = (ambient + diffuse + specular); vec3 finalValue = vec3(0);
if(distance < pointLight.radius){
finalValue = (ambient + diffuse + specular);
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0)); finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
}
return finalValue; return finalValue;
} }
// // calculates the color when using a point light. /**
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ Finds the light cluster this fragment belongs to
// vec3 lightDir = normalize(pLposition[i] - fragPos); */
// // diffuse shading uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){
// float diff = max(dot(normal, lightDir), 0.0); uint zTile = uint((log(abs(viewspaceFragPos.z) / zNear) * gridSize.z) / log(zFar / zNear));
// // specular shading vec2 tileSize = screenDimensions / gridSize.xy;
// // vec3 reflectDir = reflect(-lightDir, normal); uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
// // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
// // attenuation }
// float distance = length(pLposition[i] - fragPos);
// float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
// // combine results
// vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
// vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
// // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
// ambient *= attenuation;
// diffuse *= attenuation;
// // specular *= attenuation;
// vec3 specular = vec3(0,0,0);
// vec3 finalValue = (ambient + diffuse + specular);
// finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
// return finalValue;
// }
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){ float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){

View File

@ -30,6 +30,7 @@ uniform mat4 lightSpaceMatrix;
//output buffers //output buffers
out vec3 Normal; out vec3 Normal;
out vec3 FragPos; out vec3 FragPos;
out vec3 ViewFragPos;
out vec2 TexCoord; out vec2 TexCoord;
out vec4 FragPosLightSpace; out vec4 FragPosLightSpace;
@ -61,6 +62,7 @@ void main() {
//push frag, normal, and texture positions to fragment shader //push frag, normal, and texture positions to fragment shader
FragPos = vec3(model * FinalVertex); FragPos = vec3(model * FinalVertex);
ViewFragPos = vec3(view * model * FinalVertex);
Normal = mat3(transpose(inverse(model))) * aNormal; Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTex; TexCoord = aTex;

View File

@ -837,6 +837,7 @@ Fix static friction coeff causing player to slide on shallow slopes
- Turns out it needed auto disabling logic - Turns out it needed auto disabling logic
Change timescale for test Change timescale for test
Refactor graphics entity definitions to be under dedicated object Refactor graphics entity definitions to be under dedicated object
Tree model debug menu
# TODO # TODO

View File

@ -3,6 +3,7 @@ package electrosphere.client.ui.menu.debug;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;

View File

@ -3,6 +3,7 @@ package electrosphere.client.ui.menu.debug;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros;
import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.renderer.ui.imgui.ImGuiLinePlot; import electrosphere.renderer.ui.imgui.ImGuiLinePlot;

View File

@ -0,0 +1,135 @@
package electrosphere.client.ui.menu.debug.entity;
import java.util.Set;
import java.util.Random;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.tree.ProceduralTree;
import electrosphere.game.data.common.CommonEntityType;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.actor.ActorMeshMask;
import electrosphere.renderer.anim.AnimChannel;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.model.Bone;
import electrosphere.renderer.model.Mesh;
import electrosphere.renderer.model.Model;
import imgui.ImGui;
/**
* The actor tab on the entity detail view
*/
public class ImGuiEntityActorTab {
/**
* Client scene entity view
*/
protected static void drawActorView(boolean show, Entity detailViewEntity){
if(show && ImGui.collapsingHeader("Actor Details")){
ImGui.indent();
if(detailViewEntity != null && EntityUtils.getActor(detailViewEntity) != null){
Actor actor = EntityUtils.getActor(detailViewEntity);
CommonEntityType commonEntityData = CommonEntityUtils.getCommonData(detailViewEntity);
//procedural model
if(commonEntityData.getGraphicsTemplate().getProceduralModel() != null && ImGui.collapsingHeader("Procedural Model")){
if(ImGui.button("Regenerate")){
if(commonEntityData.getGraphicsTemplate().getProceduralModel().getTreeModel() != null){
ProceduralTree.setProceduralActor(
detailViewEntity,
commonEntityData.getGraphicsTemplate().getProceduralModel().getTreeModel(),
new Random()
);
}
}
}
//mesh mask
if(ImGui.collapsingHeader("Mesh Mask")){
ActorMeshMask meshMask = actor.getMeshMask();
ImGui.text("To Draw Meshes:");
for(Mesh mesh : meshMask.getToDrawMeshes()){
ImGui.text(mesh.getMeshName());
}
ImGui.text("Blocked Meshes:");
for(String blocked : meshMask.getBlockedMeshes()){
ImGui.text(blocked);
}
}
//animation queue
if(ImGui.collapsingHeader("Animation Queue")){
Set<ActorAnimationMask> animationQueue = actor.getAnimationQueue();
for(ActorAnimationMask mask : animationQueue){
ImGui.text(mask.getAnimationName() + " - " + mask.getPriority());
ImGui.text(mask.getDuration() + " " + mask.getTime());
}
}
//bone values
if(ImGui.collapsingHeader("Bone Values")){
for(Bone bone : actor.getBoneValues()){
ImGui.text(bone.boneID);
ImGui.text("Position: " + actor.getBonePosition(bone.boneID));
ImGui.text("Rotation: " + actor.getBoneRotation(bone.boneID));
ImGui.text(bone.getFinalTransform() + "");
}
}
//Draws all the bones in the world
if(ImGui.button("Draw Bones")){
Globals.renderingEngine.getDebugContentPipeline().getDebugBonesPipeline().setEntity(detailViewEntity);
}
//Browsable list of all animations with their data
if(ImGui.collapsingHeader("Animation Channel Data")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
ImGui.indent();
for(Animation animation : model.getAnimations()){
if(ImGui.collapsingHeader(animation.name)){
if(ImGui.button("Play")){
actor.playAnimation(animation.name, AnimationPriorities.getValue(AnimationPriorities.MODIFIER_MAX));
}
for(AnimChannel channel : animation.channels){
ImGui.pushID(channel.getNodeID());
if(ImGui.button("Fully describe")){
channel.fullDescribeChannel();
}
ImGui.text("=" + channel.getNodeID() + "=");
ImGui.text("" + channel.getCurrentPosition());
ImGui.text("" + channel.getCurrentRotation());
ImGui.text("" + channel.getCurrentScale());
ImGui.popID();
}
}
}
ImGui.unindent();
}
//print data macros
if(ImGui.collapsingHeader("Print Data")){
//print bone values
if(ImGui.button("Print current bone values")){
for(Bone bone : actor.getBoneValues()){
LoggerInterface.loggerRenderer.DEBUG(bone.boneID);
LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform());
}
}
//print animation keys
if(ImGui.button("Print animation keys")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
model.describeAllAnimations();
}
}
}
ImGui.unindent();
}
}
}

View File

@ -0,0 +1,253 @@
package electrosphere.client.ui.menu.debug.entity;
import java.util.Random;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.tree.ProceduralTree;
import electrosphere.game.data.common.CommonEntityType;
import electrosphere.game.data.foliage.type.TreeModel;
import electrosphere.game.data.graphics.ProceduralModel;
import electrosphere.renderer.actor.instance.InstancedActor;
import imgui.ImGui;
/**
* The actor tab on the entity detail view
*/
public class ImGuiEntityInstancedActorTab {
/**
* Client scene entity view
*/
protected static void drawInstancedActorView(boolean show, Entity detailViewEntity){
if(show && ImGui.collapsingHeader("Instanced Actor Details")){
ImGui.indent();
float[] limbScalarFalloffFactor = new float[1];
float[] minimumLimbScalar = new float[1];
float[] maximumLimbDispersion = new float[1];
float[] minimumLimbDispersion = new float[1];
int[] minimumNumberForks = new int[1];
int[] maximumNumberForks = new int[1];
int[] maximumTrunkSegments = new int[1];
int[] maximumBranchSegments = new int[1];
float[] maxBranchSegmentFalloffFactor = new float[1];
int[] minimumSegmentToSpawnLeaves = new int[1];
float[] minBranchHeightToStartSpawningLeaves = new float[1];
float[] maxBranchHeightToStartSpawningLeaves = new float[1];
float[] leafIncrement = new float[1];
int[] minLeavesToSpawnPerPoint = new int[1];
int[] maxLeavesToSpawnPerPoint = new int[1];
float[] leafDistanceFromCenter = new float[1];
float[] peelVariance = new float[1];
float[] peelMinimum = new float[1];
float[] swaySigmoidFactor = new float[1];
int[] minimumSwayTime = new int[1];
int[] swayTimeVariance = new int[1];
float[] yawVariance = new float[1];
float[] yawMinimum = new float[1];
float[] minimumScalarToGenerateSwayTree = new float[1];
float[] maximumScalarToGenerateSwayTree = new float[1];
if(detailViewEntity != null && InstancedActor.getInstancedActor(detailViewEntity) != null){
// InstancedActor actor = InstancedActor.getInstancedActor(detailViewEntity);
CommonEntityType commonEntityData = CommonEntityUtils.getCommonData(detailViewEntity);
//procedural model
if(commonEntityData.getGraphicsTemplate().getProceduralModel() != null && ImGui.collapsingHeader("Procedural Model")){
ProceduralModel proceduralModel = commonEntityData.getGraphicsTemplate().getProceduralModel();
if(ImGui.button("Regenerate")){
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
if(proceduralModel.getTreeModel() != null && ImGui.collapsingHeader("Tree Model")){
TreeModel treeModel = proceduralModel.getTreeModel();
maximumTrunkSegments[0] = treeModel.getMaximumTrunkSegments();
if(ImGui.sliderInt("maximumTrunkSegments", maximumTrunkSegments, 1, 8)){
treeModel.setMaximumTrunkSegments(maximumTrunkSegments[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
if(ImGui.collapsingHeader("Branches")){
limbScalarFalloffFactor[0] = treeModel.getLimbScalarFalloffFactor();
if(ImGui.sliderFloat("limbScalarFalloffFactor", limbScalarFalloffFactor, 0.01f, 1f)){
treeModel.setLimbScalarFalloffFactor(limbScalarFalloffFactor[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minimumLimbScalar[0] = treeModel.getMinimumLimbScalar();
if(ImGui.sliderFloat("minimumLimbScalar", minimumLimbScalar, 0.01f, 1f)){
treeModel.setLimbScalarFalloffFactor(minimumLimbScalar[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maximumLimbDispersion[0] = treeModel.getMaximumLimbDispersion();
if(ImGui.sliderFloat("maximumLimbDispersion", maximumLimbDispersion, 0.01f, 1f)){
treeModel.setMaximumLimbDispersion(maximumLimbDispersion[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minimumLimbDispersion[0] = treeModel.getMinimumLimbDispersion();
if(ImGui.sliderFloat("minimumLimbDispersion", minimumLimbDispersion, 0.01f, 1f)){
treeModel.setMinimumLimbDispersion(minimumLimbDispersion[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minimumNumberForks[0] = treeModel.getMinimumNumberForks();
if(ImGui.sliderInt("minimumNumberForks", minimumNumberForks, 1, 8)){
treeModel.setMinimumNumberForks(minimumNumberForks[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maximumNumberForks[0] = treeModel.getMaximumNumberForks();
if(ImGui.sliderInt("maximumNumberForks", maximumNumberForks, 1, 8)){
treeModel.setMaximumNumberForks(maximumNumberForks[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maximumBranchSegments[0] = treeModel.getMaximumBranchSegments();
if(ImGui.sliderInt("maximumBranchSegments", maximumBranchSegments, 1, 8)){
treeModel.setMaximumBranchSegments(maximumBranchSegments[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maxBranchSegmentFalloffFactor[0] = treeModel.getMaxBranchSegmentFalloffFactor();
if(ImGui.sliderFloat("maxBranchSegmentFalloffFactor", maxBranchSegmentFalloffFactor, 0.01f, 1f)){
treeModel.setMaxBranchSegmentFalloffFactor(maxBranchSegmentFalloffFactor[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
}
if(ImGui.collapsingHeader("Branch Sway")){
peelVariance[0] = (float)treeModel.getPeelVariance();
if(ImGui.sliderFloat("peelVariance", peelVariance, 0.01f, 3f)){
treeModel.setPeelVariance(peelVariance[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
peelMinimum[0] = (float)treeModel.getPeelMinimum();
if(ImGui.sliderFloat("peelMinimum", peelMinimum, 0.01f, 3f)){
treeModel.setPeelMinimum(peelMinimum[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
swaySigmoidFactor[0] = (float)treeModel.getSwaySigmoidFactor();
if(ImGui.sliderFloat("swaySigmoidFactor", swaySigmoidFactor, 0.01f, 3f)){
treeModel.setSwaySigmoidFactor(swaySigmoidFactor[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minimumSwayTime[0] = treeModel.getMinimumSwayTime();
if(ImGui.sliderInt("minimumSwayTime", minimumSwayTime, 1, 1000)){
treeModel.setMinimumSwayTime(minimumSwayTime[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
swayTimeVariance[0] = treeModel.getSwayTimeVariance();
if(ImGui.sliderInt("swayTimeVariance", swayTimeVariance, 1, 1000)){
treeModel.setSwayTimeVariance(swayTimeVariance[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
yawVariance[0] = (float)treeModel.getYawVariance();
if(ImGui.sliderFloat("yawVariance", yawVariance, 0.01f, 3f)){
treeModel.setYawVariance(yawVariance[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
yawMinimum[0] = (float)treeModel.getYawMinimum();
if(ImGui.sliderFloat("yawMinimum", yawMinimum, 0.01f, 3f)){
treeModel.setYawMinimum(yawMinimum[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minimumScalarToGenerateSwayTree[0] = (float)treeModel.getMinimumScalarToGenerateSwayTree();
if(ImGui.sliderFloat("minimumScalarToGenerateSwayTree", minimumScalarToGenerateSwayTree, 0.01f, 3f)){
treeModel.setMinimumScalarToGenerateSwayTree(minimumScalarToGenerateSwayTree[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maximumScalarToGenerateSwayTree[0] = (float)treeModel.getMaximumScalarToGenerateSwayTree();
if(ImGui.sliderFloat("maximumScalarToGenerateSwayTree", maximumScalarToGenerateSwayTree, 0.01f, 3f)){
treeModel.setMaximumScalarToGenerateSwayTree(maximumScalarToGenerateSwayTree[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
}
if(ImGui.collapsingHeader("Leaves")){
minimumSegmentToSpawnLeaves[0] = treeModel.getMinimumSegmentToSpawnLeaves();
if(ImGui.sliderInt("minimumSegmentToSpawnLeaves", minimumSegmentToSpawnLeaves, 1, 8)){
treeModel.setMinimumSegmentToSpawnLeaves(minimumSegmentToSpawnLeaves[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minBranchHeightToStartSpawningLeaves[0] = treeModel.getMinBranchHeightToStartSpawningLeaves();
if(ImGui.sliderFloat("minBranchHeightToStartSpawningLeaves", minBranchHeightToStartSpawningLeaves, 0.01f, 5f)){
treeModel.setMinBranchHeightToStartSpawningLeaves(minBranchHeightToStartSpawningLeaves[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maxBranchHeightToStartSpawningLeaves[0] = treeModel.getMaxBranchHeightToStartSpawningLeaves();
if(ImGui.sliderFloat("maxBranchHeightToStartSpawningLeaves", maxBranchHeightToStartSpawningLeaves, 0.01f, 5f)){
treeModel.setMaxBranchHeightToStartSpawningLeaves(maxBranchHeightToStartSpawningLeaves[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
leafIncrement[0] = treeModel.getLeafIncrement();
if(ImGui.sliderFloat("leafIncrement", leafIncrement, 0.01f, 1f)){
treeModel.setLeafIncrement(leafIncrement[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
minLeavesToSpawnPerPoint[0] = treeModel.getMinLeavesToSpawnPerPoint();
if(ImGui.sliderInt("minLeavesToSpawnPerPoint", minLeavesToSpawnPerPoint, 1, 8)){
treeModel.setMinLeavesToSpawnPerPoint(minLeavesToSpawnPerPoint[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
maxLeavesToSpawnPerPoint[0] = treeModel.getMaxLeavesToSpawnPerPoint();
if(ImGui.sliderInt("maxLeavesToSpawnPerPoint", maxLeavesToSpawnPerPoint, 1, 8)){
treeModel.setMaxLeavesToSpawnPerPoint(maxLeavesToSpawnPerPoint[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
leafDistanceFromCenter[0] = treeModel.getLeafDistanceFromCenter();
if(ImGui.sliderFloat("leafDistanceFromCenter", leafDistanceFromCenter, 0.01f, 3f)){
treeModel.setLeafDistanceFromCenter(leafDistanceFromCenter[0]);
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
}
}
}
}
}
ImGui.unindent();
}
}
/**
* Regenerates the procedural model for the entity
* @param detailViewEntity The entity
* @param proceduralModel The procedural model
*/
private static void regenerateModel(Entity detailViewEntity, ProceduralModel proceduralModel){
if(proceduralModel.getTreeModel() != null){
for(Entity child : AttachUtils.getChildrenList(detailViewEntity)){
ClientEntityUtils.destroyEntity(child);
}
AttachUtils.getChildrenList(detailViewEntity).clear();
ProceduralTree.setProceduralActor(
detailViewEntity,
proceduralModel.getTreeModel(),
new Random()
);
}
}
}

View File

@ -1,4 +1,4 @@
package electrosphere.client.ui.menu.debug; package electrosphere.client.ui.menu.debug.entity;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -23,13 +23,11 @@ import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.actor.ActorMeshMask; import electrosphere.renderer.actor.instance.InstancedActor;
import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.AnimChannel;
import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.model.Bone; import electrosphere.renderer.model.Bone;
import electrosphere.renderer.model.Mesh;
import electrosphere.renderer.model.Model; import electrosphere.renderer.model.Model;
import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
@ -44,8 +42,10 @@ import imgui.ImGui;
public class ImGuiEntityMacros { public class ImGuiEntityMacros {
//window for selecting entities to view //window for selecting entities to view
protected static ImGuiWindow clientEntityListWindow; public static ImGuiWindow clientEntityListWindow;
private static boolean filterToCreatures = true; //filters the entity list to just creatures private static boolean filterBasic = true; //filters out entities we probably wouldn't want to see (particles, terrain meshes, foliage cells, etc)
private static boolean filterToCreatures = false; //filters the entity list to just creatures
private static boolean filterToFoliage = false; //filters the entity list to just foliage
//window for viewing details about an entity //window for viewing details about an entity
protected static ImGuiWindow clientEntityDetailWindow; protected static ImGuiWindow clientEntityDetailWindow;
@ -54,6 +54,7 @@ public class ImGuiEntityMacros {
//tree node values //tree node values
private static boolean showDataTab = false; //show all data names stored in the entity private static boolean showDataTab = false; //show all data names stored in the entity
private static boolean showActorTab = false; //show the actor tab private static boolean showActorTab = false; //show the actor tab
private static boolean showInstancedActorTab = false; //show the instanced actor tab
private static boolean showPoseActorTab = false; //show the pose actor tab private static boolean showPoseActorTab = false; //show the pose actor tab
private static boolean showEquipStateTab = false; //actor details private static boolean showEquipStateTab = false; //actor details
private static boolean showFirstPersonTab = false; //first person tab private static boolean showFirstPersonTab = false; //first person tab
@ -64,7 +65,7 @@ public class ImGuiEntityMacros {
/** /**
* Creates the windows in this file * Creates the windows in this file
*/ */
protected static void createClientEntityWindows(){ public static void createClientEntityWindows(){
createClientEntityDetailWindow(); createClientEntityDetailWindow();
createClientEntitySelectionWindow(); createClientEntitySelectionWindow();
} }
@ -79,14 +80,23 @@ public class ImGuiEntityMacros {
public void exec() { public void exec() {
//audio engine details //audio engine details
ImGui.text("Client Entities"); ImGui.text("Client Entities");
if(ImGui.checkbox("Filter Basic", filterBasic)){
filterBasic = !filterBasic;
}
if(ImGui.checkbox("Filter to Creatures", filterToCreatures)){ if(ImGui.checkbox("Filter to Creatures", filterToCreatures)){
filterToCreatures = !filterToCreatures; filterToCreatures = !filterToCreatures;
} }
if(ImGui.checkbox("Filter to Foliage", filterToFoliage)){
filterToFoliage = !filterToFoliage;
}
for(Entity entity : Globals.clientSceneWrapper.getScene().getEntityList()){ for(Entity entity : Globals.clientSceneWrapper.getScene().getEntityList()){
//filters //filters
if(filterToCreatures && !CreatureUtils.isCreature(entity)){ if(filterToCreatures && !CreatureUtils.isCreature(entity)){
continue; continue;
} }
if(filterToFoliage && !FoliageUtils.isFoliage(entity)){
continue;
}
ImGui.beginGroup(); ImGui.beginGroup();
ImGui.pushID(entity.getId()); ImGui.pushID(entity.getId());
ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")"); ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")");
@ -119,6 +129,9 @@ public class ImGuiEntityMacros {
if(EntityUtils.getActor(detailViewEntity) != null && ImGui.checkbox("Actor Details", showActorTab)){ if(EntityUtils.getActor(detailViewEntity) != null && ImGui.checkbox("Actor Details", showActorTab)){
showActorTab = !showActorTab; showActorTab = !showActorTab;
} }
if(InstancedActor.getInstancedActor(detailViewEntity) != null && ImGui.checkbox("Instanced Actor Details", showInstancedActorTab)){
showInstancedActorTab = !showInstancedActorTab;
}
if(EntityUtils.getPoseActor(detailViewEntity) != null && ImGui.checkbox("Pose Actor Details", showPoseActorTab)){ if(EntityUtils.getPoseActor(detailViewEntity) != null && ImGui.checkbox("Pose Actor Details", showPoseActorTab)){
showPoseActorTab = !showPoseActorTab; showPoseActorTab = !showPoseActorTab;
} }
@ -143,7 +156,8 @@ public class ImGuiEntityMacros {
ImGui.treePop(); ImGui.treePop();
} }
ImGui.nextColumn(); ImGui.nextColumn();
drawActorView(); ImGuiEntityActorTab.drawActorView(showActorTab,detailViewEntity);
ImGuiEntityInstancedActorTab.drawInstancedActorView(showInstancedActorTab, detailViewEntity);
drawPoseActor(); drawPoseActor();
drawEquipState(); drawEquipState();
drawFirstPersonView(); drawFirstPersonView();
@ -161,7 +175,7 @@ public class ImGuiEntityMacros {
* Shows the entity window for a specific entity * Shows the entity window for a specific entity
* @param entity The entity * @param entity The entity
*/ */
protected static void showEntity(Entity entity){ public static void showEntity(Entity entity){
detailViewEntity = entity; detailViewEntity = entity;
clientEntityDetailWindow.setOpen(true); clientEntityDetailWindow.setOpen(true);
} }
@ -179,98 +193,6 @@ public class ImGuiEntityMacros {
} }
} }
/**
* Client scene entity view
*/
protected static void drawActorView(){
if(showActorTab && ImGui.collapsingHeader("Actor Details")){
ImGui.indent();
if(detailViewEntity != null && EntityUtils.getActor(detailViewEntity) != null){
Actor actor = EntityUtils.getActor(detailViewEntity);
//mesh mask
if(ImGui.collapsingHeader("Mesh Mask")){
ActorMeshMask meshMask = actor.getMeshMask();
ImGui.text("To Draw Meshes:");
for(Mesh mesh : meshMask.getToDrawMeshes()){
ImGui.text(mesh.getMeshName());
}
ImGui.text("Blocked Meshes:");
for(String blocked : meshMask.getBlockedMeshes()){
ImGui.text(blocked);
}
}
//animation queue
if(ImGui.collapsingHeader("Animation Queue")){
Set<ActorAnimationMask> animationQueue = actor.getAnimationQueue();
for(ActorAnimationMask mask : animationQueue){
ImGui.text(mask.getAnimationName() + " - " + mask.getPriority());
ImGui.text(mask.getDuration() + " " + mask.getTime());
}
}
//bone values
if(ImGui.collapsingHeader("Bone Values")){
for(Bone bone : actor.getBoneValues()){
ImGui.text(bone.boneID);
ImGui.text("Position: " + actor.getBonePosition(bone.boneID));
ImGui.text("Rotation: " + actor.getBoneRotation(bone.boneID));
ImGui.text(bone.getFinalTransform() + "");
}
}
//Draws all the bones in the world
if(ImGui.button("Draw Bones")){
Globals.renderingEngine.getDebugContentPipeline().getDebugBonesPipeline().setEntity(detailViewEntity);
}
//Browsable list of all animations with their data
if(ImGui.collapsingHeader("Animation Channel Data")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
ImGui.indent();
for(Animation animation : model.getAnimations()){
if(ImGui.collapsingHeader(animation.name)){
if(ImGui.button("Play")){
actor.playAnimation(animation.name, AnimationPriorities.getValue(AnimationPriorities.MODIFIER_MAX));
}
for(AnimChannel channel : animation.channels){
ImGui.pushID(channel.getNodeID());
if(ImGui.button("Fully describe")){
channel.fullDescribeChannel();
}
ImGui.text("=" + channel.getNodeID() + "=");
ImGui.text("" + channel.getCurrentPosition());
ImGui.text("" + channel.getCurrentRotation());
ImGui.text("" + channel.getCurrentScale());
ImGui.popID();
}
}
}
ImGui.unindent();
}
//print data macros
if(ImGui.collapsingHeader("Print Data")){
//print bone values
if(ImGui.button("Print current bone values")){
for(Bone bone : actor.getBoneValues()){
LoggerInterface.loggerRenderer.DEBUG(bone.boneID);
LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform());
}
}
//print animation keys
if(ImGui.button("Print animation keys")){
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
model.describeAllAnimations();
}
}
}
ImGui.unindent();
}
}
/** /**
* Draws pose actor * Draws pose actor
*/ */

View File

@ -1,9 +1,12 @@
package electrosphere.entity; package electrosphere.entity;
import java.util.List;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
/** /**
@ -28,6 +31,16 @@ public class ClientEntityUtils {
* @param entity the entity to destroy * @param entity the entity to destroy
*/ */
public static void destroyEntity(Entity entity){ public static void destroyEntity(Entity entity){
//
//destroy the child entities, too
if(AttachUtils.hasChildren(entity)){
List<Entity> children = AttachUtils.getChildrenList(entity);
for(Entity child : children){
ClientEntityUtils.destroyEntity(child);
}
}
//check for client-specific stuff //check for client-specific stuff
Globals.renderingEngine.getLightManager().destroyPointLight(entity); Globals.renderingEngine.getLightManager().destroyPointLight(entity);

View File

@ -42,6 +42,7 @@ public class EntityDataStrings {
*/ */
public static final String ENTITY_TYPE = "entityType"; //ie "creature", "foliage", "terrain", etc public static final String ENTITY_TYPE = "entityType"; //ie "creature", "foliage", "terrain", etc
public static final String ENTITY_SUBTYPE = "entitySubtype"; //ie "human", "woodenCrate", etc public static final String ENTITY_SUBTYPE = "entitySubtype"; //ie "human", "woodenCrate", etc
public static final String COMMON_DATA = "commonData";
/* /*
Terrain Entity Terrain Entity

View File

@ -99,6 +99,7 @@ public class CommonEntityUtils {
//Set typing stuff //Set typing stuff
// //
CommonEntityUtils.setTyping(entity,rawType); CommonEntityUtils.setTyping(entity,rawType);
CommonEntityUtils.setCommonData(entity,rawType);
//tracks whether to generate a drawable or not //tracks whether to generate a drawable or not
boolean generateDrawable = true; boolean generateDrawable = true;
@ -392,6 +393,7 @@ public class CommonEntityUtils {
// //
CommonEntityUtils.setTyping(entity,rawType); CommonEntityUtils.setTyping(entity,rawType);
CommonEntityUtils.serverAttachToTag(entity,rawType); CommonEntityUtils.serverAttachToTag(entity,rawType);
CommonEntityUtils.setCommonData(entity,rawType);
//tracks whether to generate a drawable or not //tracks whether to generate a drawable or not
boolean generateDrawable = true; boolean generateDrawable = true;
@ -815,6 +817,24 @@ public class CommonEntityUtils {
entity.putData(EntityDataStrings.ENTITY_TYPE, type); entity.putData(EntityDataStrings.ENTITY_TYPE, type);
} }
/**
* Gets the common data on the entity
* @param entity The entity
* @return The common data
*/
public static CommonEntityType getCommonData(Entity entity){
return (CommonEntityType)entity.getData(EntityDataStrings.COMMON_DATA);
}
/**
* Sets the common data on the entity
* @param entity The entity
* @param data The common data
*/
public static void setCommonData(Entity entity, CommonEntityType data){
entity.putData(EntityDataStrings.COMMON_DATA, data);
}
/** /**
* Gets the subtype of this entity * Gets the subtype of this entity
* @param entity The entity * @param entity The entity

View File

@ -35,7 +35,7 @@ public class FoliageUtils {
public static Entity clientSpawnBasicFoliage(String type, long seed){ public static Entity clientSpawnBasicFoliage(String type, long seed){
FoliageType rawType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type); FoliageType rawType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type);
Entity rVal; Entity rVal;
if(rawType.getTreeModel()!=null){ if(rawType.getGraphicsTemplate().getProceduralModel().getTreeModel()!=null){
rVal = ProceduralTree.clientGenerateProceduralTree(type, 0); rVal = ProceduralTree.clientGenerateProceduralTree(type, 0);
} else { } else {
rVal = EntityCreationUtils.createClientSpatialEntity(); rVal = EntityCreationUtils.createClientSpatialEntity();
@ -52,6 +52,9 @@ public class FoliageUtils {
//Foliage specific transforms //Foliage specific transforms
// //
// //
rVal.putData(EntityDataStrings.FOLIAGE_TYPE, rawType);
rVal.putData(EntityDataStrings.FOLIAGE_SEED, seed);
rVal.putData(EntityDataStrings.FOLIAGE_IS_SEEDED, true);
//audio //audio
if(rawType.getAmbientAudio()!=null){ if(rawType.getAmbientAudio()!=null){
@ -74,7 +77,7 @@ public class FoliageUtils {
public static Entity serverSpawnTreeFoliage(Realm realm, Vector3d position, String type, long seed){ public static Entity serverSpawnTreeFoliage(Realm realm, Vector3d position, String type, long seed){
FoliageType rawType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type); FoliageType rawType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type);
Entity rVal; Entity rVal;
if(rawType.getTreeModel()!=null){ if(rawType.getGraphicsTemplate().getProceduralModel().getTreeModel()!=null){
rVal = ProceduralTree.serverGenerateProceduralTree(realm, position, rawType, seed); rVal = ProceduralTree.serverGenerateProceduralTree(realm, position, rawType, seed);
} else { } else {
rVal = EntityCreationUtils.createServerEntity(realm, position); rVal = EntityCreationUtils.createServerEntity(realm, position);

View File

@ -22,6 +22,7 @@ import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
@ -101,10 +102,22 @@ public class ProceduralTree {
//call recursive branching routine to generate branches from trunk + leaf blobs //call recursive branching routine to generate branches from trunk + leaf blobs
FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type); FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type);
TreeModel treeModel = foliageType.getTreeModel(); TreeModel treeModel = foliageType.getGraphicsTemplate().getProceduralModel().getTreeModel();
//generate trunk //generate trunk
Entity trunkChild = EntityCreationUtils.createClientSpatialEntity(); Entity trunkChild = EntityCreationUtils.createClientSpatialEntity();
setProceduralActor(trunkChild, treeModel, treeRandom);
return trunkChild;
}
/**
* Sets the procedural actor for the tree
* @param trunkChild The entity
* @param treeModel The tree model params
* @param treeRandom The random
*/
public static void setProceduralActor(Entity trunkChild, TreeModel treeModel, Random treeRandom){
InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(trunkChild, branchInstanceTemplate, modelMatrixAttribute); InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(trunkChild, branchInstanceTemplate, modelMatrixAttribute);
instancedActor.setAttribute(boneMatrixAttribute, new Matrix4f().identity()); instancedActor.setAttribute(boneMatrixAttribute, new Matrix4f().identity());
instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity());
@ -150,7 +163,7 @@ public class ProceduralTree {
true true
); );
return trunkChild; ClientEntityUtils.initiallyPositionEntity(trunkChild, EntityUtils.getPosition(trunkChild), EntityUtils.getRotation(trunkChild));
} }
private static List<Entity> clientGenerateBranchesAlt( private static List<Entity> clientGenerateBranchesAlt(
@ -371,7 +384,7 @@ public class ProceduralTree {
*/ */
public static Entity serverGenerateProceduralTree(Realm realm, Vector3d position, FoliageType foliageType, long seed){ public static Entity serverGenerateProceduralTree(Realm realm, Vector3d position, FoliageType foliageType, long seed){
//call recursive branching routine to generate branches from trunk + leaf blobs //call recursive branching routine to generate branches from trunk + leaf blobs
TreeModel treeModel = foliageType.getTreeModel(); TreeModel treeModel = foliageType.getGraphicsTemplate().getProceduralModel().getTreeModel();
//generate trunk //generate trunk
Entity trunkChild = EntityCreationUtils.createServerEntity(realm,position); Entity trunkChild = EntityCreationUtils.createServerEntity(realm,position);

View File

@ -18,7 +18,6 @@ import electrosphere.game.data.creature.type.movement.MovementSystem;
import electrosphere.game.data.creature.type.rotator.RotatorSystem; import electrosphere.game.data.creature.type.rotator.RotatorSystem;
import electrosphere.game.data.foliage.type.AmbientAudio; import electrosphere.game.data.foliage.type.AmbientAudio;
import electrosphere.game.data.foliage.type.GrowthModel; import electrosphere.game.data.foliage.type.GrowthModel;
import electrosphere.game.data.foliage.type.TreeModel;
import electrosphere.game.data.graphics.GraphicsTemplate; import electrosphere.game.data.graphics.GraphicsTemplate;
import electrosphere.game.data.particle.ParticleEmitter; import electrosphere.game.data.particle.ParticleEmitter;
@ -107,11 +106,6 @@ public class CommonEntityType {
*/ */
GrowthModel growthModel; GrowthModel growthModel;
/**
* The model for a tree
*/
TreeModel treeModel;
/** /**
* The ambient audio model * The ambient audio model
*/ */
@ -276,14 +270,6 @@ public class CommonEntityType {
return growthModel; return growthModel;
} }
/**
* Gets the tree model
* @return The tree model
*/
public TreeModel getTreeModel(){
return treeModel;
}
/** /**
* Gets the ambient audio model * Gets the ambient audio model
* @return The ambient audio model * @return The ambient audio model

View File

@ -96,7 +96,7 @@ public class TreeModel {
//The minimum scalar of a branch to generate a sway behavior tree //The minimum scalar of a branch to generate a sway behavior tree
float minimumScalarToGenerateSwayTree; float minimumScalarToGenerateSwayTree;
//The maximum scalar of a branch to generate a sway behavior tree //The maximum scalar of a branch to generate a sway behavior tree*
float maximumScalarToGenerateSwayTree; float maximumScalarToGenerateSwayTree;
//The model for the trunk of the tree //The model for the trunk of the tree
@ -354,4 +354,130 @@ public class TreeModel {
return leafModelPath; return leafModelPath;
} }
public void setLimbScalarFalloffFactor(float limbScalarFalloffFactor) {
this.limbScalarFalloffFactor = limbScalarFalloffFactor;
}
public void setMinimumLimbScalar(float minimumLimbScalar) {
this.minimumLimbScalar = minimumLimbScalar;
}
public void setMaximumLimbDispersion(float maximumLimbDispersion) {
this.maximumLimbDispersion = maximumLimbDispersion;
}
public void setMinimumLimbDispersion(float minimumLimbDispersion) {
this.minimumLimbDispersion = minimumLimbDispersion;
}
public void setMinimumNumberForks(int minimumNumberForks) {
this.minimumNumberForks = minimumNumberForks;
}
public void setMaximumNumberForks(int maximumNumberForks) {
this.maximumNumberForks = maximumNumberForks;
}
public void setBranchHeight(float branchHeight) {
this.branchHeight = branchHeight;
}
public void setCentralTrunk(boolean centralTrunk) {
this.centralTrunk = centralTrunk;
}
public void setMaximumTrunkSegments(int maximumTrunkSegments) {
this.maximumTrunkSegments = maximumTrunkSegments;
}
public void setMaximumBranchSegments(int maximumBranchSegments) {
this.maximumBranchSegments = maximumBranchSegments;
}
public void setMaxBranchSegmentFalloffFactor(float maxBranchSegmentFalloffFactor) {
this.maxBranchSegmentFalloffFactor = maxBranchSegmentFalloffFactor;
}
public void setMinimumSegmentToSpawnLeaves(int minimumSegmentToSpawnLeaves) {
this.minimumSegmentToSpawnLeaves = minimumSegmentToSpawnLeaves;
}
public void setMinBranchHeightToStartSpawningLeaves(float minBranchHeightToStartSpawningLeaves) {
this.minBranchHeightToStartSpawningLeaves = minBranchHeightToStartSpawningLeaves;
}
public void setMaxBranchHeightToStartSpawningLeaves(float maxBranchHeightToStartSpawningLeaves) {
this.maxBranchHeightToStartSpawningLeaves = maxBranchHeightToStartSpawningLeaves;
}
public void setLeafIncrement(float leafIncrement) {
this.leafIncrement = leafIncrement;
}
public void setMinLeavesToSpawnPerPoint(int minLeavesToSpawnPerPoint) {
this.minLeavesToSpawnPerPoint = minLeavesToSpawnPerPoint;
}
public void setMaxLeavesToSpawnPerPoint(int maxLeavesToSpawnPerPoint) {
this.maxLeavesToSpawnPerPoint = maxLeavesToSpawnPerPoint;
}
public void setLeafDistanceFromCenter(float leafDistanceFromCenter) {
this.leafDistanceFromCenter = leafDistanceFromCenter;
}
public void setPhysicsCutoff(int physicsCutoff) {
this.physicsCutoff = physicsCutoff;
}
public void setPhysicsBody(CollidableTemplate physicsBody) {
this.physicsBody = physicsBody;
}
public void setPeelVariance(double peelVariance) {
this.peelVariance = peelVariance;
}
public void setPeelMinimum(double peelMinimum) {
this.peelMinimum = peelMinimum;
}
public void setSwaySigmoidFactor(double swaySigmoidFactor) {
this.swaySigmoidFactor = swaySigmoidFactor;
}
public void setMinimumSwayTime(int minimumSwayTime) {
this.minimumSwayTime = minimumSwayTime;
}
public void setSwayTimeVariance(int swayTimeVariance) {
this.swayTimeVariance = swayTimeVariance;
}
public void setYawVariance(double yawVariance) {
this.yawVariance = yawVariance;
}
public void setYawMinimum(double yawMinimum) {
this.yawMinimum = yawMinimum;
}
public void setMinimumScalarToGenerateSwayTree(float minimumScalarToGenerateSwayTree) {
this.minimumScalarToGenerateSwayTree = minimumScalarToGenerateSwayTree;
}
public void setMaximumScalarToGenerateSwayTree(float maximumScalarToGenerateSwayTree) {
this.maximumScalarToGenerateSwayTree = maximumScalarToGenerateSwayTree;
}
public void setTrunkModelPath(String trunkModelPath) {
this.trunkModelPath = trunkModelPath;
}
public void setLeafModelPath(String leafModelPath) {
this.leafModelPath = leafModelPath;
}
} }