mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 13:47:23 +02:00
hook up RenderablePolyVoxEntityItem::findDetailedRayIntersection to polyvox library's version
This commit is contained in:
parent
9735174036
commit
727f457f91
3 changed files with 125 additions and 31 deletions
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
|
@ -21,6 +22,8 @@
|
|||
#include <PolyVoxCore/MarchingCubesSurfaceExtractor.h>
|
||||
#include <PolyVoxCore/SurfaceMesh.h>
|
||||
#include <PolyVoxCore/SimpleVolume.h>
|
||||
#include <PolyVoxCore/Raycast.h>
|
||||
#include <PolyVoxCore/Material.h>
|
||||
|
||||
#include "model/Geometry.h"
|
||||
#include "gpu/GLBackend.h"
|
||||
|
@ -50,22 +53,19 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize)
|
|||
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
||||
}
|
||||
|
||||
glm::vec3 RenderablePolyVoxEntityItem::metersToVoxelCoordinates(glm::vec3 metersOffCenter) {
|
||||
// convert a vector from the center of the entity with units of meters to a vector with units
|
||||
// of index-into-volData.
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 scale = dimensions / _voxelVolumeSize; // meters / voxel-units
|
||||
glm::vec3 voxelCoords = metersOffCenter / scale;
|
||||
// the voxel volume is entirely in positive space, but the voxel space is centered at the entity's coords, so:
|
||||
return voxelCoords + _voxelVolumeSize / 2.0f;
|
||||
glm::mat4 RenderablePolyVoxEntityItem::voxelToWorldMatrix() const {
|
||||
glm::vec3 scale = _dimensions / _voxelVolumeSize; // meters / voxel-units
|
||||
glm::mat4 scaled = glm::scale(glm::mat4(), scale);
|
||||
glm::mat4 centerToCorner = glm::translate(scaled, _voxelVolumeSize / -2.0f);
|
||||
glm::mat4 rotation = glm::mat4_cast(_rotation);
|
||||
glm::mat4 translation = glm::translate(getCenter());
|
||||
return translation * rotation * centerToCorner;
|
||||
}
|
||||
|
||||
glm::vec3 RenderablePolyVoxEntityItem::voxelCoordinatesToMeters(glm::vec3 voxelCoords) {
|
||||
// convert a vector is voxel-space to an offset from the entity-center in meters
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 scale = dimensions / _voxelVolumeSize; // meters / voxel-units
|
||||
glm::vec3 centeredCoords = voxelCoords - _voxelVolumeSize / 2.0f;
|
||||
return centeredCoords * scale;
|
||||
glm::mat4 RenderablePolyVoxEntityItem::worldToVoxelMatrix() const {
|
||||
glm::mat4 worldToModelMatrix = glm::inverse(voxelToWorldMatrix());
|
||||
return worldToModelMatrix;
|
||||
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
|
||||
|
@ -91,13 +91,29 @@ void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radi
|
|||
}
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::createSphereInVolume(glm::vec3 center, float radius) {
|
||||
setSphereInVolume(center, radius, 255);
|
||||
void RenderablePolyVoxEntityItem::createSphereInVolume(glm::vec3 centerVoxelCoords, float radiusVoxelCoords) {
|
||||
setSphereInVolume(centerVoxelCoords, radiusVoxelCoords, 255);
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::eraseSphereInVolume(glm::vec3 centerVoxelCoords, float radiusVoxelCoords) {
|
||||
setSphereInVolume(centerVoxelCoords, radiusVoxelCoords, 0);
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::eraseSphereInVolume(glm::vec3 center, float radius) {
|
||||
setSphereInVolume(center, radius, 0);
|
||||
void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords, uint8_t toValue) {
|
||||
// glm::vec3 centerVoxelCoords = worldToVoxelCoordinates(centerWorldCoords);
|
||||
glm::vec4 centerVoxelCoords = worldToVoxelMatrix() * glm::vec4(centerWorldCoords, 1.0f);
|
||||
glm::vec3 scale = _dimensions / _voxelVolumeSize; // meters / voxel-units
|
||||
float scaleY = scale[0];
|
||||
float radiusVoxelCoords = radiusWorldCoords / scaleY;
|
||||
setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::createSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords) {
|
||||
setSphere(centerWorldCoords, radiusWorldCoords, 255);
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::eraseSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords) {
|
||||
setSphere(centerWorldCoords, radiusWorldCoords, 0);
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::getModel() {
|
||||
|
@ -106,12 +122,19 @@ void RenderablePolyVoxEntityItem::getModel() {
|
|||
setVoxelVolumeSize(_voxelVolumeSize);
|
||||
}
|
||||
|
||||
glm::vec3 center(_volData->getDepth() / 2.0f,
|
||||
_volData->getHeight() / 2.0f,
|
||||
_volData->getWidth() / 2.0f);
|
||||
createSphereInVolume(center, 15);
|
||||
createSphereInVolume(center + glm::vec3(8.0f, 0.0f, 0.0f), 15);
|
||||
eraseSphereInVolume(center + glm::vec3(4.0f, 0.0f, 4.0f), 15);
|
||||
// glm::vec3 center(_volData->getDepth() / 2.0f,
|
||||
// _volData->getHeight() / 2.0f,
|
||||
// _volData->getWidth() / 2.0f);
|
||||
// createSphereInVolume(center, 15);
|
||||
// createSphereInVolume(center + glm::vec3(8.0f, 0.0f, 0.0f), 15);
|
||||
// eraseSphereInVolume(center + glm::vec3(4.0f, 0.0f, 4.0f), 15);
|
||||
|
||||
|
||||
glm::vec3 center = getCenter();
|
||||
createSphere(center, 4);
|
||||
createSphere(center + glm::vec3(6.0f, 0.0f, 0.0f), 2);
|
||||
// eraseSphere(center + glm::vec3(0.5f, 0.0f, 4.0f), 0.8);
|
||||
|
||||
|
||||
// A mesh object to hold the result of surface extraction
|
||||
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
|
||||
|
@ -153,7 +176,7 @@ void RenderablePolyVoxEntityItem::getModel() {
|
|||
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
|
||||
|
||||
|
||||
qDebug() << "-------------XXXXXXXXXXXXXXXXXXXX-------------------";
|
||||
qDebug() << "-------------XXXXXXXXXXXXXXXXXXXX-------------------" << usecTimestampNow();
|
||||
qDebug() << "---- vecIndices.size() =" << vecIndices.size();
|
||||
qDebug() << "---- sizeof(vecIndices[0]) =" << sizeof(vecIndices[0]);
|
||||
qDebug() << "---- vecVertices.size() =" << vecVertices.size();
|
||||
|
@ -175,8 +198,6 @@ void RenderablePolyVoxEntityItem::getModel() {
|
|||
_needsModelReload = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::PolyVox);
|
||||
|
@ -214,3 +235,60 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
glPopMatrix();
|
||||
RenderableDebugableEntityItem::render(this, args);
|
||||
}
|
||||
|
||||
class RaycastFunctor
|
||||
{
|
||||
public:
|
||||
RaycastFunctor() : _result(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) { }
|
||||
bool operator()(PolyVox::SimpleVolume<unsigned char>::Sampler& sampler)
|
||||
{
|
||||
if (sampler.getVoxel() == 0) {
|
||||
return true; // keep raycasting
|
||||
}
|
||||
PolyVox::Vector3DInt32 positionIndex = sampler.getPosition();
|
||||
_result = glm::vec4(positionIndex.getX(), positionIndex.getY(), positionIndex.getZ(), 1.0f);
|
||||
return false;
|
||||
}
|
||||
glm::vec4 _result;
|
||||
};
|
||||
|
||||
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin,
|
||||
const glm::vec3& direction,
|
||||
bool& keepSearching,
|
||||
OctreeElement*& element,
|
||||
float& distance, BoxFace& face,
|
||||
void** intersectedObject,
|
||||
bool precisionPicking) const
|
||||
{
|
||||
if (_needsModelReload || !precisionPicking) {
|
||||
// just intersect with bounding box
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
||||
glm::vec3 far = origin + direction;
|
||||
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
||||
glm::vec4 farInVoxel = wtvMatrix * glm::vec4(far, 1.0f);
|
||||
glm::vec4 directionInVoxel = farInVoxel - originInVoxel;
|
||||
|
||||
PolyVox::Vector3DFloat start(originInVoxel[0], originInVoxel[1], originInVoxel[2]);
|
||||
PolyVox::Vector3DFloat pvDirection(directionInVoxel[0], directionInVoxel[1], directionInVoxel[2]);
|
||||
pvDirection.normalise();
|
||||
// pvDirection *= 1000.0f; // Casts ray of length 1000
|
||||
pvDirection *= 64.0f; // Casts ray of length 1000
|
||||
|
||||
PolyVox::RaycastResult raycastResult;
|
||||
RaycastFunctor callback;
|
||||
raycastResult = PolyVox::raycastWithDirection(_volData, start, pvDirection, callback);
|
||||
|
||||
if (raycastResult == PolyVox::RaycastResults::Completed) // the ray completed its path -- nothing was hit.
|
||||
return false;
|
||||
|
||||
glm::vec4 intersectedWorldPosition = voxelToWorldMatrix() * callback._result;
|
||||
|
||||
distance = glm::distance(glm::vec3(intersectedWorldPosition), origin);
|
||||
|
||||
face = BoxFace::MIN_X_FACE; // XXX
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,30 @@ public:
|
|||
|
||||
virtual ~RenderablePolyVoxEntityItem();
|
||||
|
||||
virtual void somethingChangedNotification() {
|
||||
// This gets called from EnityItem::readEntityDataFromBuffer every time a packet describing
|
||||
// this entity comes from the entity-server. It gets called even if nothing has actually changed
|
||||
// (see the comment in EntityItem.cpp). If that gets fixed, this could be used to know if we
|
||||
// need to redo the voxel data.
|
||||
// _needsModelReload = true;
|
||||
}
|
||||
|
||||
|
||||
void render(RenderArgs* args);
|
||||
virtual bool hasModel() const { return true; }
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking) const;
|
||||
|
||||
void getModel();
|
||||
|
||||
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
|
||||
glm::mat4 voxelToWorldMatrix() const;
|
||||
glm::mat4 worldToVoxelMatrix() const;
|
||||
|
||||
glm::vec3 metersToVoxelCoordinates(glm::vec3 metersOffCenter);
|
||||
glm::vec3 voxelCoordinatesToMeters(glm::vec3 voxelCoords);
|
||||
void setSphere(glm::vec3 center, float radius, uint8_t toValue);
|
||||
void createSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords);
|
||||
void eraseSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords);
|
||||
|
||||
void setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue);
|
||||
void createSphereInVolume(glm::vec3 center, float radius);
|
||||
|
|
|
@ -613,7 +613,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
// we want to extrapolate the motion forward to compensate for packet travel time, but
|
||||
// we don't want the side effect of flag setting.
|
||||
// simulateKinematicMotion(skipTimeForward, false);
|
||||
simulateKinematicMotion(skipTimeForward, false);
|
||||
}
|
||||
_lastSimulated = now;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue