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