Merge pull request #5132 from sethalves/polyvox

Polyvox fixes
This commit is contained in:
Philip Rosedale 2015-06-17 10:49:35 -07:00
commit 8b8f0bcbde
6 changed files with 81 additions and 30 deletions

View file

@ -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 @@
<div class="poly-vox-section property">
<div class="label">Voxel Volume Size</div>
<div class="value">
<div class="input-area">X <br><input class="coord" type='number' id="property-voxel-volume-size-x"></input></div>
<div class="input-area">Y <br><input class="coord" type='number' id="property-voxel-volume-size-y"></input></div>
<div class="input-area">Z <br><input class="coord" type='number' id="property-voxel-volume-size-z"></input></div>
<div class="input-area">X <br> <input class="coord" type='number' id="property-voxel-volume-size-x"></input></div>
<div class="input-area">Y <br><input class="coord" type='number' id="property-voxel-volume-size-y"></input></div>
<div class="input-area">Z <br><input class="coord" type='number' id="property-voxel-volume-size-z"></input></div>
</div>
<div class="label">Surface Extractor</div>

View file

@ -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]);
}
}
}

View file

@ -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();

View file

@ -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;

View file

@ -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),

View file

@ -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