Skip to content

Commit

Permalink
InstancesMesh: Add bounding volume
Browse files Browse the repository at this point in the history
  • Loading branch information
markaren committed Mar 20, 2024
1 parent 32210bc commit 8d791cf
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 33 deletions.
1 change: 1 addition & 0 deletions examples/extras/physics/PxEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class PxEngine: public threepp::Object3D {
}

instanced->instanceMatrix()->needsUpdate();
instanced->computeBoundingSphere();

} else {

Expand Down
2 changes: 2 additions & 0 deletions examples/objects/instancing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace {
}
mesh.instanceMatrix()->needsUpdate();
mesh.instanceColor()->needsUpdate();

mesh.computeBoundingSphere();
}

}// namespace
Expand Down
16 changes: 16 additions & 0 deletions include/threepp/objects/InstancedMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace threepp {
class InstancedMesh: public Mesh {

public:
std::optional<Sphere> boundingSphere;
std::optional<Box3> boundingBox;

InstancedMesh(
std::shared_ptr<BufferGeometry> geometry,
std::shared_ptr<Material> material,
Expand All @@ -35,6 +38,10 @@ namespace threepp {

void setMatrixAt(size_t index, const Matrix4& matrix) const;

void computeBoundingBox();

void computeBoundingSphere();

void dispose();

void raycast(const Raycaster& raycaster, std::vector<Intersection>& intersects) override;
Expand All @@ -52,8 +59,17 @@ namespace threepp {

size_t count_;
size_t maxCount_;

std::unique_ptr<FloatBufferAttribute> instanceMatrix_;
std::unique_ptr<FloatBufferAttribute> instanceColor_ = nullptr;

Matrix4 _instanceLocalMatrix;
Matrix4 _instanceWorldMatrix;

Sphere _sphere;
Box3 _box3;

std::vector<Intersection> _instanceIntersects;
};

}// namespace threepp
Expand Down
54 changes: 36 additions & 18 deletions src/threepp/math/Box3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

#include "threepp/core/BufferGeometry.hpp"
#include "threepp/core/Object3D.hpp"
#include "threepp/objects/InstancedMesh.hpp"

#include "threepp/math/Plane.hpp"
#include "threepp/math/Triangle.hpp"


using namespace threepp;

namespace {
Expand Down Expand Up @@ -199,32 +200,49 @@ Box3& Box3::expandByObject(Object3D& object, bool presice) {

object.updateWorldMatrix(false, false);

const auto geometry = object.geometry();
if (auto instancedMesh = object.as<InstancedMesh>()) {

if (geometry) {
Box3 _box{};

if (presice && geometry->getAttributes().count("position")) {
if (!instancedMesh->boundingBox) instancedMesh->computeBoundingBox();

const auto position = geometry->getAttribute<float>("position");
for (unsigned i = 0, l = position->count(); i < l; i++) {
_box.copy(*instancedMesh->boundingBox);

position->setFromBufferAttribute(_vector, i);
_vector.applyMatrix4(*object.matrixWorld);
this->expandByPoint(_vector);
}
_box.applyMatrix4(*object.matrixWorld);

} else {
this->union_(_box);

if (!geometry->boundingBox) {
} else {

geometry->computeBoundingBox();
}
const auto geometry = object.geometry();

if (geometry) {

if (presice && geometry->getAttributes().count("position")) {

const auto position = geometry->getAttribute<float>("position");
for (unsigned i = 0, l = position->count(); i < l; i++) {

Box3 _box{};
_box.copy(geometry->boundingBox.value());
_box.applyMatrix4(*object.matrixWorld);
position->setFromBufferAttribute(_vector, i);
_vector.applyMatrix4(*object.matrixWorld);

this->union_(_box);
this->expandByPoint(_vector);
}

} else {

if (!geometry->boundingBox) {

geometry->computeBoundingBox();
}

Box3 _box{};

_box.copy(geometry->boundingBox.value());
_box.applyMatrix4(*object.matrixWorld);

this->union_(_box);
}
}
}

Expand Down
16 changes: 13 additions & 3 deletions src/threepp/math/Frustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "threepp/math/Frustum.hpp"

#include "threepp/core/BufferGeometry.hpp"
#include "threepp/objects/InstancedMesh.hpp"
#include "threepp/objects/Sprite.hpp"

using namespace threepp;
Expand Down Expand Up @@ -56,11 +57,20 @@ Frustum& Frustum::setFromProjectionMatrix(const Matrix4& m) {

bool Frustum::intersectsObject(Object3D& object) const {

auto geometry = object.geometry();
if (auto instancedMesh = object.as<InstancedMesh>()) {

if (!geometry->boundingSphere) geometry->computeBoundingSphere();
if (!instancedMesh->boundingSphere) instancedMesh->computeBoundingSphere();

_sphere.copy(geometry->boundingSphere.value()).applyMatrix4(*object.matrixWorld);
_sphere.copy(instancedMesh->boundingSphere.value()).applyMatrix4(*object.matrixWorld);

} else {

const auto geometry = object.geometry();

if (!geometry->boundingSphere) geometry->computeBoundingSphere();

_sphere.copy(geometry->boundingSphere.value()).applyMatrix4(*object.matrixWorld);
}

return this->intersectsSphere(_sphere);
}
Expand Down
71 changes: 59 additions & 12 deletions src/threepp/objects/InstancedMesh.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@

#include <memory>

#include "threepp/objects/InstancedMesh.hpp"

#include "threepp/core/Raycaster.hpp"

using namespace threepp;

namespace {

Matrix4 _instanceLocalMatrix;
Matrix4 _instanceWorldMatrix;

std::vector<Intersection> _instanceIntersects;

}// namespace


InstancedMesh::InstancedMesh(
std::shared_ptr<BufferGeometry> geometry,
Expand All @@ -24,7 +13,11 @@ InstancedMesh::InstancedMesh(
: Mesh(std::move(geometry), std::move(material)),
count_(count), maxCount_(count), instanceMatrix_(FloatBufferAttribute::create(std::vector<float>(count * 16), 16)) {

this->frustumCulled = false;
Matrix4 identity;
for (unsigned i = 0; i < count; i++) {

this->setMatrixAt(i, identity);
}
}

size_t InstancedMesh::count() const {
Expand Down Expand Up @@ -134,3 +127,57 @@ std::shared_ptr<InstancedMesh> InstancedMesh::create(

return std::make_shared<InstancedMesh>(std::move(geometry), std::move(material), count);
}

void InstancedMesh::computeBoundingBox() {

const auto geometry = this->geometry();
const auto count = this->count_;

if (!this->boundingBox) {

this->boundingBox = Box3();
}

if (!geometry->boundingBox) {

geometry->computeBoundingBox();
}

this->boundingBox->makeEmpty();

for (unsigned i = 0; i < count; i++) {

this->getMatrixAt(i, _instanceLocalMatrix);

_box3.copy(*geometry->boundingBox).applyMatrix4(_instanceLocalMatrix);

this->boundingBox->union_(_box3);
}
}

void InstancedMesh::computeBoundingSphere() {

const auto geometry = this->geometry();
const auto count = this->count_;

if (!this->boundingSphere) {

this->boundingSphere = Sphere();
}

if (!geometry->boundingSphere) {

geometry->computeBoundingSphere();
}

this->boundingSphere->makeEmpty();

for (unsigned i = 0; i < count; i++) {

this->getMatrixAt(i, _instanceLocalMatrix);

_sphere.copy(*geometry->boundingSphere).applyMatrix4(_instanceLocalMatrix);

this->boundingSphere->union_(_sphere);
}
}

0 comments on commit 8d791cf

Please sign in to comment.