diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html
index 8a15147f16..a2358b40d5 100644
--- a/examples/html/entityProperties.html
+++ b/examples/html/entityProperties.html
@@ -362,6 +362,9 @@
var elVoxelVolumeSizeY = document.getElementById("property-voxel-volume-size-y");
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
var elVoxelSurfaceStyle = document.getElementById("property-voxel-surface-style");
+ var elXTextureURL = document.getElementById("property-x-texture-url");
+ var elYTextureURL = document.getElementById("property-y-texture-url");
+ var elZTextureURL = document.getElementById("property-z-texture-url");
var elHyperlinkHref = document.getElementById("property-hyperlink-href");
var elHyperlinkDescription = document.getElementById("property-hyperlink-description");
@@ -614,6 +617,9 @@
elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2);
elVoxelVolumeSizeZ.value = properties.voxelVolumeSize.z.toFixed(2);
elVoxelSurfaceStyle.value = properties.voxelSurfaceStyle;
+ elXTextureURL.value = properties.xTextureURL;
+ elYTextureURL.value = properties.yTextureURL;
+ elZTextureURL.value = properties.zTextureURL;
}
if (selected) {
@@ -867,6 +873,9 @@
elVoxelVolumeSizeY.addEventListener('change', voxelVolumeSizeChangeFunction);
elVoxelVolumeSizeZ.addEventListener('change', voxelVolumeSizeChangeFunction);
elVoxelSurfaceStyle.addEventListener('change', createEmitTextPropertyUpdateFunction('voxelSurfaceStyle'));
+ elXTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('xTextureURL'));
+ elYTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('yTextureURL'));
+ elZTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('zTextureURL'));
elMoveSelectionToGrid.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
@@ -1063,7 +1072,22 @@
-
+
+
+
+
X-axis Texture URL
+
+
+
+
+ Y-axis Texture URL
+
+
+
+
+ Z-axis Texture URL
+
+
diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js
index 1b1a6a9c12..b386953c7c 100644
--- a/examples/libraries/entityPropertyDialogBox.js
+++ b/examples/libraries/entityPropertyDialogBox.js
@@ -98,8 +98,8 @@ EntityPropertyDialogBox = (function () {
index++;
}
- if (properties.type == "PolyVox") {
- array.push({ label: "Voxel Space Size:", type: "header" });
+ if (properties.type == "PolyVox") {
+ array.push({ label: "Voxel Space Size:", type: "header" });
index++;
array.push({ label: "X:", value: properties.voxelVolumeSize.x.toFixed(decimals) });
@@ -109,9 +109,16 @@ EntityPropertyDialogBox = (function () {
array.push({ label: "Z:", value: properties.voxelVolumeSize.z.toFixed(decimals) });
index++;
- array.push({ label: "Surface Extractor", value: properties.voxelSurfaceStyle });
- index++;
- }
+ array.push({ label: "Surface Extractor", value: properties.voxelSurfaceStyle });
+ index++;
+
+ array.push({ label: "X-axis Texture URL:", value: properties.xTextureURL });
+ index++;
+ array.push({ label: "Y-axis Texture URL:", value: properties.yTextureURL });
+ index++;
+ array.push({ label: "Z-axis Texture URL:", value: properties.zTextureURL });
+ index++;
+ }
array.push({ label: "Position:", type: "header" });
index++;
@@ -348,14 +355,17 @@ EntityPropertyDialogBox = (function () {
properties.backgroundColor.blue = array[index++].value;
}
- if (properties.type == "PolyVox") {
+ if (properties.type == "PolyVox") {
properties.shapeType = array[index++].value;
- index++; // skip header
- properties.voxelVolumeSize.x = array[index++].value;
- properties.voxelVolumeSize.y = array[index++].value;
- properties.voxelVolumeSize.z = array[index++].value;
- properties.voxelSurfaceStyle = array[index++].value;
+ index++; // skip header
+ properties.voxelVolumeSize.x = array[index++].value;
+ properties.voxelVolumeSize.y = array[index++].value;
+ properties.voxelVolumeSize.z = array[index++].value;
+ properties.voxelSurfaceStyle = array[index++].value;
+ properties.xTextureURL = array[index++].value;
+ properties.yTextureURL = array[index++].value;
+ properties.zTextureURL = array[index++].value;
}
index++; // skip header
diff --git a/examples/voxels.js b/examples/voxels.js
index e110f15260..9627b40701 100644
--- a/examples/voxels.js
+++ b/examples/voxels.js
@@ -44,7 +44,7 @@ function mousePressEvent(event) {
}
}
- // if the PolyVox entity is empty, we can't pick against its voxel. try picking against its
+ // if the PolyVox entity is empty, we can't pick against its "on" voxels. try picking against its
// bounding box, instead.
intersection = Entities.findRayIntersection(pickRay, false); // bounding box picking
if (intersection.intersects) {
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
index 681702bb07..2a41ea63fb 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -37,16 +38,22 @@
#include "model/Geometry.h"
#include "gpu/Context.h"
#include "EntityTreeRenderer.h"
+#include "polyvox_vert.h"
+#include "polyvox_frag.h"
#include "RenderablePolyVoxEntityItem.h"
+gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
+
EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return std::make_shared(entityID, properties);
}
RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& entityItemID,
const EntityItemProperties& properties) :
- PolyVoxEntityItem(entityItemID, properties) {
-
+ PolyVoxEntityItem(entityItemID, properties),
+ _xTexture(nullptr),
+ _yTexture(nullptr),
+ _zTexture(nullptr) {
model::Mesh* mesh = new model::Mesh();
model::MeshPointer meshPtr(mesh);
_modelGeometry.setMesh(meshPtr);
@@ -275,7 +282,6 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
for (int z = 0; z < _voxelVolumeSize.z; z++) {
for (int y = 0; y < _voxelVolumeSize.y; y++) {
for (int x = 0; x < _voxelVolumeSize.x; x++) {
- updateOnCount(x, y, z, toValue);
setVoxelInternal(x, y, z, toValue);
}
}
@@ -325,106 +331,6 @@ void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float r
setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
}
-void RenderablePolyVoxEntityItem::getModel() {
- // A mesh object to hold the result of surface extraction
- PolyVox::SurfaceMesh polyVoxMesh;
-
- switch (_voxelSurfaceStyle) {
- case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: {
- PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor
- (_volData, _volData->getEnclosingRegion(), &polyVoxMesh);
- surfaceExtractor.execute();
- break;
- }
- case PolyVoxEntityItem::SURFACE_EDGED_CUBIC:
- case PolyVoxEntityItem::SURFACE_CUBIC: {
- PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor
- (_volData, _volData->getEnclosingRegion(), &polyVoxMesh);
- surfaceExtractor.execute();
- break;
- }
- }
-
- // convert PolyVox mesh to a Sam mesh
- auto mesh = _modelGeometry.getMesh();
-
- const std::vector& vecIndices = polyVoxMesh.getIndices();
- auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t),
- (gpu::Byte*)vecIndices.data());
- auto indexBufferPtr = gpu::BufferPointer(indexBuffer);
- auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW));
- mesh->setIndexBuffer(*indexBufferView);
-
-
- const std::vector& vecVertices = polyVoxMesh.getVertices();
- auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal),
- (gpu::Byte*)vecVertices.data());
- auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
- auto vertexBufferView = new gpu::BufferView(vertexBufferPtr,
- 0,
- vertexBufferPtr->getSize() - sizeof(float) * 3,
- sizeof(PolyVox::PositionMaterialNormal),
- gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
- mesh->setVertexBuffer(*vertexBufferView);
- mesh->addAttribute(gpu::Stream::NORMAL,
- gpu::BufferView(vertexBufferPtr,
- sizeof(float) * 3,
- vertexBufferPtr->getSize() - sizeof(float) * 3,
- sizeof(PolyVox::PositionMaterialNormal),
- gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
-
-
-
- // auto normalAttrib = mesh->getAttributeBuffer(gpu::Stream::NORMAL);
- // for (auto normal = normalAttrib.begin(); normal != normalAttrib.end(); normal++) {
- // (*normal) = -(*normal);
- // }
-
-
- // mesh->addAttribute(gpu::Stream::TEXCOORD,
- // gpu::BufferView(vertexBufferPtr,
- // sizeof(float) * 2,
- // vertexBufferPtr->getSize() - sizeof(float) * 2,
- // sizeof(PolyVox::PositionMaterialNormal),
- // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
-
-
-
- #ifdef WANT_DEBUG
- qDebug() << "---- vecIndices.size() =" << vecIndices.size();
- qDebug() << "---- vecVertices.size() =" << vecVertices.size();
- #endif
-
- _needsModelReload = false;
-}
-
-void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
- PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
- assert(getType() == EntityTypes::PolyVox);
-
- if (_needsModelReload) {
- getModel();
- }
-
- Transform transform(voxelToWorldMatrix());
-
- auto mesh = _modelGeometry.getMesh();
- Q_ASSERT(args->_batch);
- gpu::Batch& batch = *args->_batch;
- DependencyManager::get()->bindSimpleProgram(batch);
- batch.setModelTransform(transform);
- batch.setInputFormat(mesh->getVertexFormat());
- batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer());
- batch.setInputBuffer(gpu::Stream::NORMAL,
- mesh->getVertexBuffer()._buffer,
- sizeof(float) * 3,
- mesh->getVertexBuffer()._stride);
- batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0);
- batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
-
- RenderableDebugableEntityItem::render(this, args);
-}
-
class RaycastFunctor
{
public:
@@ -709,3 +615,190 @@ void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
info.setParams(type, collisionModelDimensions, QString(b64));
info.setConvexHulls(_points);
}
+
+void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) {
+ PolyVoxEntityItem::setXTextureURL(xTextureURL);
+}
+
+void RenderablePolyVoxEntityItem::setYTextureURL(QString yTextureURL) {
+ PolyVoxEntityItem::setYTextureURL(yTextureURL);
+}
+
+void RenderablePolyVoxEntityItem::setZTextureURL(QString zTextureURL) {
+ PolyVoxEntityItem::setZTextureURL(zTextureURL);
+}
+
+void RenderablePolyVoxEntityItem::getModel() {
+ // A mesh object to hold the result of surface extraction
+ PolyVox::SurfaceMesh polyVoxMesh;
+
+ switch (_voxelSurfaceStyle) {
+ case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: {
+ PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor
+ (_volData, _volData->getEnclosingRegion(), &polyVoxMesh);
+ surfaceExtractor.execute();
+ break;
+ }
+ case PolyVoxEntityItem::SURFACE_EDGED_CUBIC:
+ case PolyVoxEntityItem::SURFACE_CUBIC: {
+ PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor
+ (_volData, _volData->getEnclosingRegion(), &polyVoxMesh);
+ surfaceExtractor.execute();
+ break;
+ }
+ }
+
+ // convert PolyVox mesh to a Sam mesh
+ auto mesh = _modelGeometry.getMesh();
+
+ const std::vector& vecIndices = polyVoxMesh.getIndices();
+ auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t),
+ (gpu::Byte*)vecIndices.data());
+ auto indexBufferPtr = gpu::BufferPointer(indexBuffer);
+ auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW));
+ mesh->setIndexBuffer(*indexBufferView);
+
+
+ const std::vector& vecVertices = polyVoxMesh.getVertices();
+ auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal),
+ (gpu::Byte*)vecVertices.data());
+ auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
+ auto vertexBufferView = new gpu::BufferView(vertexBufferPtr,
+ 0,
+ vertexBufferPtr->getSize() - sizeof(float) * 3,
+ sizeof(PolyVox::PositionMaterialNormal),
+ gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
+ mesh->setVertexBuffer(*vertexBufferView);
+ mesh->addAttribute(gpu::Stream::NORMAL,
+ gpu::BufferView(vertexBufferPtr,
+ sizeof(float) * 3,
+ vertexBufferPtr->getSize() - sizeof(float) * 3,
+ sizeof(PolyVox::PositionMaterialNormal),
+ gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
+
+ #ifdef WANT_DEBUG
+ qDebug() << "---- vecIndices.size() =" << vecIndices.size();
+ qDebug() << "---- vecVertices.size() =" << vecVertices.size();
+ #endif
+
+ _needsModelReload = false;
+}
+
+void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
+ PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
+ assert(getType() == EntityTypes::PolyVox);
+ Q_ASSERT(args->_batch);
+
+ if (!_pipeline) {
+ gpu::ShaderPointer vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(polyvox_vert)));
+ gpu::ShaderPointer pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(polyvox_frag)));
+
+ gpu::Shader::BindingSet slotBindings;
+ slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("xMap"), 0));
+ slotBindings.insert(gpu::Shader::Binding(std::string("yMap"), 1));
+ slotBindings.insert(gpu::Shader::Binding(std::string("zMap"), 2));
+
+ gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
+ gpu::Shader::makeProgram(*program, slotBindings);
+
+ auto state = std::make_shared();
+ state->setCullMode(gpu::State::CULL_BACK);
+ state->setDepthTest(true, true, gpu::LESS_EQUAL);
+
+ _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
+ }
+
+ if (_needsModelReload) {
+ getModel();
+ }
+
+ gpu::Batch& batch = *args->_batch;
+ batch.setPipeline(_pipeline);
+
+ auto mesh = _modelGeometry.getMesh();
+ Transform transform(voxelToWorldMatrix());
+ batch.setModelTransform(transform);
+ batch.setInputFormat(mesh->getVertexFormat());
+ batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer());
+ batch.setInputBuffer(gpu::Stream::NORMAL,
+ mesh->getVertexBuffer()._buffer,
+ sizeof(float) * 3,
+ mesh->getVertexBuffer()._stride);
+ batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0);
+
+ if (!_xTextureURL.isEmpty() && !_xTexture) {
+ _xTexture = DependencyManager::get()->getTexture(_xTextureURL);
+ }
+ if (!_yTextureURL.isEmpty() && !_yTexture) {
+ _yTexture = DependencyManager::get()->getTexture(_yTextureURL);
+ }
+ if (!_zTextureURL.isEmpty() && !_zTexture) {
+ _zTexture = DependencyManager::get()->getTexture(_zTextureURL);
+ }
+
+ batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ if (_xTexture) {
+ batch.setResourceTexture(0, _xTexture->getGPUTexture());
+ } else {
+ batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture());
+ }
+ if (_yTexture) {
+ batch.setResourceTexture(1, _yTexture->getGPUTexture());
+ } else {
+ batch.setResourceTexture(1, DependencyManager::get()->getWhiteTexture());
+ }
+ if (_zTexture) {
+ batch.setResourceTexture(2, _zTexture->getGPUTexture());
+ } else {
+ batch.setResourceTexture(2, DependencyManager::get()->getWhiteTexture());
+ }
+
+ int voxelVolumeSizeLocation = _pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
+ batch._glUniform3f(voxelVolumeSizeLocation, _voxelVolumeSize.x, _voxelVolumeSize.y, _voxelVolumeSize.z);
+
+ batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
+
+ RenderableDebugableEntityItem::render(this, args);
+}
+
+bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self,
+ std::shared_ptr scene,
+ render::PendingChanges& pendingChanges) {
+ _myItem = scene->allocateID();
+
+ auto renderItem = std::make_shared(shared_from_this());
+ auto renderData = PolyVoxPayload::Pointer(renderItem);
+ auto renderPayload = std::make_shared(renderData);
+
+ pendingChanges.resetItem(_myItem, renderPayload);
+
+ return true;
+}
+
+void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self,
+ std::shared_ptr scene,
+ render::PendingChanges& pendingChanges) {
+ pendingChanges.removeItem(_myItem);
+}
+
+namespace render {
+ template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload) {
+ return ItemKey::Builder::opaqueShape();
+ }
+
+ template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) {
+ if (payload && payload->_owner) {
+ auto polyVoxEntity = std::dynamic_pointer_cast(payload->_owner);
+ return polyVoxEntity->getAABox();
+ }
+ return render::Item::Bound();
+ }
+
+ template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args) {
+ if (args && payload && payload->_owner) {
+ payload->_owner->render(args);
+ }
+ }
+}
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
index 1097ad21be..d495900ce9 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
@@ -13,11 +13,30 @@
#define hifi_RenderablePolyVoxEntityItem_h
#include
+#include
#include "PolyVoxEntityItem.h"
#include "RenderableDebugableEntityItem.h"
#include "RenderableEntityItem.h"
+
+class PolyVoxPayload {
+public:
+ PolyVoxPayload(EntityItemPointer owner) : _owner(owner), _bounds(AABox()) { }
+ typedef render::Payload Payload;
+ typedef Payload::DataPointer Pointer;
+
+ EntityItemPointer _owner;
+ AABox _bounds;
+};
+
+namespace render {
+ template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload);
+ template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload);
+ template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args);
+}
+
+
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
@@ -70,7 +89,16 @@ public:
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
- SIMPLE_RENDERABLE();
+ virtual void setXTextureURL(QString xTextureURL);
+ virtual void setYTextureURL(QString yTextureURL);
+ virtual void setZTextureURL(QString zTextureURL);
+
+ virtual bool addToScene(EntityItemPointer self,
+ std::shared_ptr scene,
+ render::PendingChanges& pendingChanges);
+ virtual void removeFromScene(EntityItemPointer self,
+ std::shared_ptr scene,
+ render::PendingChanges& pendingChanges);
protected:
virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
@@ -90,7 +118,15 @@ private:
QVector> _points; // XXX
+ NetworkTexturePointer _xTexture;
+ NetworkTexturePointer _yTexture;
+ NetworkTexturePointer _zTexture;
+
int _onCount = 0; // how many non-zero voxels are in _volData
+
+ const int MATERIAL_GPU_SLOT = 3;
+ render::ItemID _myItem;
+ static gpu::PipelinePointer _pipeline;
};
diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf
new file mode 100644
index 0000000000..e5c8a49133
--- /dev/null
+++ b/libraries/entities-renderer/src/polyvox.slf
@@ -0,0 +1,54 @@
+<@include gpu/Config.slh@>
+<$VERSION_HEADER$>
+// Generated on <$_SCRIBE_DATE$>
+// model.frag
+// fragment shader
+//
+// Created by Seth Alves on 2015-8-3
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+<@include gpu/Inputs.slh@>
+
+layout(location = 0) out vec4 _fragColor0;
+layout(location = 1) out vec4 _fragColor1;
+layout(location = 2) out vec4 _fragColor2;
+
+<@include model/Material.slh@>
+
+in vec3 _normal;
+in vec4 _position;
+in vec4 _inPosition;
+
+uniform sampler2D xMap;
+uniform sampler2D yMap;
+uniform sampler2D zMap;
+uniform vec3 voxelVolumeSize;
+
+void main(void) {
+ vec3 worldNormal = cross(dFdy(_inPosition.xyz), dFdx(_inPosition.xyz));
+ worldNormal = normalize(worldNormal);
+
+ float inPositionX = (_inPosition.x - 0.5) / voxelVolumeSize.x;
+ float inPositionY = (_inPosition.y - 0.5) / voxelVolumeSize.y;
+ float inPositionZ = (_inPosition.z - 0.5) / voxelVolumeSize.z;
+
+ vec4 xyDiffuse = texture2D(xMap, vec2(-inPositionX, -inPositionY));
+ vec4 xzDiffuse = texture2D(yMap, vec2(-inPositionX, inPositionZ));
+ vec4 yzDiffuse = texture2D(zMap, vec2(inPositionZ, -inPositionY));
+
+ vec3 xyDiffuseScaled = xyDiffuse.rgb * abs(worldNormal.z);
+ vec3 xzDiffuseScaled = xzDiffuse.rgb * abs(worldNormal.y);
+ vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x);
+
+ vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0);
+
+ Material mat = getMaterial();
+
+ _fragColor0 = vec4(diffuse.rgb, 0.0);
+ _fragColor1 = vec4(_normal, 1.0);
+ _fragColor2 = vec4(getMaterialSpecular(mat), getMaterialShininess(mat) / 128.0);
+}
diff --git a/libraries/entities-renderer/src/polyvox.slv b/libraries/entities-renderer/src/polyvox.slv
new file mode 100644
index 0000000000..0074993c80
--- /dev/null
+++ b/libraries/entities-renderer/src/polyvox.slv
@@ -0,0 +1,30 @@
+<@include gpu/Config.slh@>
+<$VERSION_HEADER$>
+// Generated on <$_SCRIBE_DATE$>
+// polyvox.vert
+// vertex shader
+//
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+<@include gpu/Inputs.slh@>
+
+<@include gpu/Transform.slh@>
+
+<$declareStandardTransform()$>
+
+out vec4 _position;
+out vec4 _inPosition;
+out vec3 _normal;
+
+void main(void) {
+ // standard transform
+ TransformCamera cam = getTransformCamera();
+ TransformObject obj = getTransformObject();
+ <$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
+ <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
+ _inPosition = inPosition;
+}
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index 4e7228e573..698df8c669 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -102,6 +102,9 @@ CONSTRUCT_PROPERTY(lineWidth, LineEntityItem::DEFAULT_LINE_WIDTH),
CONSTRUCT_PROPERTY(linePoints, QVector()),
CONSTRUCT_PROPERTY(faceCamera, TextEntityItem::DEFAULT_FACE_CAMERA),
CONSTRUCT_PROPERTY(actionData, QByteArray()),
+CONSTRUCT_PROPERTY(xTextureURL, ""),
+CONSTRUCT_PROPERTY(yTextureURL, ""),
+CONSTRUCT_PROPERTY(zTextureURL, ""),
_id(UNKNOWN_ENTITY_ID),
_idSet(false),
@@ -364,6 +367,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
+ CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
+ CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
+ CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
changedProperties += _stage.getChangedProperties();
changedProperties += _atmosphere.getChangedProperties();
@@ -501,6 +507,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
_atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
_skybox.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(xTextureURL);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(yTextureURL);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(zTextureURL);
+
return properties;
}
@@ -591,6 +601,12 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
_stage.copyFromScriptValue(object, _defaultSettings);
_atmosphere.copyFromScriptValue(object, _defaultSettings);
_skybox.copyFromScriptValue(object, _defaultSettings);
+
+
+ COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
+ COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
+ COPY_PROPERTY_FROM_QSCRIPTVALUE(zTextureURL, QString, setZTextureURL);
+
_lastEdited = usecTimestampNow();
}
@@ -818,6 +834,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
APPEND_ENTITY_PROPERTY(PROP_VOXEL_VOLUME_SIZE, properties.getVoxelVolumeSize());
APPEND_ENTITY_PROPERTY(PROP_VOXEL_DATA, properties.getVoxelData());
APPEND_ENTITY_PROPERTY(PROP_VOXEL_SURFACE_STYLE, properties.getVoxelSurfaceStyle());
+ APPEND_ENTITY_PROPERTY(PROP_X_TEXTURE_URL, properties.getXTextureURL());
+ APPEND_ENTITY_PROPERTY(PROP_Y_TEXTURE_URL, properties.getYTextureURL());
+ APPEND_ENTITY_PROPERTY(PROP_Z_TEXTURE_URL, properties.getZTextureURL());
}
if (properties.getType() == EntityTypes::Line) {
@@ -1069,6 +1088,9 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_DATA, QByteArray, setVoxelData);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_SURFACE_STYLE, uint16_t, setVoxelSurfaceStyle);
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_X_TEXTURE_URL, QString, setXTextureURL);
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Y_TEXTURE_URL, QString, setYTextureURL);
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Z_TEXTURE_URL, QString, setZTextureURL);
}
if (properties.getType() == EntityTypes::Line) {
@@ -1193,6 +1215,10 @@ void EntityItemProperties::markAllChanged() {
_descriptionChanged = true;
_faceCameraChanged = true;
_actionDataChanged = true;
+
+ _xTextureURLChanged = true;
+ _yTextureURLChanged = true;
+ _zTextureURLChanged = true;
}
/// The maximum bounding cube for the entity, independent of it's rotation.
diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h
index 3ce6040d19..423aefd44a 100644
--- a/libraries/entities/src/EntityItemProperties.h
+++ b/libraries/entities/src/EntityItemProperties.h
@@ -154,6 +154,9 @@ public:
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
+ DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
+ DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
+ DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
static QString getBackgroundModeString(BackgroundMode mode);
@@ -317,6 +320,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Href, href, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Description, description, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ActionData, actionData, "");
+ DEBUG_PROPERTY_IF_CHANGED(debug, properties, XTextureURL, xTextureURL, "");
+ DEBUG_PROPERTY_IF_CHANGED(debug, properties, YTextureURL, yTextureURL, "");
+ DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZTextureURL, zTextureURL, "");
properties.getStage().debugDump();
properties.getAtmosphere().debugDump();
diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h
index be16683f39..c23c45fabf 100644
--- a/libraries/entities/src/EntityPropertyFlags.h
+++ b/libraries/entities/src/EntityPropertyFlags.h
@@ -126,6 +126,10 @@ enum EntityPropertyList {
PROP_SCRIPT_TIMESTAMP,
PROP_ACTION_DATA,
+ PROP_X_TEXTURE_URL, // used by PolyVox
+ PROP_Y_TEXTURE_URL, // used by PolyVox
+ PROP_Z_TEXTURE_URL, // used by PolyVox
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line
PROP_AFTER_LAST_ITEM,
diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp
index 048017de1c..c9f3705712 100644
--- a/libraries/entities/src/PolyVoxEntityItem.cpp
+++ b/libraries/entities/src/PolyVoxEntityItem.cpp
@@ -26,6 +26,9 @@ const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 32.0f;
const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(PolyVoxEntityItem::makeEmptyVoxelData());
const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE =
PolyVoxEntityItem::SURFACE_MARCHING_CUBES;
+const QString PolyVoxEntityItem::DEFAULT_X_TEXTURE_URL = QString("");
+const QString PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL = QString("");
+const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString("");
EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return std::make_shared(entityID, properties);
@@ -49,7 +52,10 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const Ent
EntityItem(entityItemID),
_voxelVolumeSize(PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE),
_voxelData(PolyVoxEntityItem::DEFAULT_VOXEL_DATA),
- _voxelSurfaceStyle(PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE)
+ _voxelSurfaceStyle(PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE),
+ _xTextureURL(PolyVoxEntityItem::DEFAULT_X_TEXTURE_URL),
+ _yTextureURL(PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL),
+ _zTextureURL(PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL)
{
_type = EntityTypes::PolyVox;
setProperties(properties);
@@ -94,6 +100,9 @@ EntityItemProperties PolyVoxEntityItem::getProperties() const {
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelData, getVoxelData);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelSurfaceStyle, getVoxelSurfaceStyle);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(xTextureURL, getXTextureURL);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(yTextureURL, getYTextureURL);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(zTextureURL, getZTextureURL);
return properties;
}
@@ -103,6 +112,9 @@ bool PolyVoxEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(voxelVolumeSize, setVoxelVolumeSize);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(voxelData, setVoxelData);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(voxelSurfaceStyle, setVoxelSurfaceStyle);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(xTextureURL, setXTextureURL);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(yTextureURL, setYTextureURL);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(zTextureURL, setZTextureURL);
if (somethingChanged) {
bool wantDebug = false;
@@ -127,6 +139,9 @@ int PolyVoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* dat
READ_ENTITY_PROPERTY(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
READ_ENTITY_PROPERTY(PROP_VOXEL_DATA, QByteArray, setVoxelData);
READ_ENTITY_PROPERTY(PROP_VOXEL_SURFACE_STYLE, uint16_t, setVoxelSurfaceStyle);
+ READ_ENTITY_PROPERTY(PROP_X_TEXTURE_URL, QString, setXTextureURL);
+ READ_ENTITY_PROPERTY(PROP_Y_TEXTURE_URL, QString, setYTextureURL);
+ READ_ENTITY_PROPERTY(PROP_Z_TEXTURE_URL, QString, setZTextureURL);
return bytesRead;
}
@@ -138,6 +153,9 @@ EntityPropertyFlags PolyVoxEntityItem::getEntityProperties(EncodeBitstreamParams
requestedProperties += PROP_VOXEL_VOLUME_SIZE;
requestedProperties += PROP_VOXEL_DATA;
requestedProperties += PROP_VOXEL_SURFACE_STYLE;
+ requestedProperties += PROP_X_TEXTURE_URL;
+ requestedProperties += PROP_Y_TEXTURE_URL;
+ requestedProperties += PROP_Z_TEXTURE_URL;
return requestedProperties;
}
@@ -153,6 +171,10 @@ void PolyVoxEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeB
APPEND_ENTITY_PROPERTY(PROP_VOXEL_VOLUME_SIZE, getVoxelVolumeSize());
APPEND_ENTITY_PROPERTY(PROP_VOXEL_DATA, getVoxelData());
APPEND_ENTITY_PROPERTY(PROP_VOXEL_SURFACE_STYLE, (uint16_t) getVoxelSurfaceStyle());
+ APPEND_ENTITY_PROPERTY(PROP_X_TEXTURE_URL, getXTextureURL());
+ APPEND_ENTITY_PROPERTY(PROP_Y_TEXTURE_URL, getYTextureURL());
+ APPEND_ENTITY_PROPERTY(PROP_Z_TEXTURE_URL, getZTextureURL());
+
}
void PolyVoxEntityItem::debugDump() const {
diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h
index 9e20187195..0d0ab060f9 100644
--- a/libraries/entities/src/PolyVoxEntityItem.h
+++ b/libraries/entities/src/PolyVoxEntityItem.h
@@ -87,6 +87,18 @@ class PolyVoxEntityItem : public EntityItem {
static QByteArray makeEmptyVoxelData(quint16 voxelXSize = 16, quint16 voxelYSize = 16, quint16 voxelZSize = 16);
+ static const QString DEFAULT_X_TEXTURE_URL;
+ virtual void setXTextureURL(QString xTextureURL) { _xTextureURL = xTextureURL; }
+ virtual const QString& getXTextureURL() const { return _xTextureURL; }
+
+ static const QString DEFAULT_Y_TEXTURE_URL;
+ virtual void setYTextureURL(QString yTextureURL) { _yTextureURL = yTextureURL; }
+ virtual const QString& getYTextureURL() const { return _yTextureURL; }
+
+ static const QString DEFAULT_Z_TEXTURE_URL;
+ virtual void setZTextureURL(QString zTextureURL) { _zTextureURL = zTextureURL; }
+ virtual const QString& getZTextureURL() const { return _zTextureURL; }
+
protected:
virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
_voxelSurfaceStyle = voxelSurfaceStyle;
@@ -95,6 +107,11 @@ class PolyVoxEntityItem : public EntityItem {
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
QByteArray _voxelData;
PolyVoxSurfaceStyle _voxelSurfaceStyle;
+
+ QString _xTextureURL;
+ QString _yTextureURL;
+ QString _zTextureURL;
+
};
#endif // hifi_PolyVoxEntityItem_h
diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp
index f3f222f310..a4e9b5f799 100644
--- a/libraries/networking/src/udt/PacketHeaders.cpp
+++ b/libraries/networking/src/udt/PacketHeaders.cpp
@@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
case EntityAdd:
case EntityEdit:
case EntityData:
- return VERSION_ENTITIES_NEW_PROTOCOL_LAYER;
+ return VERSION_POLYVOX_TEXTURES;
default:
return 11;
}
diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h
index 46f834db74..96f097a4b2 100644
--- a/libraries/networking/src/udt/PacketHeaders.h
+++ b/libraries/networking/src/udt/PacketHeaders.h
@@ -140,5 +140,6 @@ const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP = 31;
const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32;
const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33;
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
+const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
#endif // hifi_PacketHeaders_h