yunusemregul / bsp_viewer Goto Github PK
View Code? Open in Web Editor NEWSource Engine BSP file viewer based on OpenGL
License: GNU General Public License v3.0
Source Engine BSP file viewer based on OpenGL
License: GNU General Public License v3.0
Hello there!
I'm doing my own Source BSP renderer as well and in researching the face displacement algorithm I found your repo, and saw that you were having problems with it too.
I just spent 2 days reverse engineering the format and found the solution.
I don't have much time to open a PR so I'll leave the code here:
void generatePatch(const std::vector<glm::vec3>& inVertices, const std::vector<unsigned int>& inIndices, std::vector<glm::vec3>& outVertices, std::vector<glm::vec2>& uvs, std::vector<unsigned int>& indices, ddispinfo_t dispInfo, float tv[2][4], dface_t face) {
auto lerp = [](glm::vec3 a, glm::vec3 b, float t) -> glm::vec3 {
return a + t * (b - a);
};
std::vector<glm::vec3> v = { inVertices[0], inVertices[1], inVertices[2], inVertices[3] };
//check which corner has the minimum value, to use it as starting point
float startDist = 10000000000000; //big number, nothing special
int startIndex = -1;
for (int j = 0; j < 4; j++) {
const float dist = glm::distance(v[j], dispInfo.startPosition);
if (dist < startDist) {
startIndex = j;
startDist = dist;
}
}
//rotate the vector to put the lowest point first
if (startIndex != 0)
std::rotate(v.begin(), v.begin() + startIndex, v.end());
int power = dispInfo.power;
int numVerts = glm::pow((glm::pow(2, power) + 1), 2);
int length = (1 << power) + 1;
outVertices.resize(numVerts);
glm::vec3 v0{};
glm::vec3 v1{};
for (int i = 0; i < length; i++) {
const float ty = (float)i / (float)(length - 1);
v0 = lerp(v[0], v[1], ty);
v1 = lerp(v[3], v[2], ty);
for (int j = 0; j < length; j++) {
int index = dispInfo.DispVertStart + (i * length) + j;
auto& dispVertex = m_pBspFileData.vertDisps[index];
const float tx = (float)j / (float)(length - 1.0f);
glm::vec3 vtx = lerp(v0, v1, tx);
//Generate texcoords
float u = (tv[0][0] * vtx.x) + (tv[0][1] * vtx.y) + (tv[0][2] * vtx.z) + tv[0][3];
float v = (tv[1][0] * vtx.x) + (tv[1][1] * vtx.y) + (tv[1][2] * vtx.z) + tv[1][3];
uvs.push_back(glm::vec2(u, v));
//displace
vtx += dispVertex.vec * dispVertex.dist;
outVertices[i * length + j] = vtx;
}
}
//Triangulate
int edge = 0;
for (int i = 0; i < numVerts - length; i++) {
if (edge == length - 1) {
edge = 0;
continue;
}
indices.push_back(i + 1);
indices.push_back(i);
indices.push_back(i + length);
indices.push_back(i + 1);
indices.push_back(i + length);
indices.push_back(i + length + 1);
edge++;
}
}
Anyway, I hope you find this useful
Good luck!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.