diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html
index f029088b1a..27a2929d1c 100644
--- a/examples/html/entityProperties.html
+++ b/examples/html/entityProperties.html
@@ -354,7 +354,8 @@
var elZoneAtmosphereScatteringWavelengthsZ = document.getElementById("property-zone-atmosphere-scattering-wavelengths-z");
var elZoneAtmosphereHasStars = document.getElementById("property-zone-atmosphere-has-stars");
- var elPolyVoxSelections = document.querySelectorAll(".poly-vox-section");
+ var elPolyVoxSections = document.querySelectorAll(".poly-vox-section");
+ allSections.push(elPolyVoxSections);
var elVoxelVolumeSizeX = document.getElementById("property-voxel-volume-size-x");
var elVoxelVolumeSizeY = document.getElementById("property-voxel-volume-size-y");
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
@@ -602,6 +603,10 @@
elParticleLocalGravity.value = properties.localGravity.toFixed(2);
elParticleRadius.value = properties.particleRadius.toFixed(3);
} else if (properties.type == "PolyVox") {
+ for (var i = 0; i < elPolyVoxSections.length; i++) {
+ elPolyVoxSections[i].style.display = 'block';
+ }
+
elVoxelVolumeSizeX.value = properties.voxelVolumeSize.x.toFixed(2);
elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2);
elVoxelVolumeSizeZ.value = properties.voxelVolumeSize.z.toFixed(2);
@@ -1014,9 +1019,9 @@
Voxel Volume Size
Surface Extractor
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
index bb5932d70c..71c3537a0c 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
@@ -121,7 +121,7 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize)
_volData->setBorderValue(255);
#ifdef WANT_DEBUG
- qDebug() << " new size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth();
+ qDebug() << " new voxel-space size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth();
#endif
// I'm not sure this is needed... the docs say that each element is initialized with its default
@@ -220,12 +220,15 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
return _volData->getVoxelAt(x, y, z);
}
-void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
+void RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t toValue) {
+ // set a voxel without recompressing the voxel data
assert(_volData);
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
return;
}
+ updateOnCount(x, y, z, toValue);
+
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) {
_volData->setVoxelAt(x + 1, y + 1, z + 1, toValue);
} else {
@@ -234,6 +237,14 @@ void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue)
}
+void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
+ if (_locked) {
+ return;
+ }
+ setVoxelInternal(x, y, z, toValue);
+ compressVolumeData();
+}
+
void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) {
// keep _onCount up to date
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
@@ -255,11 +266,15 @@ void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toV
}
void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
+ if (_locked) {
+ return;
+ }
+
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);
- setVoxel(x, y, z, toValue);
+ setVoxelInternal(x, y, z, toValue);
}
}
}
@@ -267,11 +282,19 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
}
void RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) {
- updateOnCount(position.x, position.y, position.z, toValue);
- setVoxel(position.x, position.y, position.z, toValue);
+ if (_locked) {
+ return;
+ }
+
+ // same as setVoxel but takes a vector rather than 3 floats.
+ setVoxel((int)position.x, (int)position.y, (int)position.z, toValue);
}
void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
+ if (_locked) {
+ return;
+ }
+
// This three-level for loop iterates over every voxel in the volume
for (int z = 0; z < _voxelVolumeSize.z; z++) {
for (int y = 0; y < _voxelVolumeSize.y; y++) {
@@ -283,7 +306,7 @@ void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radi
// If the current voxel is less than 'radius' units from the center then we make it solid.
if (fDistToCenter <= radius) {
updateOnCount(x, y, z, toValue);
- setVoxel(x, y, z, toValue);
+ setVoxelInternal(x, y, z, toValue);
}
}
}
@@ -380,10 +403,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
getModel();
}
- Transform transform;
- transform.setTranslation(getPosition() - getRegistrationPoint() * getDimensions());
- transform.setRotation(getRotation());
- transform.setScale(getDimensions() / _voxelVolumeSize);
+ Transform transform(voxelToWorldMatrix());
auto mesh = _modelGeometry.getMesh();
Q_ASSERT(args->_batch);
@@ -514,6 +534,11 @@ void RenderablePolyVoxEntityItem::compressVolumeData() {
QByteArray newVoxelData;
QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate);
+
+ #ifdef WANT_DEBUG
+ qDebug() << "compressing voxel data of size:" << voxelXSize << voxelYSize << voxelZSize;
+ #endif
+
writer << voxelXSize << voxelYSize << voxelZSize;
QByteArray compressedData = qCompress(uncompressedData, 9);
@@ -573,7 +598,7 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() {
for (int x = 0; x < voxelXSize; x++) {
int uncompressedIndex = (z * voxelYSize * voxelXSize) + (y * voxelZSize) + x;
updateOnCount(x, y, z, uncompressedData[uncompressedIndex]);
- setVoxel(x, y, z, uncompressedData[uncompressedIndex]);
+ setVoxelInternal(x, y, z, uncompressedData[uncompressedIndex]);
}
}
}
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
index 77aeb24f2a..814f3deb07 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h
@@ -73,11 +73,12 @@ public:
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
SIMPLE_RENDERABLE();
-
+
private:
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
// may not match _voxelVolumeSize.
+ void setVoxelInternal(int x, int y, int z, uint8_t toValue);
void compressVolumeData();
void decompressVolumeData();
diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp
index f64dad0ef4..d2881e5f3a 100644
--- a/libraries/entities/src/EntityItem.cpp
+++ b/libraries/entities/src/EntityItem.cpp
@@ -67,12 +67,12 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
_simulatorIDChangedTime(0),
_marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID),
_name(ENTITY_ITEM_DEFAULT_NAME),
+ _href(""),
+ _description(""),
_dirtyFlags(0),
_element(nullptr),
_physicsInfo(nullptr),
- _simulated(false),
- _href(""),
- _description("")
+ _simulated(false)
{
quint64 now = usecTimestampNow();
_lastSimulated = now;
diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp
index 95ab7d1035..84fbf11311 100644
--- a/libraries/entities/src/PolyVoxEntityItem.cpp
+++ b/libraries/entities/src/PolyVoxEntityItem.cpp
@@ -23,7 +23,7 @@
const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32);
const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 32.0f;
-const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(qCompress(QByteArray(0), 9)); // XXX
+const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(PolyVoxEntityItem::makeEmptyVoxelData());
const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE =
PolyVoxEntityItem::SURFACE_MARCHING_CUBES;
@@ -31,6 +31,25 @@ EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const
return EntityItemPointer(new PolyVoxEntityItem(entityID, properties));
}
+
+
+
+QByteArray PolyVoxEntityItem::makeEmptyVoxelData(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) {
+ int rawSize = voxelXSize * voxelYSize * voxelZSize;
+
+ QByteArray uncompressedData = QByteArray(rawSize, '\0');
+ QByteArray newVoxelData;
+ QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate);
+ writer << voxelXSize << voxelYSize << voxelZSize;
+
+ QByteArray compressedData = qCompress(uncompressedData, 9);
+ writer << compressedData;
+
+ return newVoxelData;
+}
+
+
+
PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
EntityItem(entityItemID),
_voxelVolumeSize(PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE),
diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h
index bf8214675b..e5d511c087 100644
--- a/libraries/entities/src/PolyVoxEntityItem.h
+++ b/libraries/entities/src/PolyVoxEntityItem.h
@@ -12,14 +12,14 @@
#ifndef hifi_PolyVoxEntityItem_h
#define hifi_PolyVoxEntityItem_h
-#include "EntityItem.h"
+#include "EntityItem.h"
class PolyVoxEntityItem : public EntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
-
+
ALLOW_INSTANTIATION // This class can be instantiated
// methods for getting/setting all properties of an entity
@@ -29,22 +29,22 @@ class PolyVoxEntityItem : public EntityItem {
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
- virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
+ virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
- int& propertyCount,
+ int& propertyCount,
OctreeElement::AppendState& appendState) const;
- virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
+ virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args,
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
-
+
// never have a ray intersection pick a PolyVoxEntityItem.
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,
+ bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking) const { return false; }
virtual void debugDump() const;
@@ -58,12 +58,12 @@ class PolyVoxEntityItem : public EntityItem {
enum PolyVoxSurfaceStyle {
SURFACE_MARCHING_CUBES,
SURFACE_CUBIC,
- SURFACE_EDGED_CUBIC
+ SURFACE_EDGED_CUBIC
};
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) { _voxelSurfaceStyle = voxelSurfaceStyle; }
virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) {
- setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle);
+ setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle);
}
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
@@ -82,10 +82,11 @@ class PolyVoxEntityItem : public EntityItem {
virtual void setAll(uint8_t toValue) {}
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue) {}
-
+
virtual uint8_t getVoxel(int x, int y, int z) { return 0; }
virtual void setVoxel(int x, int y, int z, uint8_t toValue) {}
+ static QByteArray makeEmptyVoxelData(quint16 voxelXSize = 16, quint16 voxelYSize = 16, quint16 voxelZSize = 16);
protected:
glm::vec3 _voxelVolumeSize; // this is always 3 bytes