Skip to content

Commit

Permalink
aabb
Browse files Browse the repository at this point in the history
  • Loading branch information
ChenxiZhou0619 committed Mar 10, 2023
1 parent 83f48bf commit 1f7bcf3
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.cache
/target
/scenes
.vscode
.vscode
/examples
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ add_executable(Moer
src/CoreLayer/Math/Transform.cpp

src/FunctionLayer/Acceleration/EmbreeBVH.cpp
src/FunctionLayer/Acceleration/AABB.cpp

src/FunctionLayer/Integrator/NormalIntegrator.cpp
src/FunctionLayer/Integrator/DirectIntegrator.cpp
src/FunctionLayer/Integrator/WhittedIntegrator.cpp
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Moer-lite的框架基于Moer主干:https://github.com/NJUCG/Moer .
- 2023-3-2 添加了进度条,whitted-style积分器,镜面材质以及一个新场景cornell-box。
- 2023-3-10
- 修改了Cube.cpp 28、29行bug(之前代码正确性不影响,但是逻辑不对)
- 修改了Triangle.cpp中的bug(之前当mesh文件不存在法线和纹理信息时会发生段错误)
- 对AABB进行封装(见Shape::getAABB)

## TODO
- 对mesh和sphere实现表面采样(目前只有parallelogram可以配置为面光源)
52 changes: 52 additions & 0 deletions src/FunctionLayer/Acceleration/AABB.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "AABB.h"

Point3f minP(const Point3f &p1, const Point3f &p2) {
return Point3f{std::min(p1[0], p2[0]), std::min(p1[1], p2[1]),
std::min(p1[2], p2[2])};
}

Point3f maxP(const Point3f &p1, const Point3f &p2) {
return Point3f{std::max(p1[0], p2[0]), std::max(p1[1], p2[1]),
std::max(p1[2], p2[2])};
}

AABB AABB::Union(const AABB &other) const {
Point3f min = minP(other.pMin, pMin), max = maxP(other.pMax, pMax);
return AABB{min, max};
}

void AABB::Expand(const AABB &other) {
pMin = minP(pMin, other.pMin);
pMax = maxP(pMax, other.pMax);
}

AABB AABB::Union(const Point3f &other) const {
Point3f min = minP(other, pMin), max = maxP(other, pMax);
return AABB{min, max};
}

void AABB::Expand(const Point3f &other) {
pMin = minP(pMin, other);
pMax = maxP(pMax, other);
}

bool AABB::rayIntersect(const Ray &ray, float *tMin, float *tMax) const {
float tNear = ray.tNear, tFar = ray.tFar;
for (int i = 0; i < 3; ++i) {
float invDir = 1.f / ray.direction[i];
float t0 = (pMin[i] - ray.origin[i]) * invDir,
t1 = (pMax[i] - ray.origin[i]) * invDir;
if (t0 > t1)
std::swap(t0, t1);
tNear = std::max(tNear, t0);
tFar = std::min(tFar, t1);

if (tNear > tFar)
return false;
}
if (tMin)
*tMin = tNear;
if (tMax)
*tMax = tFar;
return true;
}
27 changes: 27 additions & 0 deletions src/FunctionLayer/Acceleration/AABB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once
#include <CoreLayer/Math/Math.h>
#include <FunctionLayer/Ray/Ray.h>
// Axis-aligned Bounding box,即AABB
class AABB {
public:
AABB() {
pMin = Point3f{FLT_MAX, FLT_MAX, FLT_MAX};
pMax = Point3f{-FLT_MAX, -FLT_MAX, -FLT_MAX};
}

AABB(const Point3f &_pMin, const Point3f &_pMax) : pMin(_pMin), pMax(_pMax) {}

AABB Union(const AABB &other) const;

void Expand(const AABB &other);

AABB Union(const Point3f &other) const;

void Expand(const Point3f &other);

bool rayIntersect(const Ray &ray, float *tMin = nullptr,
float *tMax = nullptr) const;

public:
Point3f pMin, pMax;
};
4 changes: 1 addition & 3 deletions src/FunctionLayer/Shape/Cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Cube::Cube(const Json &json) : Shape(json) {
boxMax = Point3f{1.f, 1.f, 1.f};

// 构建AABB
pMin = pMax = transform.toWorld(boxMin);
for (int i = 0; i < 8; ++i) {
Point3f p;
p[0] = (i & 0b100) ? boxMax[0] : boxMin[0];
Expand All @@ -18,8 +17,7 @@ Cube::Cube(const Json &json) : Shape(json) {
p = transform.toWorld(p);

for (int j = 0; j < 3; ++j) {
pMin[j] = std::min(pMin[j], p[j]);
pMax[j] = std::max(pMax[j], p[j]);
boundingBox.Expand(p);
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/FunctionLayer/Shape/Parallelogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ Parallelogram::Parallelogram(const Json &json) : Shape(json) {
vertices[1] = vertices[0] + edge0;
vertices[2] = vertices[1] + edge1;
vertices[3] = vertices[0] + edge1;
pMin = pMax = vertices[0]; // 初始化
for (int dim = 0; dim < 3; ++dim) {
for (int i = 1; i < 4; ++i) {
pMin[dim] = std::min(pMin[dim], vertices[i][dim]);
pMax[dim] = std::max(pMax[dim], vertices[i][dim]);
}

for (int i = 0; i < 4; ++i) {
boundingBox.Expand(vertices[i]);
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/FunctionLayer/Shape/Shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ Shape::Shape(const Json &json) {
}
}

std::pair<Point3f, Point3f> Shape::getAABB() const { return {pMin, pMax}; }

void UserShapeBound(const RTCBoundsFunctionArguments *args) {
Shape *shape = static_cast<Shape *>(args->geometryUserPtr);
auto [pMin, pMax] = shape->getAABB();
Expand Down
6 changes: 3 additions & 3 deletions src/FunctionLayer/Shape/Shape.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "Intersection.h"
#include <FunctionLayer/Acceleration/AABB.h>
#include <FunctionLayer/Ray/Ray.h>
#include <ResourceLayer/JsonUtil.h>
#include <embree3/rtcore.h>
Expand All @@ -16,8 +17,7 @@ class Shape : public Transformable {

virtual RTCGeometry getEmbreeGeometry(RTCDevice device) const;

// TODO 对AABB做一个封装
std::pair<Point3f, Point3f> getAABB() const;
AABB getAABB() const { return boundingBox; }

virtual bool rayIntersectShape(const Ray &ray, float *distance, int *primID,
float *u, float *v) const = 0;
Expand All @@ -37,5 +37,5 @@ class Shape : public Transformable {
std::shared_ptr<Material> material;

protected:
Point3f pMin, pMax; // AABB包围盒,构建时初始化
AABB boundingBox;
};
3 changes: 1 addition & 2 deletions src/FunctionLayer/Shape/Sphere.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ Sphere::Sphere(const Json &json) : Shape(json) {
radius = fetchRequired<float>(json, "radius");

center = transform.toWorld(center);
pMin = center - Vector3f(radius);
pMax = center + Vector3f(radius);
boundingBox = AABB(center - Vector3f(radius), center + Vector3f(radius));
}

bool Sphere::rayIntersectShape(const Ray &ray, float *distance, int *primID,
Expand Down
27 changes: 19 additions & 8 deletions src/FunctionLayer/Shape/Triangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,27 @@ void Triangle::fillIntersection(float distance, int primID, float u, float v,
w * pw[1] + u * pu[1] + v * pv[1],
w * pw[2] + u * pu[2] + v * pv[2]};
//* 计算法线
Vector3f nw = transform.toWorld(mesh->normalBuffer[faceInfo[0].normalIndex]),
nu = transform.toWorld(mesh->normalBuffer[faceInfo[1].normalIndex]),
nv = transform.toWorld(mesh->normalBuffer[faceInfo[2].normalIndex]);
intersection->normal = normalize(w * nw + u * nu + v * nv);
if (mesh->normalBuffer.size() != 0) {
Vector3f nw =
transform.toWorld(mesh->normalBuffer[faceInfo[0].normalIndex]),
nu =
transform.toWorld(mesh->normalBuffer[faceInfo[1].normalIndex]),
nv =
transform.toWorld(mesh->normalBuffer[faceInfo[2].normalIndex]);
intersection->normal = normalize(w * nw + u * nu + v * nv);
} else {
intersection->normal = normalize(cross(pu - pw, pv - pw));
}

//* 计算纹理坐标
Vector2f tw = mesh->texcodBuffer[faceInfo[0].texcodIndex],
tu = mesh->texcodBuffer[faceInfo[1].texcodIndex],
tv = mesh->texcodBuffer[faceInfo[2].texcodIndex];
intersection->texCoord = w * tw + u * tu + v * tv;
if (mesh->texcodBuffer.size() != 0) {
Vector2f tw = mesh->texcodBuffer[faceInfo[0].texcodIndex],
tu = mesh->texcodBuffer[faceInfo[1].texcodIndex],
tv = mesh->texcodBuffer[faceInfo[2].texcodIndex];
intersection->texCoord = w * tw + u * tu + v * tv;
} else {
intersection->texCoord = Vector2f{.0f, .0f};
}

// TODO 计算交点的切线和副切线
Vector3f tangent{1.f, 0.f, .0f};
Expand Down

0 comments on commit 1f7bcf3

Please sign in to comment.