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;
|
||||
vec3 color = spec.xyz;
|
||||
|
||||
if (!gl_FrontFacing) color *= vec3(1, 0, 0);
|
||||
|
||||
if (highlight) {
|
||||
color *= 1.25;
|
||||
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(),
|
||||
camera(&window),
|
||||
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()) {
|
||||
update();
|
||||
|
@ -22,7 +23,6 @@ App::App() :
|
|||
void App::update() {
|
||||
window.update();
|
||||
controller.update();
|
||||
blockManager.update(input, controller);
|
||||
}
|
||||
|
||||
void App::render() {
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#include "graph/Camera.h"
|
||||
#include "graph/Renderer.h"
|
||||
|
||||
#include "input/ViewportControl.h"
|
||||
#include "model/BlockModelManager.h"
|
||||
#include "input/Controller.h"
|
||||
|
||||
class App {
|
||||
public:
|
||||
|
@ -22,8 +22,9 @@ private:
|
|||
Window window;
|
||||
Camera camera;
|
||||
Renderer renderer;
|
||||
Input& input;
|
||||
|
||||
ViewportControl controller;
|
||||
BlockModelManager blockManager;
|
||||
|
||||
Input& input;
|
||||
Controller controller;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
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})
|
|
@ -36,7 +36,7 @@ void Renderer::setClearColor(glm::vec4 color) {
|
|||
void Renderer::reset() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
// glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
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 <iostream>
|
||||
|
||||
#include "ViewportControl.h"
|
||||
#include "ViewportController.h"
|
||||
|
||||
#include "../graph/Camera.h"
|
||||
#include "Input.h"
|
||||
|
||||
ViewportControl::ViewportControl(Input &input, Camera &camera) :
|
||||
ViewportController::ViewportController(Input &input, Camera &camera) :
|
||||
input(input),
|
||||
camera(camera) {
|
||||
|
||||
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)) {
|
||||
input.setMouseLocked(true);
|
||||
yaw += -input.mouseDelta().x * panFactor;
|
||||
|
@ -29,6 +29,15 @@ void ViewportControl::update() {
|
|||
}
|
||||
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 = {
|
||||
distance * -sinf(yaw) * cosf(pitch),
|
||||
distance * -sinf(pitch),
|
||||
|
@ -51,6 +60,6 @@ void ViewportControl::update() {
|
|||
camera.setYaw(lookYaw);
|
||||
}
|
||||
|
||||
void ViewportControl::setViewFocus(glm::vec3 focus) {
|
||||
void ViewportController::setViewFocus(glm::vec3 focus) {
|
||||
this->focus = focus;
|
||||
}
|
|
@ -6,13 +6,14 @@
|
|||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
class Input;
|
||||
class Camera;
|
||||
|
||||
class ViewportControl {
|
||||
class ViewportController {
|
||||
public:
|
||||
ViewportControl(Input& input, Camera& camera);
|
||||
ViewportController(Input& input, Camera& camera);
|
||||
|
||||
void update();
|
||||
void setViewFocus(glm::vec3 focus);
|
||||
|
@ -22,6 +23,7 @@ private:
|
|||
Camera& camera;
|
||||
|
||||
double panFactor = 0.0075;
|
||||
double arrowFactor = 0.05;
|
||||
double distance = 4;
|
||||
|
||||
glm::vec3 focus;
|
|
@ -3,8 +3,6 @@
|
|||
//
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "BlockModel.h"
|
||||
#include "BlockModelManager.h"
|
||||
|
@ -13,8 +11,7 @@
|
|||
#include "../graph/Camera.h"
|
||||
#include "../graph/Window.h"
|
||||
#include "../graph/Renderer.h"
|
||||
#include "../input/ViewportControl.h"
|
||||
#include "../input/Ray.h"
|
||||
#include "../input/ViewportController.h"
|
||||
|
||||
BlockModelManager::BlockModelManager(Camera* camera, Window* window) :
|
||||
dirt("../assets/textures/dirt.png"),
|
||||
|
@ -22,66 +19,39 @@ BlockModelManager::BlockModelManager(Camera* camera, Window* window) :
|
|||
window(window) {
|
||||
|
||||
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[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) {
|
||||
dirt.use();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void BlockModelManager::setEditingModel(BlockModelInstance& instance) {
|
||||
editingPos = instance.getPos();
|
||||
editingModel = instance.getModel();
|
||||
|
||||
editingInstance = std::make_shared<EditingBlockModel>(editingPos, editingModel);
|
||||
std::shared_ptr<BlockModel> BlockModelManager::getEditingModel() {
|
||||
return 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 Window;
|
||||
class Renderer;
|
||||
class ViewportControl;
|
||||
class ViewportController;
|
||||
class EditingBlockModel;
|
||||
|
||||
class BlockModelManager {
|
||||
public:
|
||||
BlockModelManager(Camera* camera, Window* window);
|
||||
|
||||
void update(Input& input, ViewportControl& viewport);
|
||||
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<BlockModelInstance> instances;
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "EditingBlockModel.h"
|
||||
|
||||
#include "BlockModel.h"
|
||||
#include "../input/Ray.h"
|
||||
#include "../util/Ray.h"
|
||||
#include "../graph/Renderer.h"
|
||||
|
||||
EditingBlockModel::EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel> model) :
|
||||
|
@ -17,21 +19,11 @@ EditingBlockModel::EditingBlockModel(glm::vec3 pos, std::shared_ptr<BlockModel>
|
|||
updateFaces();
|
||||
}
|
||||
|
||||
void EditingBlockModel::update(ViewportControl &viewport, Window &window, Camera &camera) {
|
||||
glm::vec3 dir = Ray::worldRayFromCursor(window, camera);
|
||||
glm::vec3 ray = camera.getPos();
|
||||
|
||||
int ind = -1;
|
||||
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::update(ViewportController &viewport, Window &window, Camera &camera) {
|
||||
if (!highlightedFace || !window.getInput().keyDown(GLFW_MOUSE_BUTTON_LEFT))
|
||||
holdOrigin = findHoveredFace(viewport, window, camera);
|
||||
else if (highlightedFace)
|
||||
manipulateFace(viewport, window, camera);
|
||||
}
|
||||
|
||||
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() {
|
||||
faces.clear();
|
||||
facesHighlighted.clear();
|
||||
|
@ -59,4 +120,5 @@ void EditingBlockModel::updateFaces() {
|
|||
faces.push_back(mesh);
|
||||
facesHighlighted.push_back(false);
|
||||
}
|
||||
model->updateMesh();
|
||||
}
|
||||
|
|
|
@ -8,26 +8,33 @@
|
|||
#include <vector>
|
||||
|
||||
#include "../graph/Mesh.h"
|
||||
#include "BlockFace.h"
|
||||
|
||||
class Window;
|
||||
class Camera;
|
||||
class Renderer;
|
||||
class BlockModel;
|
||||
class ViewportControl;
|
||||
class ViewportController;
|
||||
|
||||
class EditingBlockModel {
|
||||
public:
|
||||
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);
|
||||
|
||||
private:
|
||||
glm::vec3 findHoveredFace(ViewportController &viewport, Window &window, Camera &camera);
|
||||
void manipulateFace(ViewportController &viewport, Window &window, Camera &camera);
|
||||
|
||||
void updateFaces();
|
||||
|
||||
glm::vec3 pos;
|
||||
std::shared_ptr<BlockModel> model;
|
||||
|
||||
BlockFace* highlightedFace = nullptr;
|
||||
glm::vec3 holdOrigin;
|
||||
|
||||
std::vector<BlockMesh> faces;
|
||||
std::vector<bool> facesHighlighted;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,14 @@
|
|||
#include "../graph/Camera.h"
|
||||
|
||||
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) {
|
||||
return glm::vec3(glm::inverse(camera.getViewMatrix()) *
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
rayOrigin -= pO;
|
||||
glm::vec3 v1 = p[1] - p[0];
|
||||
|
@ -27,7 +37,11 @@ namespace Ray {
|
|||
float D = -glm::dot(n, p[0]);
|
||||
|
||||
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;
|
||||
|
||||
// First pass
|
||||
|
@ -36,21 +50,38 @@ namespace Ray {
|
|||
glm::vec3 v4 = glm::normalize(intercepts - p[0]);
|
||||
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
|
||||
v2 = glm::normalize(v2);
|
||||
glm::vec3 v6 = glm::normalize(p[0] - p[3]);
|
||||
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;
|
||||
return t;
|
||||
if (!(glm::dot(v2, v7) >= 0 && glm::dot(v6, v8) >= 0)) {
|
||||
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 = {}) {
|
||||
for (auto& p : pointsVec)
|
||||
if (rayInterceptsRect(rayOrigin, rayDir, p, pO)) return true;
|
||||
if (rayInterceptsRectDist(rayOrigin, rayDir, p, pO)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue