Zepha Voxel Modeller
parent
7e731cb6e9
commit
9100a853e6
|
@ -0,0 +1,2 @@
|
||||||
|
lib
|
||||||
|
.idea
|
|
@ -0,0 +1,5 @@
|
||||||
|
(c) 2018-2019 Nicole Collings, All rights reserved.
|
||||||
|
|
||||||
|
You do not have permission to redistribute, copy, or share this work without my explicit written permission.
|
||||||
|
You may download the repository and compile it for personal use or potential contributions.
|
||||||
|
Please contact me if you have any questions or special requests.
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Zepha Voxel Game
|
||||||
|
|
||||||
|
[![Codacy Rating](https://img.shields.io/codacy/grade/666016450e2645f7a88a2baea1a9f7fd.svg?logo=codacy)](https://app.codacy.com/app/Aurailus/Zepha?utm_source=github.com&utm_medium=referral&utm_content=Aurailus/Zeus_cpp&utm_campaign=Badge_Grade_Settings)
|
||||||
|
[![Discord Badge](https://img.shields.io/discord/416379773976051712.svg?color=7289DA&label=discord&logo=discord&logoColor=white)](https://auri.xyz/discord.php)
|
||||||
|
[![GitHub Commit](https://img.shields.io/github/commit-activity/m/aurailus/zepha.svg?logo=github&label=commit%20activity)](https://github.com/Aurailus/Zepha/commits/master)
|
||||||
|
|
||||||
|
### About
|
||||||
|
|
||||||
|
Zepha is a powerful, extensible C++ Voxel Game with immense modding possibilities. The API provided allows everybody with even a basic knowledge of Lua to create any subgame imaginable. Though other Voxel Games like Zepha exist, none of them can match it's superior performance, graphical capabilities, and raw modding capability.
|
||||||
|
|
||||||
|
Zepha is very early in developement, however it already has several strengths over alternative games / engines. Infinite-sized worlds, client side scripting, a well-designed game selection menu, and more. For those interested in trying out the modding API, a seperate repository containing the documentation for the game is available [here](https://github.com/Aurailus/Zepha-docs).
|
||||||
|
|
||||||
|
Zepha's full source code is currently available on this repository for viewing and personal use, however it is important to note that this project is *not* free nor open source. Unfortunately, as my dream is to make a living off of game development this is not a viable strategy for me. Learning from the source code or exploring the source is allowed and encouraged, though. Feel free to use this repository as a reference for similar works until the repository eventually becomes private.
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
**(c) 2018-2020 Nicole Collings, All Rights Reserved.**
|
||||||
|
|
||||||
|
You do not have permission to redistribute, copy, or share this work without my explicit written permission.
|
||||||
|
You may download the repository and compile it for personal use or potential contributions.
|
||||||
|
Please contact me if you have any questions or special requests.
|
|
@ -0,0 +1,33 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec4 colorData;
|
||||||
|
in vec3 colorBlend;
|
||||||
|
in float normalShading;
|
||||||
|
in float useTex;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform vec4 uClipBounds;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Overflow clipping
|
||||||
|
if (uClipBounds.z != 0 && uClipBounds.w != 0
|
||||||
|
&&(gl_FragCoord.x < uClipBounds.x || gl_FragCoord.y < uClipBounds.y
|
||||||
|
|| gl_FragCoord.x > uClipBounds.z || gl_FragCoord.y > uClipBounds.w)) discard;
|
||||||
|
|
||||||
|
vec4 color = vec4(1, 1, 1, 1);
|
||||||
|
|
||||||
|
if (useTex > 0.5) {
|
||||||
|
vec4 spec = texture(tex, colorData.xy) * vec4(colorBlend, colorData.w);
|
||||||
|
if (spec.a <= 0) discard;
|
||||||
|
color = spec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (colorData.a <= 0) discard;
|
||||||
|
color = colorData * vec4(colorBlend, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
color *= vec4(vec3(normalShading), 1);
|
||||||
|
fragColor = color;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec4 aColorData;
|
||||||
|
layout (location = 2) in vec3 aColorBlend;
|
||||||
|
layout (location = 3) in float aUseTex;
|
||||||
|
layout (location = 4) in vec3 aNormal;
|
||||||
|
layout (location = 5) in ivec4 aBoneIDs;
|
||||||
|
layout (location = 6) in vec4 aBoneWeights;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 ortho;
|
||||||
|
|
||||||
|
const int MAX_BONES = 100;
|
||||||
|
uniform mat4 uBones[MAX_BONES];
|
||||||
|
|
||||||
|
out vec4 colorData;
|
||||||
|
out vec3 colorBlend;
|
||||||
|
out float normalShading;
|
||||||
|
out float useTex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 boneTransform = uBones[aBoneIDs[0]] * aBoneWeights[0];
|
||||||
|
boneTransform += uBones[aBoneIDs[1]] * aBoneWeights[1];
|
||||||
|
boneTransform += uBones[aBoneIDs[2]] * aBoneWeights[2];
|
||||||
|
boneTransform += uBones[aBoneIDs[3]] * aBoneWeights[3];
|
||||||
|
|
||||||
|
float totalWeight = aBoneWeights[0] + aBoneWeights[1] + aBoneWeights[2] + aBoneWeights[3];
|
||||||
|
|
||||||
|
boneTransform = (boneTransform * totalWeight) + (mat4(1.0) * (1 - totalWeight));
|
||||||
|
|
||||||
|
if (aNormal == vec3(0, 0, 0)) normalShading = 1;
|
||||||
|
else {
|
||||||
|
vec3 normal = normalize(transpose(inverse(mat3(model))) * (boneTransform * vec4(normalize(aNormal), 0.0)).xyz);
|
||||||
|
normalShading = 1 + (normal.x * -normal.z * 0.15) - (normal.y * 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = ortho * model * boneTransform * vec4(aPos, 1);
|
||||||
|
colorData = aColorData;
|
||||||
|
colorBlend = aColorBlend;
|
||||||
|
useTex = aUseTex;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
#define NEAR_FOG vec3(0.40, 0.56, 0.72)
|
||||||
|
#define FAR_FOG vec3(0.58, 0.76, 0.94)
|
||||||
|
|
||||||
|
out vec4 outColor;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
//uniform sampler2D gPosition;
|
||||||
|
uniform sampler2D gNormal;
|
||||||
|
uniform sampler2D gColorSpec;
|
||||||
|
uniform sampler2D ssaoSampler;
|
||||||
|
|
||||||
|
uniform vec3 camPosition;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 normal = texture(gNormal, texCoords).rgb;
|
||||||
|
vec3 color = texture(gColorSpec, texCoords).rgb;
|
||||||
|
float ssao = texture(ssaoSampler, texCoords).r;
|
||||||
|
|
||||||
|
//Shade based on Normals
|
||||||
|
float shading = (0.8 + abs(normal.x) * 0.15) + (normal.y * 0.15) + 0.2;
|
||||||
|
color *= vec3(shading);
|
||||||
|
|
||||||
|
vec3 lighting = color;
|
||||||
|
|
||||||
|
//Apply Lighting
|
||||||
|
// lighting *= 0.1;
|
||||||
|
//
|
||||||
|
// float radius = 16;
|
||||||
|
//
|
||||||
|
// float lightDist = length(camPosition - fragPos);
|
||||||
|
// if (lightDist < radius) {
|
||||||
|
// vec3 lightDir = normalize(camPosition - fragPos);
|
||||||
|
// vec3 diffuse = max(dot(normal, lightDir) * 0.6 + 0.4, 0.0) * color * vec3(1, 1, 1);
|
||||||
|
// diffuse *= 1 - min(lightDist / radius, 1);
|
||||||
|
// lighting += diffuse;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//Apply fog color based on distance from camera
|
||||||
|
// float dist = distance(vec3(0, 0, 0), vec3(fragPos));
|
||||||
|
// float nearFog = min(max(dist - 200, 0) / 100, 1);
|
||||||
|
// float farFog = min(max(dist - 250, 0) / 100, 1);
|
||||||
|
|
||||||
|
// color = mix(mix(vec3(lighting), NEAR_FOG, nearFog), FAR_FOG, farFog);
|
||||||
|
color = lighting * ssao;
|
||||||
|
|
||||||
|
outColor = vec4(color, 1);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
//Just translate the coordinates directly into screen space.
|
||||||
|
//For rendering the data onto a quad.
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoords;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texCoords = aTexCoords;
|
||||||
|
gl_Position = vec4(aPos, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#version 440 core
|
||||||
|
|
||||||
|
#define RAD 2
|
||||||
|
#define DIVIDEBY ((RAD * 2) * (RAD * 2))
|
||||||
|
|
||||||
|
out float outColor;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D ssaoInput;
|
||||||
|
|
||||||
|
uniform float sampleScale;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 texelSize = 1.0 / vec2(textureSize(ssaoInput, 0));
|
||||||
|
|
||||||
|
float result = 0.0;
|
||||||
|
for (int x = -RAD; x < RAD; x++) {
|
||||||
|
for (int y = -RAD; y < RAD; y++) {
|
||||||
|
vec2 offset = vec2(float(x), float(y)) * texelSize;
|
||||||
|
result += texture(ssaoInput, (texCoords * sampleScale) + offset).r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outColor = result / DIVIDEBY;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#version 440 core
|
||||||
|
|
||||||
|
#define RADIUS 1.0
|
||||||
|
#define RANGE 0.50
|
||||||
|
#define BIAS 0.08
|
||||||
|
|
||||||
|
out float outColor;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D gPosition;
|
||||||
|
layout (binding = 1) uniform sampler2D gNormal;
|
||||||
|
layout (binding = 2) uniform sampler2D texNoise;
|
||||||
|
|
||||||
|
uniform uint kernels;
|
||||||
|
uniform vec3 samples[64]; //Must be a constant, setting to 64 because it's unlikely to go higher
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
uniform float sampleScale;
|
||||||
|
|
||||||
|
const vec2 noiseScale = vec2(1920.0/4.0, 1004.0/4.0);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 fragPos = vec3(vec4(texture(gPosition, texCoords * sampleScale).xyz, 1.0f));
|
||||||
|
vec3 normal = normalize(mat3(view) * texture(gNormal, texCoords * sampleScale).xyz);
|
||||||
|
vec3 randomVec = normalize(texture(texNoise, texCoords * sampleScale * noiseScale).xyz);
|
||||||
|
|
||||||
|
if (normal == vec3(0)) discard;
|
||||||
|
|
||||||
|
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
||||||
|
vec3 bitangent = cross(normal, tangent);
|
||||||
|
mat3 tbn = mat3(tangent, bitangent, normal);
|
||||||
|
|
||||||
|
vec4 fragSample = vec4(fragPos, 1.0);
|
||||||
|
fragSample = projection * fragSample;
|
||||||
|
fragSample.xyz /= fragSample.w;
|
||||||
|
fragSample.xyz = fragSample.xyz * 0.5 + 0.5;
|
||||||
|
|
||||||
|
float fragDepth = vec3(texture(gPosition, fragSample.xy)).z;
|
||||||
|
|
||||||
|
float occlusion = 0.0;
|
||||||
|
for (int i = 0; i < kernels; ++i) {
|
||||||
|
vec3 smpl = tbn * samples[i]; // From tangent to view-space
|
||||||
|
smpl = fragPos + smpl * RADIUS;
|
||||||
|
|
||||||
|
vec4 offset = vec4(smpl, 1.0);
|
||||||
|
offset = projection * offset;
|
||||||
|
offset.xyz /= offset.w;
|
||||||
|
offset.xyz = offset.xyz * 0.5 + 0.5;
|
||||||
|
|
||||||
|
float sampleDepth = vec3(texture(gPosition, offset.xy)).z;
|
||||||
|
|
||||||
|
float rangeCheck = smoothstep(0.0, 1.0, RANGE / abs(fragDepth - sampleDepth));
|
||||||
|
occlusion += (sampleDepth >= fragDepth + BIAS ? 1.0 : 0.0) * rangeCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
outColor = 1.0 - (occlusion / kernels / 2);
|
||||||
|
}
|
|
@ -15,6 +15,8 @@ void main() {
|
||||||
if (spec.a < 0.1) discard;
|
if (spec.a < 0.1) discard;
|
||||||
vec3 color = spec.xyz;
|
vec3 color = spec.xyz;
|
||||||
|
|
||||||
|
if (!gl_FrontFacing) color *= vec3(1, 0, 0);
|
||||||
|
|
||||||
if (highlight) {
|
if (highlight) {
|
||||||
color *= 1.25;
|
color *= 1.25;
|
||||||
color += 0.05;
|
color += 0.05;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 gPosition;
|
||||||
|
layout (location = 1) out vec4 gNormal;
|
||||||
|
layout (location = 2) out vec4 gSpecular;
|
||||||
|
|
||||||
|
in vec3 fragPos;
|
||||||
|
in vec4 colorData;
|
||||||
|
in vec3 colorBlend;
|
||||||
|
in float useTex;
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (useTex > 0.5) {
|
||||||
|
vec4 spec = texture(tex, colorData.xy) * vec4(colorBlend, colorData.w);
|
||||||
|
if (spec.a < 0.1) discard;
|
||||||
|
gSpecular = spec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (colorData.a < 0.1) discard;
|
||||||
|
gSpecular = colorData * vec4(colorBlend, 1);
|
||||||
|
}
|
||||||
|
gPosition = vec4(fragPos, 1);
|
||||||
|
gNormal = vec4(normalize(normal), 1);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec4 aColorData;
|
||||||
|
layout (location = 2) in vec3 aColorBlend;
|
||||||
|
layout (location = 3) in float aUseTex;
|
||||||
|
layout (location = 4) in vec3 aNormal;
|
||||||
|
layout (location = 5) in ivec4 aBoneIDs;
|
||||||
|
layout (location = 6) in vec4 aBoneWeights;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
const int MAX_BONES = 100;
|
||||||
|
uniform mat4 uBones[MAX_BONES];
|
||||||
|
|
||||||
|
out vec3 fragPos;
|
||||||
|
out vec4 colorData;
|
||||||
|
out vec3 colorBlend;
|
||||||
|
out float useTex;
|
||||||
|
out vec3 normal;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 boneTransform = uBones[aBoneIDs[0]] * aBoneWeights[0];
|
||||||
|
boneTransform += uBones[aBoneIDs[1]] * aBoneWeights[1];
|
||||||
|
boneTransform += uBones[aBoneIDs[2]] * aBoneWeights[2];
|
||||||
|
boneTransform += uBones[aBoneIDs[3]] * aBoneWeights[3];
|
||||||
|
|
||||||
|
float totalWeight = aBoneWeights[0] + aBoneWeights[1] + aBoneWeights[2] + aBoneWeights[3];
|
||||||
|
|
||||||
|
boneTransform = (boneTransform * totalWeight) + (mat4(1.0) * (1 - totalWeight));
|
||||||
|
|
||||||
|
vec4 worldPos = model * boneTransform * vec4(aPos, 1.0);
|
||||||
|
normal = transpose(inverse(mat3(model))) * (boneTransform * vec4(normalize(aNormal), 0.0)).xyz;
|
||||||
|
|
||||||
|
fragPos = (view * worldPos).xyz;
|
||||||
|
colorData = aColorData;
|
||||||
|
colorBlend = aColorBlend;
|
||||||
|
useTex = aUseTex;
|
||||||
|
|
||||||
|
gl_Position = projection * view * worldPos;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 gPosition;
|
||||||
|
layout (location = 1) out vec4 gNormal;
|
||||||
|
layout (location = 2) out vec4 gSpecular;
|
||||||
|
|
||||||
|
in vec2 texCoords;
|
||||||
|
in vec2 blendMaskCoords;
|
||||||
|
in vec3 blend;
|
||||||
|
in vec3 fragPos;
|
||||||
|
in vec3 normal;
|
||||||
|
in vec3 light;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float blendMaskMult = -1;
|
||||||
|
|
||||||
|
if (blendMaskCoords.x >= 0 && blendMaskCoords.y >= 0) blendMaskMult = texture(tex, blendMaskCoords).r;
|
||||||
|
|
||||||
|
vec4 spec = texture(tex, texCoords);
|
||||||
|
vec3 blendCol = blend;
|
||||||
|
if (blendMaskMult >= 0) {
|
||||||
|
blendCol = (vec3(1, 1, 1) * (1 - blendMaskMult)) + (blendCol * blendMaskMult);
|
||||||
|
}
|
||||||
|
|
||||||
|
spec = vec4(spec.xyz * blendCol * light, spec.a);
|
||||||
|
|
||||||
|
if (spec.a < 0.1) discard;
|
||||||
|
|
||||||
|
gSpecular = spec;
|
||||||
|
gPosition = vec4(fragPos, 1);
|
||||||
|
gNormal = vec4(normal, 1);
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
#define TAU 6.28318530718
|
||||||
|
#define MAX_BLOCKLIGHT 31
|
||||||
|
#define MAX_SUNLIGHT 15
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoords;
|
||||||
|
layout (location = 2) in vec3 aBlend;
|
||||||
|
layout (location = 3) in vec2 aBlendMaskCoords;
|
||||||
|
layout (location = 4) in float aNormal;
|
||||||
|
layout (location = 5) in vec4 aLight;
|
||||||
|
layout (location = 6) in float aShaderMod;
|
||||||
|
layout (location = 7) in vec3 aModValues;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
uniform sampler2D swayTex;
|
||||||
|
uniform float time;
|
||||||
|
|
||||||
|
out vec2 texCoords;
|
||||||
|
out vec2 blendMaskCoords;
|
||||||
|
out vec3 blend;
|
||||||
|
out vec3 fragPos;
|
||||||
|
out vec3 normal;
|
||||||
|
out vec3 light;
|
||||||
|
|
||||||
|
vec3 unpackFloat(float src) {
|
||||||
|
return vec3(fract(src) * 2.0f - 1.0f, fract(src * 256.f) * 2.0f - 1.0f, fract(src * 65536.f) * 2.0f - 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 rotateX(vec4 vertex, vec4 offset, float radians) {
|
||||||
|
vertex -= offset;
|
||||||
|
mat2 m = mat2(cos(radians), -sin(radians), sin(radians), cos(radians));
|
||||||
|
return vec4(m * vertex.zy, vertex.xw).zyxw + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 rotateY(vec4 vertex, vec4 offset, float radians) {
|
||||||
|
vertex -= offset;
|
||||||
|
mat2 m = mat2(cos(radians), -sin(radians), sin(radians), cos(radians));
|
||||||
|
return vec4(m * vertex.xz, vertex.yw).xzyw + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 rotateZ(vec4 vertex, vec4 offset, float radians) {
|
||||||
|
vertex -= offset;
|
||||||
|
mat2 m = mat2(cos(radians), -sin(radians), sin(radians), cos(radians));
|
||||||
|
return vec4(m * vertex.xy, vertex.zw).xyzw + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 pos = vec4(aPos, 1);
|
||||||
|
vec4 nml = vec4(unpackFloat(aNormal), 1);
|
||||||
|
|
||||||
|
switch (int(aShaderMod)) {
|
||||||
|
default: break;
|
||||||
|
case 1: { // Rotate X
|
||||||
|
vec4 origin = vec4(round(unpackFloat(aModValues.x) * 8 + 8) + 0.5, 1);
|
||||||
|
pos = rotateX(pos, origin, time * TAU * aModValues.y);
|
||||||
|
nml = rotateX(nml, vec4(0), time * TAU * aModValues.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: { // Rotate Y
|
||||||
|
vec4 origin = vec4(round(unpackFloat(aModValues.x) * 8 + 8) + 0.5, 1);
|
||||||
|
pos = rotateY(pos, origin, time * TAU * aModValues.y);
|
||||||
|
nml = rotateY(nml, vec4(0), time * TAU * aModValues.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: { // Rotate Z
|
||||||
|
vec4 origin = vec4(round(unpackFloat(aModValues.x) * 8 + 8) + 0.5, 1);
|
||||||
|
pos = rotateZ(pos, origin, time * TAU * aModValues.y);
|
||||||
|
nml = rotateZ(nml, vec4(0), time * TAU * aModValues.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: { //Sway Grounded
|
||||||
|
vec4 origin = vec4(round(unpackFloat(aModValues.x) * 8 + 8), 1);
|
||||||
|
vec3 bsp = vec3(pos - origin);
|
||||||
|
vec3 worldPos = (model * pos).xyz;
|
||||||
|
if (bsp.x*bsp.y*bsp.z != 0 && bsp.x*bsp.y*bsp.z != 1) {
|
||||||
|
vec3 sway = (texture(swayTex, worldPos.xz * (worldPos.y / 16.f) / 16.f).xyz - .5f) * vec3(aModValues.y, aModValues.y / 2, aModValues.y);
|
||||||
|
pos += vec4(sway, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: { //Sway Full Block
|
||||||
|
vec3 worldPos = (model * pos).xyz;
|
||||||
|
vec3 sway = (texture(swayTex, worldPos.xz * (worldPos.y / 16.f) / 16.f).xyz - .5f) * vec3(aModValues.y, aModValues.y / 2, aModValues.y);
|
||||||
|
pos += vec4(sway, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float sunlightIntensity = 1;
|
||||||
|
// float sunlightIntensity = aLight.w * clamp(sin(time / 2.5) + 0.25, 0, 1) / MAX_SUNLIGHT;
|
||||||
|
vec3 blockLightColor = (aLight.xyz / MAX_BLOCKLIGHT) * vec3(1 + sunlightIntensity / 4);
|
||||||
|
vec3 sunlightColor = clamp(sunlightIntensity * 1.25 * vec3(1, 1, 1) * (aLight.w / 15.0), 0, 1);
|
||||||
|
vec3 resultantLight = vec3(max(sunlightColor.x, blockLightColor.x), max(sunlightColor.y, blockLightColor.y), max(sunlightColor.z, blockLightColor.z));
|
||||||
|
|
||||||
|
vec4 worldPos = model * pos;
|
||||||
|
// worldPos.y -= pow(length(view * worldPos * 0.125) - 0.125, 2);
|
||||||
|
worldPos.y -= pow(length(view * worldPos * 0.025) - 0, 2);
|
||||||
|
|
||||||
|
fragPos = (view * worldPos).xyz;
|
||||||
|
texCoords = aTexCoords;
|
||||||
|
blendMaskCoords = aBlendMaskCoords;
|
||||||
|
blend = aBlend;
|
||||||
|
normal = nml.xyz;
|
||||||
|
light = resultantLight;
|
||||||
|
gl_Position = projection * view * worldPos;
|
||||||
|
}
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
@ -8,10 +8,11 @@ App::App() :
|
||||||
window(),
|
window(),
|
||||||
camera(&window),
|
camera(&window),
|
||||||
renderer(&window, &camera),
|
renderer(&window, &camera),
|
||||||
input(window.getInput()),
|
|
||||||
|
|
||||||
controller(input, camera),
|
blockManager(&camera, &window),
|
||||||
blockManager(&camera, &window) {
|
|
||||||
|
input(window.getInput()),
|
||||||
|
controller(input, window, camera, blockManager) {
|
||||||
|
|
||||||
while (!window.shouldEnd()) {
|
while (!window.shouldEnd()) {
|
||||||
update();
|
update();
|
||||||
|
@ -22,7 +23,6 @@ App::App() :
|
||||||
void App::update() {
|
void App::update() {
|
||||||
window.update();
|
window.update();
|
||||||
controller.update();
|
controller.update();
|
||||||
blockManager.update(input, controller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::render() {
|
void App::render() {
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include "graph/Camera.h"
|
#include "graph/Camera.h"
|
||||||
#include "graph/Renderer.h"
|
#include "graph/Renderer.h"
|
||||||
|
|
||||||
#include "input/ViewportControl.h"
|
|
||||||
#include "model/BlockModelManager.h"
|
#include "model/BlockModelManager.h"
|
||||||
|
#include "input/Controller.h"
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
public:
|
public:
|
||||||
|
@ -22,8 +22,9 @@ private:
|
||||||
Window window;
|
Window window;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
Input& input;
|
|
||||||
|
|
||||||
ViewportControl controller;
|
|
||||||
BlockModelManager blockManager;
|
BlockModelManager blockManager;
|
||||||
|
|
||||||
|
Input& input;
|
||||||
|
Controller controller;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
set(MODELLER_SRC
|
set(MODELLER_SRC
|
||||||
graph/Renderer.cpp graph/Renderer.h App.cpp App.h graph/Window.cpp graph/Window.h graph/Shader.cpp graph/Shader.h graph/Camera.h graph/Camera.cpp graph/Mesh.h graph/Vertex.h graph/Texture.h graph/Texture.cpp input/ViewportControl.cpp input/ViewportControl.h input/Input.cpp input/Input.h model/BlockModelManager.cpp model/BlockModelManager.h model/BlockModelInstance.cpp model/BlockModelInstance.h model/BlockFace.cpp model/BlockFace.h model/BlockModel.cpp model/BlockModel.h model/EditingBlockModel.cpp model/EditingBlockModel.h input/Ray.h)
|
graph/Renderer.cpp graph/Renderer.h App.cpp App.h graph/Window.cpp graph/Window.h graph/Shader.cpp graph/Shader.h graph/Camera.h graph/Camera.cpp graph/Mesh.h graph/Vertex.h graph/Texture.h graph/Texture.cpp input/ViewportController.cpp input/ViewportController.h input/Input.cpp input/Input.h model/BlockModelManager.cpp model/BlockModelManager.h model/BlockModelInstance.cpp model/BlockModelInstance.h model/BlockFace.cpp model/BlockFace.h model/BlockModel.cpp model/BlockModel.h model/EditingBlockModel.cpp model/EditingBlockModel.h util/Ray.h input/Controller.cpp input/Controller.h)
|
||||||
add_library(${MAIN_LIB_NAME} ${MODELLER_SRC})
|
add_library(${MAIN_LIB_NAME} ${MODELLER_SRC})
|
|
@ -36,7 +36,7 @@ void Renderer::setClearColor(glm::vec4 color) {
|
||||||
void Renderer::reset() {
|
void Renderer::reset() {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
// glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-05.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "Controller.h"
|
||||||
|
|
||||||
|
#include "Input.h"
|
||||||
|
#include "../model/BlockModelManager.h"
|
||||||
|
#include "../util/Ray.h"
|
||||||
|
|
||||||
|
Controller::Controller(Input& input, Window& window, Camera& camera, BlockModelManager& blockManager) :
|
||||||
|
input(input),
|
||||||
|
window(window),
|
||||||
|
camera(camera),
|
||||||
|
viewport(input, camera),
|
||||||
|
blockManager(blockManager) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::update() {
|
||||||
|
viewport.update();
|
||||||
|
|
||||||
|
if (!blockManager.getEditingModel()) modelSelect();
|
||||||
|
else modelEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::modelSelect() {
|
||||||
|
glm::vec3 dir = Ray::worldRayFromCursor(window, camera);
|
||||||
|
glm::vec3 ray = camera.getPos();
|
||||||
|
|
||||||
|
float dis = 0.05f;
|
||||||
|
while (dis < 20) {
|
||||||
|
glm::vec3 end = ray + (dir * dis);
|
||||||
|
glm::ivec3 pos = glm::floor(end + glm::vec3(0.5));
|
||||||
|
|
||||||
|
if (blockManager.highlightInstanceAtPos(pos)) {
|
||||||
|
if (input.keyPressed(GLFW_MOUSE_BUTTON_LEFT)) {
|
||||||
|
blockManager.setEditingInstance(pos);
|
||||||
|
viewport.setViewFocus(pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dis += 0.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::modelEdit() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-05.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ViewportController.h"
|
||||||
|
|
||||||
|
class Input;
|
||||||
|
class Camera;
|
||||||
|
class Window;
|
||||||
|
class BlockModelManager;
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
public:
|
||||||
|
Controller(Input& input, Window& window, Camera& camera, BlockModelManager& blockManager);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void modelSelect();
|
||||||
|
void modelEdit();
|
||||||
|
|
||||||
|
ViewportController viewport;
|
||||||
|
|
||||||
|
Input& input;
|
||||||
|
Window& window;
|
||||||
|
Camera& camera;
|
||||||
|
BlockModelManager& blockManager;
|
||||||
|
};
|
|
@ -8,19 +8,19 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "ViewportControl.h"
|
#include "ViewportController.h"
|
||||||
|
|
||||||
#include "../graph/Camera.h"
|
#include "../graph/Camera.h"
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
|
|
||||||
ViewportControl::ViewportControl(Input &input, Camera &camera) :
|
ViewportController::ViewportController(Input &input, Camera &camera) :
|
||||||
input(input),
|
input(input),
|
||||||
camera(camera) {
|
camera(camera) {
|
||||||
|
|
||||||
this->cb = input.addScrollCallback([&](int delta) { distance = fmin(fmax(distance - delta * (distance / 6), 1.1), 20); });
|
this->cb = input.addScrollCallback([&](int delta) { distance = fmin(fmax(distance - delta * (distance / 6), 1.1), 20); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewportControl::update() {
|
void ViewportController::update() {
|
||||||
if (input.keyDown(GLFW_MOUSE_BUTTON_MIDDLE)) {
|
if (input.keyDown(GLFW_MOUSE_BUTTON_MIDDLE)) {
|
||||||
input.setMouseLocked(true);
|
input.setMouseLocked(true);
|
||||||
yaw += -input.mouseDelta().x * panFactor;
|
yaw += -input.mouseDelta().x * panFactor;
|
||||||
|
@ -29,6 +29,15 @@ void ViewportControl::update() {
|
||||||
}
|
}
|
||||||
else input.setMouseLocked(false);
|
else input.setMouseLocked(false);
|
||||||
|
|
||||||
|
if (input.keyDown(GLFW_KEY_RIGHT))
|
||||||
|
yaw += arrowFactor;
|
||||||
|
if (input.keyDown(GLFW_KEY_LEFT))
|
||||||
|
yaw -= arrowFactor;
|
||||||
|
if (input.keyDown(GLFW_KEY_UP))
|
||||||
|
pitch = fmin(fmax(pitch - arrowFactor, -1.55), 1.55);
|
||||||
|
if (input.keyDown(GLFW_KEY_DOWN))
|
||||||
|
pitch = fmin(fmax(pitch + arrowFactor, -1.55), 1.55);
|
||||||
|
|
||||||
glm::vec3 camPos = {
|
glm::vec3 camPos = {
|
||||||
distance * -sinf(yaw) * cosf(pitch),
|
distance * -sinf(yaw) * cosf(pitch),
|
||||||
distance * -sinf(pitch),
|
distance * -sinf(pitch),
|
||||||
|
@ -51,6 +60,6 @@ void ViewportControl::update() {
|
||||||
camera.setYaw(lookYaw);
|
camera.setYaw(lookYaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewportControl::setViewFocus(glm::vec3 focus) {
|
void ViewportController::setViewFocus(glm::vec3 focus) {
|
||||||
this->focus = focus;
|
this->focus = focus;
|
||||||
}
|
}
|
|
@ -6,13 +6,14 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
class Input;
|
class Input;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
|
||||||
class ViewportControl {
|
class ViewportController {
|
||||||
public:
|
public:
|
||||||
ViewportControl(Input& input, Camera& camera);
|
ViewportController(Input& input, Camera& camera);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void setViewFocus(glm::vec3 focus);
|
void setViewFocus(glm::vec3 focus);
|
||||||
|
@ -22,6 +23,7 @@ private:
|
||||||
Camera& camera;
|
Camera& camera;
|
||||||
|
|
||||||
double panFactor = 0.0075;
|
double panFactor = 0.0075;
|
||||||
|
double arrowFactor = 0.05;
|
||||||
double distance = 4;
|
double distance = 4;
|
||||||
|
|
||||||
glm::vec3 focus;
|
glm::vec3 focus;
|
|
@ -3,8 +3,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "BlockModel.h"
|
#include "BlockModel.h"
|
||||||
#include "BlockModelManager.h"
|
#include "BlockModelManager.h"
|
||||||
|
@ -13,8 +11,7 @@
|
||||||
#include "../graph/Camera.h"
|
#include "../graph/Camera.h"
|
||||||
#include "../graph/Window.h"
|
#include "../graph/Window.h"
|
||||||
#include "../graph/Renderer.h"
|
#include "../graph/Renderer.h"
|
||||||
#include "../input/ViewportControl.h"
|
#include "../input/ViewportController.h"
|
||||||
#include "../input/Ray.h"
|
|
||||||
|
|
||||||
BlockModelManager::BlockModelManager(Camera* camera, Window* window) :
|
BlockModelManager::BlockModelManager(Camera* camera, Window* window) :
|
||||||
dirt("../assets/textures/dirt.png"),
|
dirt("../assets/textures/dirt.png"),
|
||||||
|
@ -22,66 +19,39 @@ BlockModelManager::BlockModelManager(Camera* camera, Window* window) :
|
||||||
window(window) {
|
window(window) {
|
||||||
|
|
||||||
models.emplace_back(std::make_shared<BlockModel>());
|
models.emplace_back(std::make_shared<BlockModel>());
|
||||||
|
|
||||||
instances.emplace_back(models[0]);
|
instances.emplace_back(models[0]);
|
||||||
instances.emplace_back(models[0]);
|
|
||||||
instances.emplace_back(models[0]);
|
|
||||||
// instances.emplace_back(models[0]);
|
|
||||||
// instances.emplace_back(models[0]);
|
|
||||||
// instances.emplace_back(models[0]);
|
|
||||||
// instances.emplace_back(models[0]);
|
|
||||||
|
|
||||||
instances[1].setPos({1, 0, 0});
|
|
||||||
instances[2].setPos({-1, 0, 0});
|
|
||||||
// instances[3].setPos({0, 0, 1});
|
|
||||||
// instances[4].setPos({0, 0, -1});
|
|
||||||
// instances[5].setPos({0, 1, 0});
|
|
||||||
// instances[6].setPos({0, -1, 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockModelManager::update(Input& input, ViewportControl& viewport) {
|
|
||||||
for (auto& instance : instances) instance.setHighlighted(false);
|
|
||||||
|
|
||||||
if (!editingModel) {
|
|
||||||
glm::vec3 dir = Ray::worldRayFromCursor(*window, *camera);
|
|
||||||
glm::vec3 ray = camera->getPos();
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
float dis = 0.05f;
|
|
||||||
|
|
||||||
while (dis < 20) {
|
|
||||||
glm::vec3 end = ray + (dir * dis);
|
|
||||||
glm::ivec3 blockSpace = glm::floor(end + glm::vec3(0.5));
|
|
||||||
|
|
||||||
for (auto& instance : instances) {
|
|
||||||
if (instance.getPos() == blockSpace) {
|
|
||||||
instance.setHighlighted(true);
|
|
||||||
if (input.keyPressed(GLFW_MOUSE_BUTTON_LEFT)) {
|
|
||||||
viewport.setViewFocus(instance.getPos());
|
|
||||||
setEditingModel(instance);
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) break;
|
|
||||||
dis += 0.05;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else editingInstance->update(viewport, *window, *camera);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockModelManager::render(Renderer &renderer) {
|
void BlockModelManager::render(Renderer &renderer) {
|
||||||
dirt.use();
|
dirt.use();
|
||||||
|
|
||||||
for (auto& instance : instances)
|
for (auto& instance : instances)
|
||||||
if (!editingModel || editingPos != instance.getPos()) instance.render(renderer);
|
if (!editingModel || editingPos != instance.getPos())
|
||||||
|
instance.render(renderer);
|
||||||
|
|
||||||
if (editingInstance) editingInstance->render(renderer);
|
if (editingInstance) editingInstance->render(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockModelManager::setEditingModel(BlockModelInstance& instance) {
|
std::shared_ptr<BlockModel> BlockModelManager::getEditingModel() {
|
||||||
editingPos = instance.getPos();
|
return editingModel;
|
||||||
editingModel = instance.getModel();
|
}
|
||||||
|
|
||||||
editingInstance = std::make_shared<EditingBlockModel>(editingPos, editingModel);
|
void BlockModelManager::setEditingInstance(glm::ivec3 pos) {
|
||||||
|
for (auto& instance : instances) {
|
||||||
|
if (instance.getPos() != pos) continue;
|
||||||
|
|
||||||
|
editingPos = instance.getPos();
|
||||||
|
editingModel = instance.getModel();
|
||||||
|
editingInstance = std::make_shared<EditingBlockModel>(editingPos, editingModel);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlockModelManager::highlightInstanceAtPos(glm::ivec3 pos) {
|
||||||
|
for (auto& instance : instances) {
|
||||||
|
instance.setHighlighted(instance.getPos() == pos);
|
||||||
|
if (instance.getPos() == pos) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,17 +12,18 @@ class Input;
|
||||||
class Camera;
|
class Camera;
|
||||||
class Window;
|
class Window;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class ViewportControl;
|
class ViewportController;
|
||||||
class EditingBlockModel;
|
class EditingBlockModel;
|
||||||
|
|
||||||
class BlockModelManager {
|
class BlockModelManager {
|
||||||
public:
|
public:
|
||||||
BlockModelManager(Camera* camera, Window* window);
|
BlockModelManager(Camera* camera, Window* window);
|
||||||
|
|
||||||
void update(Input& input, ViewportControl& viewport);
|
|
||||||
void render(Renderer& renderer);
|
void render(Renderer& renderer);
|
||||||
|
|
||||||
void setEditingModel(BlockModelInstance& instance);
|
bool highlightInstanceAtPos(glm::ivec3 pos);
|
||||||
|
std::shared_ptr<BlockModel> getEditingModel();
|
||||||
|
void setEditingInstance(glm::ivec3 pos);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<BlockModel>> models;
|
std::vector<std::shared_ptr<BlockModel>> models;
|
||||||
std::vector<BlockModelInstance> instances;
|
std::vector<BlockModelInstance> instances;
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "EditingBlockModel.h"
|
#include "EditingBlockModel.h"
|
||||||
|
|
||||||
#include "BlockModel.h"
|
#include "BlockModel.h"
|
||||||
#include "../input/Ray.h"
|
#include "../util/Ray.h"
|
||||||
#include "../graph/Renderer.h"
|
#include "../graph/Renderer.h"
|
||||||
|
|
||||||
EditingBlockModel::EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel> model) :
|
EditingBlockModel::EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel> model) :
|
||||||
|
@ -17,21 +19,11 @@ EditingBlockModel::EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel>
|
||||||
updateFaces();
|
updateFaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditingBlockModel::update(ViewportControl &viewport, Window &window, Camera &camera) {
|
void EditingBlockModel::update(ViewportController &viewport, Window &window, Camera &camera) {
|
||||||
glm::vec3 dir = Ray::worldRayFromCursor(window, camera);
|
if (!highlightedFace || !window.getInput().keyDown(GLFW_MOUSE_BUTTON_LEFT))
|
||||||
glm::vec3 ray = camera.getPos();
|
holdOrigin = findHoveredFace(viewport, window, camera);
|
||||||
|
else if (highlightedFace)
|
||||||
int ind = -1;
|
manipulateFace(viewport, window, camera);
|
||||||
float smallestDistance = 1000;
|
|
||||||
for (int i = 0; i < faces.size(); i++) {
|
|
||||||
facesHighlighted[i] = false;
|
|
||||||
float dist = Ray::rayInterceptsRect(ray, dir, this->model->faces[i].points, pos);
|
|
||||||
if (dist != 0 && dist < smallestDistance) {
|
|
||||||
smallestDistance = dist;
|
|
||||||
ind = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ind != -1) facesHighlighted[ind] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditingBlockModel::render(Renderer &renderer) {
|
void EditingBlockModel::render(Renderer &renderer) {
|
||||||
|
@ -45,6 +37,75 @@ void EditingBlockModel::render(Renderer &renderer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 EditingBlockModel::findHoveredFace(ViewportController &viewport, Window &window, Camera &camera) {
|
||||||
|
glm::vec3 dir = Ray::worldRayFromCursor(window, camera);
|
||||||
|
glm::vec3 ray = camera.getPos();
|
||||||
|
|
||||||
|
int ind = -1;
|
||||||
|
float smallestDistance = 1000;
|
||||||
|
glm::vec3 targetPos;
|
||||||
|
|
||||||
|
for (int i = 0; i < faces.size(); i++) {
|
||||||
|
facesHighlighted[i] = false;
|
||||||
|
|
||||||
|
float dist;
|
||||||
|
glm::vec3 intPos;
|
||||||
|
|
||||||
|
Ray::rayInterceptsRect(ray, dir, this->model->faces[i].points, pos, dist, intPos);
|
||||||
|
if (dist != 0 && dist < smallestDistance) {
|
||||||
|
smallestDistance = dist;
|
||||||
|
targetPos = intPos;
|
||||||
|
ind = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ind != -1) {
|
||||||
|
highlightedFace = &this->model->faces[ind];
|
||||||
|
this->facesHighlighted[ind] = true;
|
||||||
|
}
|
||||||
|
else highlightedFace = nullptr;
|
||||||
|
|
||||||
|
return targetPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditingBlockModel::manipulateFace(ViewportController &viewport, Window &window, Camera &camera) {
|
||||||
|
if (window.getInput().keyDown(GLFW_MOUSE_BUTTON_LEFT)) {
|
||||||
|
glm::vec3 ray = camera.getPos();
|
||||||
|
glm::vec3 dir = Ray::worldRayFromCursor(window, camera);
|
||||||
|
|
||||||
|
glm::vec3 nml = glm::normalize(glm::cross(highlightedFace->points[1] - highlightedFace->points[0],
|
||||||
|
highlightedFace->points[3] - highlightedFace->points[0]));
|
||||||
|
|
||||||
|
// Get ray to be on plane determined by the camera view-angle.
|
||||||
|
auto lookVec = glm::abs(Ray::lookVecFromCamera(camera));
|
||||||
|
float b = lookVec.x > lookVec.y ? lookVec.x > lookVec.z ? 0 : 2 : lookVec.y > lookVec.z ? 1 : 2;
|
||||||
|
|
||||||
|
// Looking head-on at face, use a different lock value.
|
||||||
|
if (nml[b] != 0) b = b == 1 ? 0 : 1;
|
||||||
|
|
||||||
|
if (ray[b] < holdOrigin[b]) {
|
||||||
|
while (ray[b] < holdOrigin[b]) ray += dir;
|
||||||
|
while (ray[b] > holdOrigin[b]) ray -= dir / 20.f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (ray[b] > holdOrigin[b]) ray += dir;
|
||||||
|
while (ray[b] < holdOrigin[b]) ray -= dir / 20.f;
|
||||||
|
}
|
||||||
|
ray[b] = holdOrigin[b];
|
||||||
|
|
||||||
|
for (auto& point : highlightedFace->points) {
|
||||||
|
glm::vec3 diff = ray - point - pos;
|
||||||
|
if (true) diff = glm::vec3(glm::ivec3(diff * 16.f)) / 16.f;
|
||||||
|
point += diff * glm::abs(nml);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << nml.x << ", " << nml.y << ", " << nml.z << std::endl;
|
||||||
|
std::cout << b << std::endl;
|
||||||
|
|
||||||
|
updateFaces();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EditingBlockModel::updateFaces() {
|
void EditingBlockModel::updateFaces() {
|
||||||
faces.clear();
|
faces.clear();
|
||||||
facesHighlighted.clear();
|
facesHighlighted.clear();
|
||||||
|
@ -59,4 +120,5 @@ void EditingBlockModel::updateFaces() {
|
||||||
faces.push_back(mesh);
|
faces.push_back(mesh);
|
||||||
facesHighlighted.push_back(false);
|
facesHighlighted.push_back(false);
|
||||||
}
|
}
|
||||||
|
model->updateMesh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,33 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "../graph/Mesh.h"
|
#include "../graph/Mesh.h"
|
||||||
|
#include "BlockFace.h"
|
||||||
|
|
||||||
class Window;
|
class Window;
|
||||||
class Camera;
|
class Camera;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class BlockModel;
|
class BlockModel;
|
||||||
class ViewportControl;
|
class ViewportController;
|
||||||
|
|
||||||
class EditingBlockModel {
|
class EditingBlockModel {
|
||||||
public:
|
public:
|
||||||
EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel> model);
|
EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel> model);
|
||||||
|
|
||||||
void update(ViewportControl &viewport, Window &window, Camera &camera);
|
void update(ViewportController &viewport, Window &window, Camera &camera);
|
||||||
void render(Renderer& renderer);
|
void render(Renderer& renderer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
glm::vec3 findHoveredFace(ViewportController &viewport, Window &window, Camera &camera);
|
||||||
|
void manipulateFace(ViewportController &viewport, Window &window, Camera &camera);
|
||||||
|
|
||||||
void updateFaces();
|
void updateFaces();
|
||||||
|
|
||||||
glm::vec3 pos;
|
glm::vec3 pos;
|
||||||
std::shared_ptr<BlockModel> model;
|
std::shared_ptr<BlockModel> model;
|
||||||
|
|
||||||
|
BlockFace* highlightedFace = nullptr;
|
||||||
|
glm::vec3 holdOrigin;
|
||||||
|
|
||||||
std::vector<BlockMesh> faces;
|
std::vector<BlockMesh> faces;
|
||||||
std::vector<bool> facesHighlighted;
|
std::vector<bool> facesHighlighted;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,14 @@
|
||||||
#include "../graph/Camera.h"
|
#include "../graph/Camera.h"
|
||||||
|
|
||||||
namespace Ray {
|
namespace Ray {
|
||||||
|
static glm::vec3 lookVecFromCamera(Camera& camera) {
|
||||||
|
return glm::normalize(glm::vec3 {
|
||||||
|
cos(camera.getYaw()) * cos(camera.getPitch()),
|
||||||
|
sin(camera.getPitch()),
|
||||||
|
sin(camera.getYaw()) * cos(camera.getPitch()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static glm::vec3 worldRayFromCursor(Window &window, Camera &camera) {
|
static glm::vec3 worldRayFromCursor(Window &window, Camera &camera) {
|
||||||
return glm::vec3(glm::inverse(camera.getViewMatrix()) *
|
return glm::vec3(glm::inverse(camera.getViewMatrix()) *
|
||||||
glm::vec4(glm::vec2(glm::inverse(camera.getProjectionMatrix()) * glm::vec4 {
|
glm::vec4(glm::vec2(glm::inverse(camera.getProjectionMatrix()) * glm::vec4 {
|
||||||
|
@ -17,7 +25,9 @@ namespace Ray {
|
||||||
1.f - (2.f * window.getInput().mousePos().y) / window.getSize().y, -1.f, 1.f }), -1.0, 0.0));
|
1.f - (2.f * window.getInput().mousePos().y) / window.getSize().y, -1.f, 1.f }), -1.0, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static float rayInterceptsRect(glm::vec3 rayOrigin, glm::vec3 rayDir, std::array<glm::vec3, 4> p, glm::vec3 pO = {}) {
|
static void rayInterceptsRect(glm::vec3 rayOrigin, glm::vec3 rayDir,
|
||||||
|
std::array<glm::vec3, 4> p, glm::vec3 pO, float& intDist, glm::vec3& intPos) {
|
||||||
|
|
||||||
rayDir = glm::normalize(rayDir);
|
rayDir = glm::normalize(rayDir);
|
||||||
rayOrigin -= pO;
|
rayOrigin -= pO;
|
||||||
glm::vec3 v1 = p[1] - p[0];
|
glm::vec3 v1 = p[1] - p[0];
|
||||||
|
@ -27,7 +37,11 @@ namespace Ray {
|
||||||
float D = -glm::dot(n, p[0]);
|
float D = -glm::dot(n, p[0]);
|
||||||
|
|
||||||
float t = -(glm::dot(n, rayOrigin) + D) / (glm::dot(n, rayDir));
|
float t = -(glm::dot(n, rayOrigin) + D) / (glm::dot(n, rayDir));
|
||||||
if (t < 0) return 0;
|
if (t < 0) {
|
||||||
|
intDist = 0;
|
||||||
|
intPos = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
glm::vec3 intercepts = rayOrigin + rayDir * t;
|
glm::vec3 intercepts = rayOrigin + rayDir * t;
|
||||||
|
|
||||||
// First pass
|
// First pass
|
||||||
|
@ -36,21 +50,38 @@ namespace Ray {
|
||||||
glm::vec3 v4 = glm::normalize(intercepts - p[0]);
|
glm::vec3 v4 = glm::normalize(intercepts - p[0]);
|
||||||
glm::vec3 v5 = glm::normalize(intercepts - p[2]);
|
glm::vec3 v5 = glm::normalize(intercepts - p[2]);
|
||||||
|
|
||||||
if (!(glm::dot(v1, v4) >= 0 && glm::dot(v3, v5) >= 0)) return 0;
|
if (!(glm::dot(v1, v4) >= 0 && glm::dot(v3, v5) >= 0)) {
|
||||||
|
intDist = 0;
|
||||||
|
intPos = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Second pass
|
// Second pass
|
||||||
v2 = glm::normalize(v2);
|
v2 = glm::normalize(v2);
|
||||||
glm::vec3 v6 = glm::normalize(p[0] - p[3]);
|
glm::vec3 v6 = glm::normalize(p[0] - p[3]);
|
||||||
glm::vec3 v7 = glm::normalize(intercepts - p[1]);
|
glm::vec3 v7 = glm::normalize(intercepts - p[1]);
|
||||||
glm::vec3 v8 = glm::normalize(intercepts - p[3]);
|
glm::vec3 v8 = intercepts - p[3];
|
||||||
|
|
||||||
if (!(glm::dot(v2, v7) >= 0 && glm::dot(v6, v8) >= 0)) return 0;
|
if (!(glm::dot(v2, v7) >= 0 && glm::dot(v6, v8) >= 0)) {
|
||||||
return t;
|
intDist = 0;
|
||||||
|
intPos = {};
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
intDist = t;
|
||||||
|
intPos = intercepts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float rayInterceptsRectDist(glm::vec3 rayOrigin, glm::vec3 rayDir, std::array<glm::vec3, 4> p, glm::vec3 pO = {}) {
|
||||||
|
float dist;
|
||||||
|
glm::vec3 pos;
|
||||||
|
rayInterceptsRect(rayOrigin, rayDir, p, pO, dist, pos);
|
||||||
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rayInterceptsRects(glm::vec3 rayOrigin, glm::vec3 rayDir, std::vector<std::array<glm::vec3, 4>> pointsVec, glm::vec3 pO = {}) {
|
static bool rayInterceptsRects(glm::vec3 rayOrigin, glm::vec3 rayDir, std::vector<std::array<glm::vec3, 4>> pointsVec, glm::vec3 pO = {}) {
|
||||||
for (auto& p : pointsVec)
|
for (auto& p : pointsVec)
|
||||||
if (rayInterceptsRect(rayOrigin, rayDir, p, pO)) return true;
|
if (rayInterceptsRectDist(rayOrigin, rayDir, p, pO)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue