mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-08 20:50:19 -06:00
189 lines
6.5 KiB
C++
189 lines
6.5 KiB
C++
/*****************************************************************************************
|
|
* *
|
|
* OpenSpace *
|
|
* *
|
|
* Copyright (c) 2014-2022 *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
|
* software and associated documentation files (the "Software"), to deal in the Software *
|
|
* without restriction, including without limitation the rights to use, copy, modify, *
|
|
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
|
* permit persons to whom the Software is furnished to do so, subject to the following *
|
|
* conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included in all copies *
|
|
* or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
|
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
|
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
|
****************************************************************************************/
|
|
|
|
#include <openspace/util/blockplaneintersectiongeometry.h>
|
|
|
|
#include <ghoul/logging/logmanager.h>
|
|
#include <algorithm>
|
|
|
|
namespace {
|
|
constexpr const char* _loggerCat = "BlockPlaneIntersectionGeometry";
|
|
} // namespace
|
|
|
|
namespace openspace {
|
|
|
|
BlockPlaneIntersectionGeometry::BlockPlaneIntersectionGeometry(glm::vec3 blockSize,
|
|
glm::vec3 planeNormal,
|
|
float planeDistance)
|
|
: _size(blockSize)
|
|
, _normal(planeNormal)
|
|
, _planeDistance(planeDistance)
|
|
{}
|
|
|
|
BlockPlaneIntersectionGeometry::~BlockPlaneIntersectionGeometry() {
|
|
glDeleteBuffers(1, &_vBufferId);
|
|
glDeleteVertexArrays(1, &_vaoId);
|
|
}
|
|
|
|
void BlockPlaneIntersectionGeometry::setBlockSize(glm::vec3 size) {
|
|
_size = std::move(size);
|
|
updateVertices();
|
|
}
|
|
|
|
void BlockPlaneIntersectionGeometry::setPlane(glm::vec3 normal, float distance) {
|
|
_normal = glm::normalize(normal);
|
|
_planeDistance = distance;
|
|
updateVertices();
|
|
}
|
|
|
|
void BlockPlaneIntersectionGeometry::updateVertices() {
|
|
_vertices.clear();
|
|
|
|
const int cornersInLines[24] = {
|
|
0, 1,
|
|
1, 5,
|
|
5, 4,
|
|
4, 0,
|
|
|
|
2, 3,
|
|
3, 7,
|
|
7, 6,
|
|
6, 2,
|
|
|
|
0, 2,
|
|
1, 3,
|
|
5, 7,
|
|
4, 6
|
|
};
|
|
|
|
const glm::vec3 halfSize = _size * 0.5f;
|
|
glm::vec3 intersections[12];
|
|
std::fill(std::begin(intersections), std::end(intersections), glm::vec3(0.f));
|
|
int nIntersections = 0;
|
|
|
|
for (int i = 0; i < 12; i++) {
|
|
int iCorner0 = cornersInLines[i * 2];
|
|
int iCorner1 = cornersInLines[i * 2 + 1];
|
|
|
|
glm::vec3 corner0 = glm::vec3(
|
|
iCorner0 % 2,
|
|
(iCorner0 / 2) % 2,
|
|
iCorner0 / 4
|
|
) - halfSize;
|
|
glm::vec3 corner1 = glm::vec3(
|
|
iCorner1 % 2,
|
|
(iCorner1 / 2) % 2,
|
|
iCorner1 / 4
|
|
) - halfSize;
|
|
|
|
glm::vec3 line = corner1 - corner0;
|
|
|
|
float t = (_planeDistance - glm::dot(corner0, _normal)) / glm::dot(line, _normal);
|
|
if (t >= 0.0 && t <= 1.0) {
|
|
intersections[nIntersections++] = corner0 + t * line;
|
|
}
|
|
}
|
|
|
|
// Gotta love intersections
|
|
if (nIntersections <3) {
|
|
return;
|
|
}
|
|
|
|
// Construct vectors vectors (vectors1 .. vectorsN) between the N points
|
|
|
|
std::vector<std::pair<int, float>> angles(nIntersections - 1);
|
|
|
|
glm::vec3 vector1 = glm::normalize(intersections[1] - intersections[0]);
|
|
angles[0] = std::pair<int, float>(1, 0.0f);
|
|
|
|
for (int i = 2; i < nIntersections; i++) {
|
|
glm::vec3 vectorI = glm::normalize(intersections[i] - intersections[0]);
|
|
float sinA = glm::dot(glm::cross(vector1, vectorI), _normal);
|
|
float cosA = glm::dot(vector1, vectorI);
|
|
angles[i - 1] = { i, glm::sign(sinA) * (1.f - cosA) };
|
|
}
|
|
|
|
// Sort the vectors by angle in the plane
|
|
std::sort(angles.begin(), angles.end(),
|
|
[](const std::pair<int, float>& a, const std::pair<int, float>& b) -> bool {
|
|
return a.second < b.second;
|
|
}
|
|
);
|
|
|
|
_vertices.push_back(intersections[0].x);
|
|
_vertices.push_back(intersections[0].y);
|
|
_vertices.push_back(intersections[0].z);
|
|
//_vertices.push_back(_w);
|
|
for (int i = 0; i < nIntersections - 1; i++) {
|
|
int j = angles[i].first;
|
|
_vertices.push_back(intersections[j].x);
|
|
_vertices.push_back(intersections[j].y);
|
|
_vertices.push_back(intersections[j].z);
|
|
//_vertices.push_back(_w);
|
|
}
|
|
|
|
// First VAO setup
|
|
glBindVertexArray(_vaoId);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
|
|
glBufferData(
|
|
GL_ARRAY_BUFFER,
|
|
_vertices.size() * sizeof(GLfloat),
|
|
_vertices.data(),
|
|
GL_STATIC_DRAW
|
|
);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
|
|
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
bool BlockPlaneIntersectionGeometry::initialize() {
|
|
if (_vaoId == 0) {
|
|
glGenVertexArrays(1, &_vaoId);
|
|
}
|
|
|
|
if (_vBufferId == 0) {
|
|
glGenBuffers(1, &_vBufferId);
|
|
|
|
if (_vBufferId == 0) {
|
|
LERROR("Could not create vertex buffer");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
updateVertices();
|
|
return true;
|
|
}
|
|
|
|
void BlockPlaneIntersectionGeometry::render() {
|
|
glBindVertexArray(_vaoId);
|
|
//glDisable(GL_CULL_FACE);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(_vertices.size() / 3));
|
|
//glEnable(GL_CULL_FACE);
|
|
}
|
|
|
|
} // namespace openspace
|