mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 22:13:29 +02:00
in edged mode, make sure border voxels are zeroed out. expose some more voxel matrix math to javascript
This commit is contained in:
parent
6db115bed5
commit
b129c2a933
5 changed files with 117 additions and 18 deletions
libraries
|
@ -9,6 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include <QByteArray>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
|
@ -67,7 +68,7 @@ RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() {
|
|||
}
|
||||
|
||||
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||
int x, int y, int z) {
|
||||
int x, int y, int z) {
|
||||
// x, y, z are in user voxel-coords, not adjusted-for-edge voxel-coords.
|
||||
switch (surfaceStyle) {
|
||||
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES:
|
||||
|
@ -206,6 +207,11 @@ glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
|
|||
return scaled;
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::localToVoxelMatrix() const {
|
||||
glm::mat4 localToModelMatrix = glm::inverse(voxelToLocalMatrix());
|
||||
return localToModelMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::voxelToWorldMatrix() const {
|
||||
glm::mat4 rotation = glm::mat4_cast(getRotation());
|
||||
glm::mat4 translation = glm::translate(getPosition());
|
||||
|
@ -252,13 +258,32 @@ bool RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t
|
|||
return result;
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::clearEdges() {
|
||||
// if we are in an edged mode, make sure the outside surfaces are zeroed out.
|
||||
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC || _voxelSurfaceStyle == SURFACE_EDGED_MARCHING_CUBES) {
|
||||
for (int z = 0; z < _volData->getDepth(); z++) {
|
||||
for (int y = 0; y < _volData->getHeight(); y++) {
|
||||
for (int x = 0; x < _volData->getWidth(); x++) {
|
||||
if (x == 0 || y == 0 || z == 0 ||
|
||||
x == _volData->getWidth() - 1 ||
|
||||
y == _volData->getHeight() - 1 ||
|
||||
z == _volData->getDepth() - 1) {
|
||||
_volData->setVoxelAt(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
|
||||
if (_locked) {
|
||||
return false;
|
||||
}
|
||||
bool result = setVoxelInternal(x, y, z, toValue);
|
||||
compressVolumeData();
|
||||
if (result) {
|
||||
compressVolumeData();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -298,7 +323,9 @@ bool RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
|
|||
}
|
||||
}
|
||||
}
|
||||
compressVolumeData();
|
||||
if (result) {
|
||||
compressVolumeData();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -308,7 +335,7 @@ bool RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t t
|
|||
}
|
||||
|
||||
// same as setVoxel but takes a vector rather than 3 floats.
|
||||
return setVoxel((int)position.x, (int)position.y, (int)position.z, toValue);
|
||||
return setVoxel(roundf(position.x), roundf(position.y), roundf(position.z), toValue);
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
|
||||
|
@ -332,7 +359,9 @@ bool RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radi
|
|||
}
|
||||
}
|
||||
}
|
||||
compressVolumeData();
|
||||
if (result) {
|
||||
compressVolumeData();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -354,9 +383,10 @@ public:
|
|||
}
|
||||
bool operator()(PolyVox::SimpleVolume<unsigned char>::Sampler& sampler)
|
||||
{
|
||||
int x = sampler.getPosition().getX();
|
||||
int y = sampler.getPosition().getY();
|
||||
int z = sampler.getPosition().getZ();
|
||||
PolyVox::Vector3DInt32 positionIndex = sampler.getPosition();
|
||||
int x = positionIndex.getX();
|
||||
int y = positionIndex.getY();
|
||||
int z = positionIndex.getZ();
|
||||
|
||||
if (!inBounds(_vol, x, y, z)) {
|
||||
return true;
|
||||
|
@ -365,8 +395,9 @@ public:
|
|||
if (sampler.getVoxel() == 0) {
|
||||
return true; // keep raycasting
|
||||
}
|
||||
PolyVox::Vector3DInt32 positionIndex = sampler.getPosition();
|
||||
_result = glm::vec4(positionIndex.getX(), positionIndex.getY(), positionIndex.getZ(), 1.0f);
|
||||
// qDebug() << "RaycastFunctor hit" << x << y << z;
|
||||
// add {0.5, 0.5, 0.5} to result so it's centered on the voxel
|
||||
_result = glm::vec4((float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f, 1.0f);
|
||||
return false;
|
||||
}
|
||||
glm::vec4 _result;
|
||||
|
@ -386,7 +417,6 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
|||
return true;
|
||||
}
|
||||
|
||||
// the PolyVox ray intersection code requires a near and far point.
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
||||
glm::vec3 normDirection = glm::normalize(direction);
|
||||
|
||||
|
@ -411,23 +441,29 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
|||
}
|
||||
|
||||
glm::vec4 result = callback._result;
|
||||
|
||||
switch (_voxelSurfaceStyle) {
|
||||
case PolyVoxEntityItem::SURFACE_EDGED_CUBIC:
|
||||
case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES:
|
||||
result -= glm::vec4(1, 1, 1, 0); // compensate for the extra voxel border
|
||||
result -= glm::vec4(1.0f, 1.0f, 1.0f, 0.0f); // compensate for the extra voxel border
|
||||
break;
|
||||
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES:
|
||||
case PolyVoxEntityItem::SURFACE_CUBIC:
|
||||
break;
|
||||
}
|
||||
|
||||
result -= glm::vec4(0.5f, 0.5f, 0.5f, 0.0f);
|
||||
// result -= glm::vec4(0.5f, 0.5f, 0.5f, 0.0f);
|
||||
|
||||
glm::vec4 intersectedWorldPosition = voxelToWorldMatrix() * result;
|
||||
|
||||
distance = glm::distance(glm::vec3(intersectedWorldPosition), origin);
|
||||
// TODO: use this to find the actual point of intersection rather than using the center of the voxel
|
||||
// GeometryUtil.h
|
||||
// bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::quat& rotation,
|
||||
// const glm::vec3& position, const glm::vec2& dimensions, float& distance);;
|
||||
|
||||
face = BoxFace::MIN_X_FACE; // XXX
|
||||
face = BoxFace::MIN_X_FACE;
|
||||
|
||||
distance = glm::distance(glm::vec3(intersectedWorldPosition), origin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -436,6 +472,8 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
|||
// compress the data in _volData and save the results. The compressed form is used during
|
||||
// saves to disk and for transmission over the wire
|
||||
void RenderablePolyVoxEntityItem::compressVolumeData() {
|
||||
auto startTime = usecTimestampNow();
|
||||
|
||||
quint16 voxelXSize = _voxelVolumeSize.x;
|
||||
quint16 voxelYSize = _voxelVolumeSize.y;
|
||||
quint16 voxelZSize = _voxelVolumeSize.z;
|
||||
|
@ -486,6 +524,8 @@ void RenderablePolyVoxEntityItem::compressVolumeData() {
|
|||
|
||||
_dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS;
|
||||
_needsModelReload = true;
|
||||
|
||||
qDebug() << "RenderablePolyVoxEntityItem::compressVolumeData" << (usecTimestampNow() - startTime) << getName();
|
||||
}
|
||||
|
||||
|
||||
|
@ -525,6 +565,7 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() {
|
|||
}
|
||||
}
|
||||
}
|
||||
clearEdges();
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "--------------- voxel decompress ---------------";
|
||||
|
@ -628,7 +669,6 @@ void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
offH += 1.0f;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 p000 = glm::vec3(vtoM * glm::vec4(x + offL, y + offL, z + offL, 1.0f));
|
||||
glm::vec3 p001 = glm::vec3(vtoM * glm::vec4(x + offL, y + offL, z + offH, 1.0f));
|
||||
glm::vec3 p010 = glm::vec3(vtoM * glm::vec4(x + offL, y + offH, z + offL, 1.0f));
|
||||
|
@ -691,6 +731,8 @@ void RenderablePolyVoxEntityItem::setZTextureURL(QString zTextureURL) {
|
|||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::getModel() {
|
||||
auto startTime = usecTimestampNow();
|
||||
|
||||
// A mesh object to hold the result of surface extraction
|
||||
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
|
||||
|
||||
|
@ -745,6 +787,8 @@ void RenderablePolyVoxEntityItem::getModel() {
|
|||
#endif
|
||||
|
||||
_needsModelReload = false;
|
||||
|
||||
qDebug() << "RenderablePolyVoxEntityItem::getModel" << (usecTimestampNow() - startTime) << getName();
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
|
@ -871,3 +915,11 @@ glm::vec3 RenderablePolyVoxEntityItem::voxelCoordsToWorldCoords(glm::vec3 voxelC
|
|||
glm::vec3 RenderablePolyVoxEntityItem::worldCoordsToVoxelCoords(glm::vec3 worldCoords) {
|
||||
return glm::vec3(worldToVoxelMatrix() * glm::vec4(worldCoords, 1.0f));
|
||||
}
|
||||
|
||||
glm::vec3 RenderablePolyVoxEntityItem::voxelCoordsToLocalCoords(glm::vec3 voxelCoords) {
|
||||
return glm::vec3(voxelToLocalMatrix() * glm::vec4(voxelCoords, 1.0f));
|
||||
}
|
||||
|
||||
glm::vec3 RenderablePolyVoxEntityItem::localCoordsToVoxelCoords(glm::vec3 localCoords) {
|
||||
return glm::vec3(localToVoxelMatrix() * glm::vec4(localCoords, 1.0f));
|
||||
}
|
||||
|
|
|
@ -71,8 +71,9 @@ public:
|
|||
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
||||
glm::vec3 getSurfacePositionAdjustment() const;
|
||||
glm::mat4 voxelToWorldMatrix() const;
|
||||
glm::mat4 voxelToLocalMatrix() const;
|
||||
glm::mat4 worldToVoxelMatrix() const;
|
||||
glm::mat4 voxelToLocalMatrix() const;
|
||||
glm::mat4 localToVoxelMatrix() const;
|
||||
|
||||
virtual ShapeType getShapeType() const;
|
||||
virtual bool isReadyToComputeShape();
|
||||
|
@ -80,6 +81,8 @@ public:
|
|||
|
||||
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3 voxelCoords);
|
||||
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3 worldCoords);
|
||||
virtual glm::vec3 voxelCoordsToLocalCoords(glm::vec3 voxelCoords);
|
||||
virtual glm::vec3 localCoordsToVoxelCoords(glm::vec3 localCoords);
|
||||
|
||||
// coords are in voxel-volume space
|
||||
virtual bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue);
|
||||
|
@ -110,7 +113,7 @@ private:
|
|||
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
|
||||
void compressVolumeData();
|
||||
void decompressVolumeData();
|
||||
|
||||
void clearEdges();
|
||||
|
||||
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
||||
model::Geometry _modelGeometry;
|
||||
|
|
|
@ -697,3 +697,43 @@ glm::vec3 EntityScriptingInterface::worldCoordsToVoxelCoords(const QUuid& entity
|
|||
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
|
||||
return polyVoxEntity->worldCoordsToVoxelCoords(worldCoords);
|
||||
}
|
||||
|
||||
glm::vec3 EntityScriptingInterface::voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords) {
|
||||
if (!_entityTree) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "EntityScriptingInterface::voxelCoordsToLocalCoords no entity with ID" << entityID;
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
EntityTypes::EntityType entityType = entity->getType();
|
||||
if (entityType != EntityTypes::PolyVox) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
|
||||
return polyVoxEntity->voxelCoordsToLocalCoords(voxelCoords);
|
||||
}
|
||||
|
||||
glm::vec3 EntityScriptingInterface::localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords) {
|
||||
if (!_entityTree) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "EntityScriptingInterface::localCoordsToVoxelCoords no entity with ID" << entityID;
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
EntityTypes::EntityType entityType = entity->getType();
|
||||
if (entityType != EntityTypes::PolyVox) {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
|
||||
return polyVoxEntity->localCoordsToVoxelCoords(localCoords);
|
||||
}
|
||||
|
|
|
@ -136,6 +136,8 @@ public slots:
|
|||
|
||||
Q_INVOKABLE glm::vec3 voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords);
|
||||
Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords);
|
||||
Q_INVOKABLE glm::vec3 voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords);
|
||||
Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords);
|
||||
|
||||
signals:
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
|
|
@ -79,6 +79,8 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
|
||||
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3 voxelCoords) { return glm::vec3(0.0f); }
|
||||
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3 worldCoords) { return glm::vec3(0.0f); }
|
||||
virtual glm::vec3 voxelCoordsToLocalCoords(glm::vec3 voxelCoords) { return glm::vec3(0.0f); }
|
||||
virtual glm::vec3 localCoordsToVoxelCoords(glm::vec3 localCoords) { return glm::vec3(0.0f); }
|
||||
|
||||
// coords are in world-space
|
||||
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) { return false; }
|
||||
|
|
Loading…
Reference in a new issue