//// PolyVoxEntityItem.cpp// libraries/entities/src//// Created by Seth Alves on 5/11/15.// 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 "PolyVoxEntityItem.h" #include <glm/gtx/transform.hpp> #include <QByteArray>#include <QDebug>#include <QWriteLocker> #include <ByteCountCoding.h> #include "EntitiesLogging.h"#include "EntityItemProperties.h"#include "EntityTree.h"#include "EntityTreeElement.h" bool PolyVoxEntityItem::isEdged(PolyVoxSurfaceStyle surfaceStyle) { switch (surfaceStyle) { case PolyVoxEntityItem::SURFACE_CUBIC: case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: return false; case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES: return true; } return false;} const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32);const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 128.0f;const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(PolyVoxEntityItem::makeEmptyVoxelData());const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE = PolyVoxEntityItem::SURFACE_EDGED_CUBIC;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) { std::shared_ptr<PolyVoxEntityItem> entity(new PolyVoxEntityItem(entityID), [](PolyVoxEntityItem* ptr) { ptr->deleteLater(); }); entity->setProperties(properties); return entity;} 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) : EntityItem(entityItemID) { _type = EntityTypes::PolyVox;} void PolyVoxEntityItem::setVoxelVolumeSize(const glm::vec3& voxelVolumeSize_) { auto voxelVolumeSize = glm::clamp(glm::round(voxelVolumeSize_), glm::vec3(1.0f), glm::vec3(MAX_VOXEL_DIMENSION)); withWriteLock([&] { _needsRenderUpdate |= _voxelVolumeSize != voxelVolumeSize; _voxelVolumeSize = voxelVolumeSize; });} glm::vec3 PolyVoxEntityItem::getVoxelVolumeSize() const { return resultWithReadLock<glm::vec3>([&] { return _voxelVolumeSize; });} EntityItemProperties PolyVoxEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class @PolyVox_ENTITY_COPY_TO@ return properties;} bool PolyVoxEntityItem::setSubClassProperties(const EntityItemProperties& properties) { bool somethingChanged = false; @PolyVox_ENTITY_SET_FROM@ return somethingChanged;} EntityPropertyFlags PolyVoxEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); @PolyVox_REQUESTED_PROPS@ return requestedProperties;} void PolyVoxEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, int& propertyCount, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; @PolyVox_ENTITY_APPEND@ } int PolyVoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; @PolyVox_ENTITY_READ@ return bytesRead;} void PolyVoxEntityItem::debugDump() const { qCDebug(entities) << "PolyVoxEntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " name:" << _name; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " editedAgo:" << debugTime(getLastEdited(), usecTimestampNow()); qCDebug(entities) << " pointer:" << this; @PolyVox_ENTITY_DEBUG@ } void PolyVoxEntityItem::setVoxelData(const QByteArray& voxelData) { withWriteLock([&] { _voxelData = voxelData; _voxelDataDirty = true; });} QByteArray PolyVoxEntityItem::getVoxelData() const { return resultWithReadLock<QByteArray>([&] { return _voxelData; });} void PolyVoxEntityItem::setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) { withWriteLock([&] { _voxelSurfaceStyle = voxelSurfaceStyle; });} uint16_t PolyVoxEntityItem::getVoxelSurfaceStyle() const { return resultWithReadLock<uint16_t>([&] { return _voxelSurfaceStyle; });} void PolyVoxEntityItem::setXNNeighborID(const EntityItemID& xNNeighborID) { withWriteLock([&] { _xNNeighborID = xNNeighborID; });} EntityItemID PolyVoxEntityItem::getXNNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _xNNeighborID; });} void PolyVoxEntityItem::setYNNeighborID(const EntityItemID& yNNeighborID) { withWriteLock([&] { _yNNeighborID = yNNeighborID; });} EntityItemID PolyVoxEntityItem::getYNNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _yNNeighborID; });} void PolyVoxEntityItem::setZNNeighborID(const EntityItemID& zNNeighborID) { withWriteLock([&] { _zNNeighborID = zNNeighborID; });} EntityItemID PolyVoxEntityItem::getZNNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _zNNeighborID; });} void PolyVoxEntityItem::setXPNeighborID(const EntityItemID& xPNeighborID) { withWriteLock([&] { _xPNeighborID = xPNeighborID; });} EntityItemID PolyVoxEntityItem::getXPNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _xPNeighborID; });} void PolyVoxEntityItem::setYPNeighborID(const EntityItemID& yPNeighborID) { withWriteLock([&] { _yPNeighborID = yPNeighborID; });} EntityItemID PolyVoxEntityItem::getYPNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _yPNeighborID; });} void PolyVoxEntityItem::setZPNeighborID(const EntityItemID& zPNeighborID) { withWriteLock([&] { _zPNeighborID = zPNeighborID; });} EntityItemID PolyVoxEntityItem::getZPNeighborID() const { return resultWithReadLock<EntityItemID>([&] { return _zPNeighborID; });} glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::vec3 result; withReadLock([&] { glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units if (isEdged()) { result = scale / -2.0f; } return scale / 2.0f; }); return result;} glm::mat4 PolyVoxEntityItem::voxelToLocalMatrix() const { glm::vec3 voxelVolumeSize; withReadLock([&] { voxelVolumeSize = _voxelVolumeSize; }); glm::vec3 dimensions = getScaledDimensions(); glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units bool success; // TODO -- Does this actually have to happen in world space? glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes glm::vec3 position = getWorldPosition(success); glm::vec3 positionToCenter = center - position; positionToCenter -= dimensions * Vectors::HALF - getSurfacePositionAdjustment(); glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter); glm::mat4 scaled = glm::scale(centerToCorner, scale); return scaled;} glm::mat4 PolyVoxEntityItem::localToVoxelMatrix() const { glm::mat4 localToModelMatrix = glm::inverse(voxelToLocalMatrix()); return localToModelMatrix;} glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix(bool includeBillboard) const { glm::vec3 position = getWorldPosition(); glm::mat4 translation = glm::translate(position); glm::mat4 rotation; if (includeBillboard) { BillboardMode billboardMode = getBillboardMode(); glm::quat orientation = billboardMode == BillboardMode::NONE ? getWorldOrientation() : getLocalOrientation(); rotation = glm::mat4_cast(BillboardModeHelpers::getBillboardRotation(position, orientation, billboardMode, BillboardModeHelpers::getPrimaryViewFrustumPosition())); } else { rotation = glm::mat4_cast(getWorldOrientation()); } return translation * rotation * voxelToLocalMatrix();} glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix(bool includeBillboard) const { return glm::inverse(voxelToWorldMatrix(includeBillboard));} glm::vec3 PolyVoxEntityItem::voxelCoordsToWorldCoords(const glm::vec3& voxelCoords) const { glm::vec3 adjustedCoords; if (isEdged()) { adjustedCoords = voxelCoords + Vectors::HALF; } else { adjustedCoords = voxelCoords - Vectors::HALF; } return glm::vec3(voxelToWorldMatrix() * glm::vec4(adjustedCoords, 1.0f));} glm::vec3 PolyVoxEntityItem::worldCoordsToVoxelCoords(const glm::vec3& worldCoords) const { glm::vec3 result = glm::vec3(worldToVoxelMatrix() * glm::vec4(worldCoords, 1.0f)); if (isEdged()) { return result - Vectors::HALF; } return result + Vectors::HALF;} glm::vec3 PolyVoxEntityItem::voxelCoordsToLocalCoords(const glm::vec3& voxelCoords) const { return glm::vec3(voxelToLocalMatrix() * glm::vec4(voxelCoords, 0.0f));} glm::vec3 PolyVoxEntityItem::localCoordsToVoxelCoords(const glm::vec3& localCoords) const { return glm::vec3(localToVoxelMatrix() * glm::vec4(localCoords, 0.0f));} ShapeType PolyVoxEntityItem::getShapeType() const { if (_collisionless) { return SHAPE_TYPE_NONE; } return SHAPE_TYPE_COMPOUND;} bool PolyVoxEntityItem::isEdged() const { return isEdged((PolyVoxSurfaceStyle)_voxelSurfaceStyle);} std::array<EntityItemID, 3> PolyVoxEntityItem::getNNeigborIDs() const { std::array<EntityItemID, 3> result; withReadLock([&] { result = { { _xNNeighborID, _yNNeighborID, _zNNeighborID } }; }); return result;} std::array<EntityItemID, 3> PolyVoxEntityItem::getPNeigborIDs() const { std::array<EntityItemID, 3> result; withReadLock([&] { result = { { _xPNeighborID, _yPNeighborID, _zPNeighborID } }; }); return result;}
//
// PolyVoxEntityItem.cpp
// libraries/entities/src
//
// Created by Seth Alves on 5/11/15.
// 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 "PolyVoxEntityItem.h"
#include <glm/gtx/transform.hpp>
#include <QByteArray>
#include <QDebug>
#include <QWriteLocker>
#include <ByteCountCoding.h>
#include "EntitiesLogging.h"
#include "EntityItemProperties.h"
#include "EntityTree.h"
#include "EntityTreeElement.h"
bool PolyVoxEntityItem::isEdged(PolyVoxSurfaceStyle surfaceStyle) {
switch (surfaceStyle) {
case PolyVoxEntityItem::SURFACE_CUBIC:
case PolyVoxEntityItem::SURFACE_MARCHING_CUBES:
return false;
case PolyVoxEntityItem::SURFACE_EDGED_CUBIC:
case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES:
return true;
}
return false;
}
const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32);
const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 128.0f;
const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(PolyVoxEntityItem::makeEmptyVoxelData());
const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE =
PolyVoxEntityItem::SURFACE_EDGED_CUBIC;
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) {
std::shared_ptr<PolyVoxEntityItem> entity(new PolyVoxEntityItem(entityID), [](PolyVoxEntityItem* ptr) { ptr->deleteLater(); });
entity->setProperties(properties);
return entity;
}
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) : EntityItem(entityItemID) {
_type = EntityTypes::PolyVox;
}
void PolyVoxEntityItem::setVoxelVolumeSize(const glm::vec3& voxelVolumeSize_) {
auto voxelVolumeSize = glm::clamp(glm::round(voxelVolumeSize_), glm::vec3(1.0f), glm::vec3(MAX_VOXEL_DIMENSION));
withWriteLock([&] {
_needsRenderUpdate |= _voxelVolumeSize != voxelVolumeSize;
_voxelVolumeSize = voxelVolumeSize;
});
}
glm::vec3 PolyVoxEntityItem::getVoxelVolumeSize() const {
return resultWithReadLock<glm::vec3>([&] {
return _voxelVolumeSize;
});
}
EntityItemProperties PolyVoxEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
@PolyVox_ENTITY_COPY_TO@
return properties;
}
bool PolyVoxEntityItem::setSubClassProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
@PolyVox_ENTITY_SET_FROM@
return somethingChanged;
}
EntityPropertyFlags PolyVoxEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
@PolyVox_REQUESTED_PROPS@
return requestedProperties;
}
void PolyVoxEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
int& propertyCount,
OctreeElement::AppendState& appendState) const {
bool successPropertyFits = true;
@PolyVox_ENTITY_APPEND@
}
int PolyVoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args,
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
bool& somethingChanged) {
int bytesRead = 0;
const unsigned char* dataAt = data;
@PolyVox_ENTITY_READ@
return bytesRead;
}
void PolyVoxEntityItem::debugDump() const {
qCDebug(entities) << "PolyVoxEntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " name:" << _name;
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " editedAgo:" << debugTime(getLastEdited(), usecTimestampNow());
qCDebug(entities) << " pointer:" << this;
@PolyVox_ENTITY_DEBUG@
}
void PolyVoxEntityItem::setVoxelData(const QByteArray& voxelData) {
withWriteLock([&] {
_voxelData = voxelData;
_voxelDataDirty = true;
});
}
QByteArray PolyVoxEntityItem::getVoxelData() const {
return resultWithReadLock<QByteArray>([&] {
return _voxelData;
});
}
void PolyVoxEntityItem::setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) {
withWriteLock([&] {
_voxelSurfaceStyle = voxelSurfaceStyle;
});
}
uint16_t PolyVoxEntityItem::getVoxelSurfaceStyle() const {
return resultWithReadLock<uint16_t>([&] {
return _voxelSurfaceStyle;
});
}
void PolyVoxEntityItem::setXNNeighborID(const EntityItemID& xNNeighborID) {
withWriteLock([&] {
_xNNeighborID = xNNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getXNNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _xNNeighborID;
});
}
void PolyVoxEntityItem::setYNNeighborID(const EntityItemID& yNNeighborID) {
withWriteLock([&] {
_yNNeighborID = yNNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getYNNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _yNNeighborID;
});
}
void PolyVoxEntityItem::setZNNeighborID(const EntityItemID& zNNeighborID) {
withWriteLock([&] {
_zNNeighborID = zNNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getZNNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _zNNeighborID;
});
}
void PolyVoxEntityItem::setXPNeighborID(const EntityItemID& xPNeighborID) {
withWriteLock([&] {
_xPNeighborID = xPNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getXPNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _xPNeighborID;
});
}
void PolyVoxEntityItem::setYPNeighborID(const EntityItemID& yPNeighborID) {
withWriteLock([&] {
_yPNeighborID = yPNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getYPNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _yPNeighborID;
});
}
void PolyVoxEntityItem::setZPNeighborID(const EntityItemID& zPNeighborID) {
withWriteLock([&] {
_zPNeighborID = zPNeighborID;
});
}
EntityItemID PolyVoxEntityItem::getZPNeighborID() const {
return resultWithReadLock<EntityItemID>([&] {
return _zPNeighborID;
});
}
glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const {
glm::vec3 result;
withReadLock([&] {
glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
if (isEdged()) {
result = scale / -2.0f;
}
return scale / 2.0f;
});
return result;
}
glm::mat4 PolyVoxEntityItem::voxelToLocalMatrix() const {
glm::vec3 voxelVolumeSize;
withReadLock([&] {
voxelVolumeSize = _voxelVolumeSize;
});
glm::vec3 dimensions = getScaledDimensions();
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
bool success; // TODO -- Does this actually have to happen in world space?
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
glm::vec3 position = getWorldPosition(success);
glm::vec3 positionToCenter = center - position;
positionToCenter -= dimensions * Vectors::HALF - getSurfacePositionAdjustment();
glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter);
glm::mat4 scaled = glm::scale(centerToCorner, scale);
return scaled;
}
glm::mat4 PolyVoxEntityItem::localToVoxelMatrix() const {
glm::mat4 localToModelMatrix = glm::inverse(voxelToLocalMatrix());
return localToModelMatrix;
}
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix(bool includeBillboard) const {
glm::vec3 position = getWorldPosition();
glm::mat4 translation = glm::translate(position);
glm::mat4 rotation;
if (includeBillboard) {
BillboardMode billboardMode = getBillboardMode();
glm::quat orientation = billboardMode == BillboardMode::NONE ? getWorldOrientation() : getLocalOrientation();
rotation = glm::mat4_cast(BillboardModeHelpers::getBillboardRotation(position, orientation, billboardMode, BillboardModeHelpers::getPrimaryViewFrustumPosition()));
} else {
rotation = glm::mat4_cast(getWorldOrientation());
}
return translation * rotation * voxelToLocalMatrix();
}
glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix(bool includeBillboard) const {
return glm::inverse(voxelToWorldMatrix(includeBillboard));
}
glm::vec3 PolyVoxEntityItem::voxelCoordsToWorldCoords(const glm::vec3& voxelCoords) const {
glm::vec3 adjustedCoords;
if (isEdged()) {
adjustedCoords = voxelCoords + Vectors::HALF;
} else {
adjustedCoords = voxelCoords - Vectors::HALF;
}
return glm::vec3(voxelToWorldMatrix() * glm::vec4(adjustedCoords, 1.0f));
}
glm::vec3 PolyVoxEntityItem::worldCoordsToVoxelCoords(const glm::vec3& worldCoords) const {
glm::vec3 result = glm::vec3(worldToVoxelMatrix() * glm::vec4(worldCoords, 1.0f));
if (isEdged()) {
return result - Vectors::HALF;
}
return result + Vectors::HALF;
}
glm::vec3 PolyVoxEntityItem::voxelCoordsToLocalCoords(const glm::vec3& voxelCoords) const {
return glm::vec3(voxelToLocalMatrix() * glm::vec4(voxelCoords, 0.0f));
}
glm::vec3 PolyVoxEntityItem::localCoordsToVoxelCoords(const glm::vec3& localCoords) const {
return glm::vec3(localToVoxelMatrix() * glm::vec4(localCoords, 0.0f));
}
ShapeType PolyVoxEntityItem::getShapeType() const {
if (_collisionless) {
return SHAPE_TYPE_NONE;
}
return SHAPE_TYPE_COMPOUND;
}
bool PolyVoxEntityItem::isEdged() const {
return isEdged((PolyVoxSurfaceStyle)_voxelSurfaceStyle);
}
std::array<EntityItemID, 3> PolyVoxEntityItem::getNNeigborIDs() const {
std::array<EntityItemID, 3> result;
withReadLock([&] {
result = { { _xNNeighborID, _yNNeighborID, _zNNeighborID } };
});
return result;
}
std::array<EntityItemID, 3> PolyVoxEntityItem::getPNeigborIDs() const {
std::array<EntityItemID, 3> result;
withReadLock([&] {
result = { { _xPNeighborID, _yPNeighborID, _zPNeighborID } };
});
return result;
}