Merge branch 'develop' into feature/cubiquity-version
This commit is contained in:
commit
a38ac6b895
@ -2,6 +2,14 @@ Changes for PolyVox version 0.3
|
|||||||
===============================
|
===============================
|
||||||
This release has focused on... (some introduction here).
|
This release has focused on... (some introduction here).
|
||||||
|
|
||||||
|
LargeVolume
|
||||||
|
-----------
|
||||||
|
It is now possible to provide custom compressors for the data which is stored in a LargeVolume. Two compressor implementation are provided with PolyVox - RLECompressor which is suitable for cubic-style terrain, and MinizCompressor which uses the 'miniz' zlib implementation for smooth terrain or general purpose use. Users can provide their own implementation of the compressor interface if they wish.
|
||||||
|
|
||||||
|
Note that the setCompressionEnabled() functionality has been removed and a compressor must always be provided when constructing the volume. The ability to disable compression was of questionable benefit and was complicating the logic in the code. In practice it is still possible to mostly disable compression by setting the maximum number of uncompressed blocks to a high value by calling setMaxNumberOfUncompressedBlocks().
|
||||||
|
|
||||||
|
These changes regarding compression and paging have also affected the LargeVolume constructors(s). Please see the API docs to see how they look now.
|
||||||
|
|
||||||
Error Handling
|
Error Handling
|
||||||
--------------
|
--------------
|
||||||
PolyVox now has it's own POLYVOX_ASSERT() macro rather than using the standard assert(). This has some advantages such as allowing a message to be printed and providing file/line information, and it is also possible to enable/disable it independantly of whether you are making a debug or release build
|
PolyVox now has it's own POLYVOX_ASSERT() macro rather than using the standard assert(). This has some advantages such as allowing a message to be printed and providing file/line information, and it is also possible to enable/disable it independantly of whether you are making a debug or release build
|
||||||
|
@ -82,6 +82,7 @@ IF(ENABLE_EXAMPLES AND QT_QTOPENGL_FOUND)
|
|||||||
ADD_SUBDIRECTORY(examples/Paging)
|
ADD_SUBDIRECTORY(examples/Paging)
|
||||||
ADD_SUBDIRECTORY(examples/OpenGL)
|
ADD_SUBDIRECTORY(examples/OpenGL)
|
||||||
ADD_SUBDIRECTORY(examples/SmoothLOD)
|
ADD_SUBDIRECTORY(examples/SmoothLOD)
|
||||||
|
ADD_SUBDIRECTORY(examples/Python)
|
||||||
SET(BUILD_EXAMPLES ON)
|
SET(BUILD_EXAMPLES ON)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(BUILD_EXAMPLES OFF)
|
SET(BUILD_EXAMPLES OFF)
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
David Williams - Lead programmer.
|
David Williams - Lead programmer.
|
||||||
Matthew Williams - Linux port, build system, support and maintenance.
|
Matthew Williams - Linux port, build system, support and maintenance.
|
||||||
Oliver Schneider - Very large Volumes
|
Oliver Schneider - Very large Volumes
|
||||||
|
|
||||||
|
Acknowledgements
|
||||||
|
----------------
|
||||||
|
PolyVox uses the 'miniz' for data compression. 'miniz' is public domain software and does not affect the license of PolyVox or of code using PolyVox. More details here: http://code.google.com/p/miniz/
|
@ -41,7 +41,7 @@ const int32_t g_uVolumeSideLength = 128;
|
|||||||
|
|
||||||
struct Vector3DUint8Compare
|
struct Vector3DUint8Compare
|
||||||
{
|
{
|
||||||
bool operator() (const PolyVox::Vector3DUint8& a, const PolyVox::Vector3DUint8& b)
|
bool operator() (const PolyVox::Vector3DUint8& a, const PolyVox::Vector3DUint8& b) const
|
||||||
{
|
{
|
||||||
const uint32_t size = 3;
|
const uint32_t size = 3;
|
||||||
for(uint32_t ct = 0; ct < size; ++ct)
|
for(uint32_t ct = 0; ct < size; ++ct)
|
||||||
|
26
examples/Python/CMakeLists.txt
Normal file
26
examples/Python/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (c) 2010-2013 Matt Williams
|
||||||
|
#
|
||||||
|
# This software is provided 'as-is', without any express or implied
|
||||||
|
# warranty. In no event will the authors be held liable for any damages
|
||||||
|
# arising from the use of this software.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
#
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
#
|
||||||
|
# 3. This notice may not be removed or altered from any source
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
PROJECT(PythonExample)
|
||||||
|
|
||||||
|
SOURCE_GROUP("Sources" FILES PythonExample.py)
|
||||||
|
|
||||||
|
configure_file(PythonExample.py PythonExample.py COPYONLY)
|
257
examples/Python/PythonExample.py
Executable file
257
examples/Python/PythonExample.py
Executable file
@ -0,0 +1,257 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Copyright (c) 2013 Matt Williams
|
||||||
|
#
|
||||||
|
# This software is provided 'as-is', without any express or implied
|
||||||
|
# warranty. In no event will the authors be held liable for any damages
|
||||||
|
# arising from the use of this software.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
#
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
#
|
||||||
|
# 3. This notice may not be removed or altered from any source
|
||||||
|
# distribution.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append("../../library/bindings/") #This is just to point to the generated bindings
|
||||||
|
|
||||||
|
import PolyVoxCore as pv
|
||||||
|
|
||||||
|
#Create a 64x64x64 volume of integers
|
||||||
|
r = pv.Region(pv.Vector3Dint32_t(0,0,0), pv.Vector3Dint32_t(63,63,63))
|
||||||
|
vol = pv.SimpleVolumeuint8(r)
|
||||||
|
|
||||||
|
#Now fill the volume with our data (a sphere)
|
||||||
|
v3dVolCenter = pv.Vector3Dint32_t(vol.getWidth() / 2, vol.getHeight() / 2, vol.getDepth() / 2)
|
||||||
|
sphereRadius = 30
|
||||||
|
#This three-level for loop iterates over every voxel in the volume
|
||||||
|
for z in range(vol.getDepth()):
|
||||||
|
for y in range(vol.getHeight()):
|
||||||
|
for x in range(vol.getWidth()):
|
||||||
|
#Store our current position as a vector...
|
||||||
|
v3dCurrentPos = pv.Vector3Dint32_t(x,y,z)
|
||||||
|
#And compute how far the current position is from the center of the volume
|
||||||
|
fDistToCenter = (v3dCurrentPos - v3dVolCenter).length()
|
||||||
|
|
||||||
|
uVoxelValue = 0
|
||||||
|
|
||||||
|
#If the current voxel is less than 'radius' units from the center then we make it solid.
|
||||||
|
if(fDistToCenter <= sphereRadius):
|
||||||
|
#Our new voxel value
|
||||||
|
uVoxelValue = 255
|
||||||
|
|
||||||
|
#Write the voxel value into the volume
|
||||||
|
vol.setVoxelAt(x, y, z, uVoxelValue);
|
||||||
|
|
||||||
|
#Create a mesh, pass it to the extractor and generate the mesh
|
||||||
|
mesh = pv.SurfaceMeshPositionMaterialNormal()
|
||||||
|
extractor = pv.CubicSurfaceExtractorWithNormalsSimpleVolumeuint8(vol, r, mesh)
|
||||||
|
extractor.execute()
|
||||||
|
|
||||||
|
#That's all of the PolyVox generation done, now to convert the output to something OpenGL can read efficiently
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
indices = np.array(mesh.getIndices(), dtype='uint32') #Throw in the vertex indices into an array
|
||||||
|
#The vertices and normals are placed in an interpolated array like [vvvnnn,vvvnnn,vvvnnn]
|
||||||
|
vertices = np.array([[vertex.getPosition().getX(), vertex.getPosition().getY(), vertex.getPosition().getZ(),
|
||||||
|
vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ()]
|
||||||
|
for vertex in mesh.getVertices()],
|
||||||
|
dtype='f')
|
||||||
|
|
||||||
|
#Now that we have our data, everything else here is just OpenGL
|
||||||
|
|
||||||
|
import OpenGL
|
||||||
|
|
||||||
|
from OpenGL.GL import shaders
|
||||||
|
from OpenGL.arrays import vbo
|
||||||
|
from OpenGL.GL import glClear, glEnable, glDepthFunc, GLuint, glEnableVertexAttribArray, glVertexAttribPointer, glDisableVertexAttribArray, \
|
||||||
|
glDrawElements, glGetUniformLocation, glUniformMatrix4fv, glDepthMask, glDepthRange, glGetString, glBindAttribLocation, \
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_TRIANGLES, GL_DEPTH_TEST, GL_LEQUAL, GL_FLOAT, \
|
||||||
|
GL_DEPTH_BUFFER_BIT, GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, GL_STATIC_DRAW, \
|
||||||
|
GL_FALSE, GL_TRUE, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_CULL_FACE, \
|
||||||
|
GL_VENDOR, GL_RENDERER, GL_VERSION, GL_SHADING_LANGUAGE_VERSION
|
||||||
|
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from math import sin, cos, tan, radians
|
||||||
|
|
||||||
|
SCREEN_SIZE = (800, 800)
|
||||||
|
|
||||||
|
def run():
|
||||||
|
#Start OpenGL and ask it for an OpenGL context
|
||||||
|
pygame.init()
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF)
|
||||||
|
|
||||||
|
#The first thing we do is print some OpenGL details and check that we have a good enough version
|
||||||
|
print "OpenGL Implementation Details:"
|
||||||
|
if glGetString(GL_VENDOR):
|
||||||
|
print "\tGL_VENDOR:", glGetString(GL_VENDOR)
|
||||||
|
if glGetString(GL_RENDERER):
|
||||||
|
print "\tGL_RENDERER:", glGetString(GL_RENDERER)
|
||||||
|
if glGetString(GL_VERSION):
|
||||||
|
print "\tGL_VERSION:", glGetString(GL_VERSION)
|
||||||
|
if glGetString(GL_SHADING_LANGUAGE_VERSION):
|
||||||
|
print "\tGL_SHADING_LANGUAGE_VERSION:", glGetString(GL_SHADING_LANGUAGE_VERSION)
|
||||||
|
|
||||||
|
major_version = int(glGetString(GL_VERSION).split()[0].split('.')[0])
|
||||||
|
minor_version = int(glGetString(GL_VERSION).split()[0].split('.')[1])
|
||||||
|
if major_version < 3 or (major_version < 3 and minor_version < 0):
|
||||||
|
print "OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).split()[0])
|
||||||
|
|
||||||
|
#Now onto the OpenGL initialisation
|
||||||
|
|
||||||
|
#Set up depth culling
|
||||||
|
glEnable(GL_CULL_FACE)
|
||||||
|
glEnable(GL_DEPTH_TEST)
|
||||||
|
glDepthMask(GL_TRUE)
|
||||||
|
glDepthFunc(GL_LEQUAL)
|
||||||
|
glDepthRange(0.0, 1.0)
|
||||||
|
|
||||||
|
#We create out shaders which do little more than set a flat colour for each face
|
||||||
|
|
||||||
|
VERTEX_SHADER = shaders.compileShader("""
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
in vec4 normal;
|
||||||
|
|
||||||
|
uniform mat4 cameraToClipMatrix;
|
||||||
|
uniform mat4 worldToCameraMatrix;
|
||||||
|
uniform mat4 modelToWorldMatrix;
|
||||||
|
|
||||||
|
flat out float theColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 temp = modelToWorldMatrix * position;
|
||||||
|
temp = worldToCameraMatrix * temp;
|
||||||
|
gl_Position = cameraToClipMatrix * temp;
|
||||||
|
|
||||||
|
theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1);
|
||||||
|
}
|
||||||
|
""", GL_VERTEX_SHADER)
|
||||||
|
|
||||||
|
FRAGMENT_SHADER = shaders.compileShader("""
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
flat in float theColor;
|
||||||
|
|
||||||
|
out vec4 outputColor;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outputColor = vec4(1.0, 0.5, theColor, 1.0);
|
||||||
|
}
|
||||||
|
""", GL_FRAGMENT_SHADER)
|
||||||
|
|
||||||
|
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
|
||||||
|
|
||||||
|
#And then grab our attribute locations from it
|
||||||
|
glBindAttribLocation(shader, 0, "position")
|
||||||
|
glBindAttribLocation(shader, 1, "normal")
|
||||||
|
|
||||||
|
#Create the Vertex Array Object to hold our volume mesh
|
||||||
|
vertexArrayObject = GLuint(0)
|
||||||
|
glGenVertexArrays(1, vertexArrayObject)
|
||||||
|
glBindVertexArray(vertexArrayObject)
|
||||||
|
|
||||||
|
#Create the index buffer object
|
||||||
|
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER, usage=GL_STATIC_DRAW)
|
||||||
|
#Create the VBO
|
||||||
|
vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW)
|
||||||
|
|
||||||
|
#Bind our VBOs and set up our data layout specifications
|
||||||
|
with indexPositions, vertexPositions:
|
||||||
|
glEnableVertexAttribArray(0)
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(0*vertices.dtype.itemsize))
|
||||||
|
glEnableVertexAttribArray(1)
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(3*vertices.dtype.itemsize))
|
||||||
|
|
||||||
|
glBindVertexArray(0)
|
||||||
|
glDisableVertexAttribArray(0)
|
||||||
|
|
||||||
|
#Now grab out transformation martix locations
|
||||||
|
modelToWorldMatrixUnif = glGetUniformLocation(shader, "modelToWorldMatrix")
|
||||||
|
worldToCameraMatrixUnif = glGetUniformLocation(shader, "worldToCameraMatrix")
|
||||||
|
cameraToClipMatrixUnif = glGetUniformLocation(shader, "cameraToClipMatrix")
|
||||||
|
|
||||||
|
modelToWorldMatrix = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
worldToCameraMatrix = np.array([[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,-50.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
cameraToClipMatrix = np.array([[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0]], dtype='f')
|
||||||
|
|
||||||
|
#These next few lines just set up our camera frustum
|
||||||
|
fovDeg = 45.0
|
||||||
|
frustumScale = 1.0 / tan(radians(fovDeg) / 2.0)
|
||||||
|
|
||||||
|
zNear = 1.0
|
||||||
|
zFar = 1000.0
|
||||||
|
|
||||||
|
cameraToClipMatrix[0][0] = frustumScale
|
||||||
|
cameraToClipMatrix[1][1] = frustumScale
|
||||||
|
cameraToClipMatrix[2][2] = (zFar + zNear) / (zNear - zFar)
|
||||||
|
cameraToClipMatrix[2][3] = -1.0
|
||||||
|
cameraToClipMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar)
|
||||||
|
|
||||||
|
#worldToCameraMatrix and cameraToClipMatrix don't change ever so just set them once here
|
||||||
|
with shader:
|
||||||
|
glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_TRUE, cameraToClipMatrix)
|
||||||
|
glUniformMatrix4fv(worldToCameraMatrixUnif, 1, GL_TRUE, worldToCameraMatrix)
|
||||||
|
|
||||||
|
#These are used to track the rotation of the volume
|
||||||
|
LastFrameMousePos = (0,0)
|
||||||
|
CurrentMousePos = (0,0)
|
||||||
|
xRotation = 0
|
||||||
|
yRotation = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
clock.tick()
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
return
|
||||||
|
if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
|
||||||
|
return
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
||||||
|
CurrentMousePos = event.pos
|
||||||
|
LastFrameMousePos = CurrentMousePos
|
||||||
|
if event.type == pygame.MOUSEMOTION and 1 in event.buttons:
|
||||||
|
CurrentMousePos = event.pos
|
||||||
|
diff = (CurrentMousePos[0] - LastFrameMousePos[0], CurrentMousePos[1] - LastFrameMousePos[1])
|
||||||
|
xRotation += event.rel[0]
|
||||||
|
yRotation += event.rel[1]
|
||||||
|
LastFrameMousePos = CurrentMousePos
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
|
#Perform the rotation of the mesh
|
||||||
|
moveToOrigin = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
rotateAroundX = np.array([[1.0,0.0,0.0,0.0],[0.0,cos(radians(yRotation)),-sin(radians(yRotation)),0.0],[0.0,sin(radians(yRotation)),cos(radians(yRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
rotateAroundY = np.array([[cos(radians(xRotation)),0.0,sin(radians(xRotation)),0.0],[0.0,1.0,0.0,0.0],[-sin(radians(xRotation)),0.0,cos(radians(xRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
|
||||||
|
modelToWorldMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin))
|
||||||
|
|
||||||
|
with shader:
|
||||||
|
glUniformMatrix4fv(modelToWorldMatrixUnif, 1, GL_TRUE, modelToWorldMatrix)
|
||||||
|
glBindVertexArray(vertexArrayObject)
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)
|
||||||
|
|
||||||
|
glBindVertexArray(0)
|
||||||
|
|
||||||
|
# Show the screen
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
run()
|
@ -31,6 +31,7 @@ endif()
|
|||||||
SET(CORE_SRC_FILES
|
SET(CORE_SRC_FILES
|
||||||
source/ArraySizes.cpp
|
source/ArraySizes.cpp
|
||||||
source/AStarPathfinder.cpp
|
source/AStarPathfinder.cpp
|
||||||
|
source/MinizCompressor.cpp
|
||||||
source/Log.cpp
|
source/Log.cpp
|
||||||
source/Region.cpp
|
source/Region.cpp
|
||||||
source/VertexTypes.cpp
|
source/VertexTypes.cpp
|
||||||
@ -48,6 +49,7 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/BaseVolume.h
|
include/PolyVoxCore/BaseVolume.h
|
||||||
include/PolyVoxCore/BaseVolume.inl
|
include/PolyVoxCore/BaseVolume.inl
|
||||||
include/PolyVoxCore/BaseVolumeSampler.inl
|
include/PolyVoxCore/BaseVolumeSampler.inl
|
||||||
|
include/PolyVoxCore/Compressor.h
|
||||||
include/PolyVoxCore/ConstVolumeProxy.h
|
include/PolyVoxCore/ConstVolumeProxy.h
|
||||||
include/PolyVoxCore/CubicSurfaceExtractor.h
|
include/PolyVoxCore/CubicSurfaceExtractor.h
|
||||||
include/PolyVoxCore/CubicSurfaceExtractor.inl
|
include/PolyVoxCore/CubicSurfaceExtractor.inl
|
||||||
@ -71,6 +73,7 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
|
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
|
||||||
include/PolyVoxCore/Material.h
|
include/PolyVoxCore/Material.h
|
||||||
include/PolyVoxCore/MaterialDensityPair.h
|
include/PolyVoxCore/MaterialDensityPair.h
|
||||||
|
include/PolyVoxCore/MinizCompressor.h
|
||||||
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
||||||
include/PolyVoxCore/RawVolume.h
|
include/PolyVoxCore/RawVolume.h
|
||||||
include/PolyVoxCore/RawVolume.inl
|
include/PolyVoxCore/RawVolume.inl
|
||||||
@ -78,6 +81,8 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/Raycast.h
|
include/PolyVoxCore/Raycast.h
|
||||||
include/PolyVoxCore/Raycast.inl
|
include/PolyVoxCore/Raycast.inl
|
||||||
include/PolyVoxCore/Region.h
|
include/PolyVoxCore/Region.h
|
||||||
|
include/PolyVoxCore/RLECompressor.h
|
||||||
|
include/PolyVoxCore/RLECompressor.inl
|
||||||
include/PolyVoxCore/SimpleVolume.h
|
include/PolyVoxCore/SimpleVolume.h
|
||||||
include/PolyVoxCore/SimpleVolume.inl
|
include/PolyVoxCore/SimpleVolume.inl
|
||||||
include/PolyVoxCore/SimpleVolumeBlock.inl
|
include/PolyVoxCore/SimpleVolumeBlock.inl
|
||||||
|
@ -298,14 +298,14 @@ namespace PolyVox
|
|||||||
hVal = SixConnectedCost(a, b);
|
hVal = SixConnectedCost(a, b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false); //Invalid case.
|
POLYVOX_ASSERT(false, "Invalid case");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sanity checks in debug mode. These can come out eventually, but I
|
//Sanity checks in debug mode. These can come out eventually, but I
|
||||||
//want to make sure that the heuristics I've come up with make sense.
|
//want to make sure that the heuristics I've come up with make sense.
|
||||||
assert((a-b).length() <= TwentySixConnectedCost(a,b));
|
POLYVOX_ASSERT((a-b).length() <= TwentySixConnectedCost(a,b), "A* heuristic error.");
|
||||||
assert(TwentySixConnectedCost(a,b) <= EighteenConnectedCost(a,b));
|
POLYVOX_ASSERT(TwentySixConnectedCost(a,b) <= EighteenConnectedCost(a,b), "A* heuristic error.");
|
||||||
assert(EighteenConnectedCost(a,b) <= SixConnectedCost(a,b));
|
POLYVOX_ASSERT(EighteenConnectedCost(a,b) <= SixConnectedCost(a,b), "A* heuristic error.");
|
||||||
|
|
||||||
//Apply the bias to the computed h value;
|
//Apply the bias to the computed h value;
|
||||||
hVal *= m_params.hBias;
|
hVal *= m_params.hBias;
|
||||||
@ -336,7 +336,7 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Robert Jenkins' 32 bit integer hash function
|
// Robert Jenkins' 32 bit integer hash function
|
||||||
// http://www.concentric.net/~ttwang/tech/inthash.htm
|
// http://www.burtleburtle.net/bob/hash/integer.html
|
||||||
template<typename VolumeType>
|
template<typename VolumeType>
|
||||||
uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a)
|
uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a)
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,9 @@ namespace PolyVox
|
|||||||
uint16_t uIndexIncreament;
|
uint16_t uIndexIncreament;
|
||||||
|
|
||||||
//Make sure that the size of the volume is an exact multiple of the size of the array.
|
//Make sure that the size of the volume is an exact multiple of the size of the array.
|
||||||
assert(volInput->getWidth() % arrayResult->getDimension(0) == 0);
|
POLYVOX_ASSERT(volInput->getWidth() % arrayResult->getDimension(0) == 0, "Volume width must be an exact multiple of array width.");
|
||||||
assert(volInput->getHeight() % arrayResult->getDimension(1) == 0);
|
POLYVOX_ASSERT(volInput->getHeight() % arrayResult->getDimension(1) == 0, "Volume height must be an exact multiple of array height.");
|
||||||
assert(volInput->getDepth() % arrayResult->getDimension(2) == 0);
|
POLYVOX_ASSERT(volInput->getDepth() % arrayResult->getDimension(2) == 0, "Volume depth must be an exact multiple of array depth.");
|
||||||
|
|
||||||
//Our initial indices. It doesn't matter exactly what we set here, but the code below makes
|
//Our initial indices. It doesn't matter exactly what we set here, but the code below makes
|
||||||
//sure they are different for different regions which helps reduce tiling patterns in the results.
|
//sure they are different for different regions which helps reduce tiling patterns in the results.
|
||||||
@ -116,7 +116,7 @@ namespace PolyVox
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fVisibility = static_cast<float>(uVisibleDirections) / static_cast<float>(uNoOfSamplesPerOutputElement);
|
fVisibility = static_cast<float>(uVisibleDirections) / static_cast<float>(uNoOfSamplesPerOutputElement);
|
||||||
assert((fVisibility >= 0.0f) && (fVisibility <= 1.0f));
|
POLYVOX_ASSERT((fVisibility >= 0.0f) && (fVisibility <= 1.0f), "Visibility value out of range.");
|
||||||
}
|
}
|
||||||
|
|
||||||
(*arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast<uint8_t>(255.0f * fVisibility);
|
(*arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast<uint8_t>(255.0f * fVisibility);
|
||||||
|
@ -73,7 +73,7 @@ namespace PolyVox
|
|||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return
|
return
|
||||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||||
m_pDimensions+1, m_pOffsets+1);
|
m_pDimensions+1, m_pOffsets+1);
|
||||||
@ -91,7 +91,7 @@ namespace PolyVox
|
|||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return
|
return
|
||||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||||
m_pDimensions+1, m_pOffsets+1);
|
m_pDimensions+1, m_pOffsets+1);
|
||||||
@ -139,7 +139,7 @@ namespace PolyVox
|
|||||||
m_uNoOfElements = 1;
|
m_uNoOfElements = 1;
|
||||||
for (uint32_t i = 0; i<noOfDims; i++)
|
for (uint32_t i = 0; i<noOfDims; i++)
|
||||||
{
|
{
|
||||||
assert(pDimensions[i] != 0);
|
POLYVOX_ASSERT(pDimensions[i] != 0, "Invalid dimension");
|
||||||
|
|
||||||
m_uNoOfElements *= pDimensions[i];
|
m_uNoOfElements *= pDimensions[i];
|
||||||
m_pDimensions[i] = pDimensions[i];
|
m_pDimensions[i] = pDimensions[i];
|
||||||
@ -186,7 +186,7 @@ namespace PolyVox
|
|||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
|
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
|
||||||
{
|
{
|
||||||
assert(uDimension < noOfDims);
|
POLYVOX_ASSERT(uDimension < noOfDims, "Dimension out of range");
|
||||||
return m_pDimensions[uDimension];
|
return m_pDimensions[uDimension];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,14 +198,14 @@ namespace PolyVox
|
|||||||
,m_uNoOfElements(0)
|
,m_uNoOfElements(0)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
Array<noOfDims, ElementType>& Array<noOfDims, ElementType>::operator=(const Array<noOfDims, ElementType>& rhs)
|
Array<noOfDims, ElementType>& Array<noOfDims, ElementType>::operator=(const Array<noOfDims, ElementType>& rhs)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Not implemented.");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -251,14 +251,14 @@ namespace PolyVox
|
|||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
|
const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,14 +307,14 @@ namespace PolyVox
|
|||||||
,m_pDimensions(0)
|
,m_pDimensions(0)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
Array<1, ElementType>& Array<1, ElementType>::operator=(const Array<1, ElementType>& rhs)
|
Array<1, ElementType>& Array<1, ElementType>::operator=(const Array<1, ElementType>& rhs)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Not implemented.");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
|
@ -38,14 +38,14 @@ namespace PolyVox
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
|
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
|
||||||
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
|
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
|
||||||
/// make a copy of a volume and in this case you should look at the Volumeresampler.
|
/// make a copy of a volume and in this case you should look at the VolumeResampler.
|
||||||
///
|
///
|
||||||
/// \sa VolumeResampler
|
/// \sa VolumeResampler
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -66,7 +66,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -162,7 +162,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxelAt(const Vector3DInt32& /*v3dPos*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxelAt(const Vector3DInt32& /*v3dPos*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
bool BaseVolume<VoxelType>::setVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
|
bool BaseVolume<VoxelType>::setVoxelAt(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/)
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
bool BaseVolume<VoxelType>::setVoxelAt(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
|
bool BaseVolume<VoxelType>::setVoxelAt(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/)
|
||||||
{
|
{
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Invalid case.");
|
||||||
return VoxelType(0);
|
return VoxelType(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
library/PolyVoxCore/include/PolyVoxCore/Compressor.h
Normal file
49
library/PolyVoxCore/include/PolyVoxCore/Compressor.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Copyright (c) 2005-2009 David Williams
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PolyVox_Compressor_H__
|
||||||
|
#define __PolyVox_Compressor_H__
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Impl/TypeDef.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
class Compressor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Compressor() {};
|
||||||
|
virtual ~Compressor() {};
|
||||||
|
|
||||||
|
// Computes a worst-case scenario for how big the output can be for a given input size. If
|
||||||
|
// necessary you can use this as a destination buffer size, though it may be somewhat wasteful.
|
||||||
|
virtual uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize) = 0;
|
||||||
|
|
||||||
|
// Compresses the data.
|
||||||
|
virtual uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
||||||
|
|
||||||
|
// Decompresses the data.
|
||||||
|
virtual uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__PolyVox_Compressor_H__
|
@ -37,25 +37,25 @@ namespace PolyVox
|
|||||||
public:
|
public:
|
||||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
|
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
|
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||||
{
|
{
|
||||||
assert(m_regValid.containsPoint(v3dPos));
|
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||||
{
|
{
|
||||||
assert(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
|
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
|
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
|
||||||
{
|
{
|
||||||
assert(m_regValid.containsPoint(v3dPos));
|
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -26,13 +26,12 @@ namespace PolyVox
|
|||||||
// We try to avoid duplicate vertices by checking whether a vertex has already been added at a given position.
|
// We try to avoid duplicate vertices by checking whether a vertex has already been added at a given position.
|
||||||
// However, it is possible that vertices have the same position but different materials. In this case, the
|
// However, it is possible that vertices have the same position but different materials. In this case, the
|
||||||
// vertices are not true duplicates and both must be added to the mesh. As far as I can tell, it is possible to have
|
// vertices are not true duplicates and both must be added to the mesh. As far as I can tell, it is possible to have
|
||||||
// at most six vertices with the same position but different materials. This worst-case scenario happens when we
|
// at most eight vertices with the same position but different materials. For example, this worst-case scenario
|
||||||
// have a 2x2x2 group of voxels (all with different materials) and then we delete two voxels from opposing corners.
|
// happens when we have a 2x2x2 group of voxels, all with different materials and some/all partially transparent.
|
||||||
// The vertex position at the center of this group is then going to be used by six quads all with different materials.
|
// The vertex position at the center of this group is then going to be used by all eight voxels all with different
|
||||||
// One futher note - we can actually have eight quads sharing a vertex position (imagine two 1x1x10 rows of voxels
|
// materials.
|
||||||
// sharing a common edge) but in this case all eight quads will not have different materials.
|
|
||||||
template<typename VolumeType, typename IsQuadNeeded>
|
template<typename VolumeType, typename IsQuadNeeded>
|
||||||
const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 6;
|
const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 8;
|
||||||
|
|
||||||
template<typename VolumeType, typename IsQuadNeeded>
|
template<typename VolumeType, typename IsQuadNeeded>
|
||||||
CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial<typename VolumeType::VoxelType> >* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)
|
CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial<typename VolumeType::VoxelType> >* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)
|
||||||
@ -228,7 +227,7 @@ namespace PolyVox
|
|||||||
|
|
||||||
// If we exit the loop here then apparently all the slots were full but none of them matched. I don't think
|
// If we exit the loop here then apparently all the slots were full but none of them matched. I don't think
|
||||||
// this can happen so let's put an assert to make sure. If you hit this assert then please report it to us!
|
// this can happen so let's put an assert to make sure. If you hit this assert then please report it to us!
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "All slots full but no matches.");
|
||||||
return -1; //Should never happen.
|
return -1; //Should never happen.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "Impl/TypeDef.h"
|
#include "Impl/TypeDef.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
|
@ -25,6 +25,8 @@ freely, subject to the following restrictions:
|
|||||||
#define __PolyVox_Block_H__
|
#define __PolyVox_Block_H__
|
||||||
|
|
||||||
#include "PolyVoxCore/Impl/TypeDef.h"
|
#include "PolyVoxCore/Impl/TypeDef.h"
|
||||||
|
|
||||||
|
#include "PolyVoxCore/PolyVoxForwardDeclarations.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -56,15 +58,15 @@ namespace PolyVox
|
|||||||
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
||||||
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||||
|
|
||||||
void fill(VoxelType tValue);
|
|
||||||
void initialise(uint16_t uSideLength);
|
void initialise(uint16_t uSideLength);
|
||||||
uint32_t calculateSizeInBytes(void);
|
uint32_t calculateSizeInBytes(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void compress(void);
|
void compress(Compressor* pCompressor);
|
||||||
void uncompress(void);
|
void uncompress(Compressor* pCompressor);
|
||||||
|
|
||||||
std::vector< RunlengthEntry<uint16_t> > m_vecCompressedData;
|
void* m_pCompressedData;
|
||||||
|
uint32_t m_uCompressedDataLength;
|
||||||
VoxelType* m_tUncompressedData;
|
VoxelType* m_tUncompressedData;
|
||||||
uint16_t m_uSideLength;
|
uint16_t m_uSideLength;
|
||||||
uint8_t m_uSideLengthPower;
|
uint8_t m_uSideLengthPower;
|
||||||
|
@ -24,9 +24,11 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||||
#include "PolyVoxCore/Impl/Utility.h"
|
#include "PolyVoxCore/Impl/Utility.h"
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Compressor.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||||
|
|
||||||
#include <cstring> //For memcpy
|
#include <cstring> //For memcpy
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <stdexcept> //for std::invalid_argument
|
#include <stdexcept> //for std::invalid_argument
|
||||||
@ -35,10 +37,12 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
Block<VoxelType>::Block(uint16_t uSideLength)
|
Block<VoxelType>::Block(uint16_t uSideLength)
|
||||||
:m_tUncompressedData(0)
|
:m_pCompressedData(0)
|
||||||
|
,m_uCompressedDataLength(0)
|
||||||
|
,m_tUncompressedData(0)
|
||||||
,m_uSideLength(0)
|
,m_uSideLength(0)
|
||||||
,m_uSideLengthPower(0)
|
,m_uSideLengthPower(0)
|
||||||
,m_bIsCompressed(true)
|
,m_bIsCompressed(false)
|
||||||
,m_bIsUncompressedDataModified(true)
|
,m_bIsUncompressedDataModified(true)
|
||||||
{
|
{
|
||||||
if(uSideLength != 0)
|
if(uSideLength != 0)
|
||||||
@ -56,11 +60,11 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(uXPos < m_uSideLength);
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
assert(uYPos < m_uSideLength);
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
assert(uZPos < m_uSideLength);
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
|
|
||||||
assert(m_tUncompressedData);
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
return m_tUncompressedData
|
return m_tUncompressedData
|
||||||
[
|
[
|
||||||
@ -79,11 +83,11 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
void Block<VoxelType>::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||||
{
|
{
|
||||||
assert(uXPos < m_uSideLength);
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
assert(uYPos < m_uSideLength);
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
assert(uZPos < m_uSideLength);
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
|
|
||||||
assert(m_tUncompressedData);
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
m_tUncompressedData
|
m_tUncompressedData
|
||||||
[
|
[
|
||||||
@ -101,33 +105,11 @@ namespace PolyVox
|
|||||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
|
||||||
void Block<VoxelType>::fill(VoxelType tValue)
|
|
||||||
{
|
|
||||||
if(!m_bIsCompressed)
|
|
||||||
{
|
|
||||||
//The memset *may* be faster than the std::fill(), but it doesn't compile nicely
|
|
||||||
//in 64-bit mode as casting the pointer to an int causes a loss of precision.
|
|
||||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
|
||||||
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, tValue);
|
|
||||||
|
|
||||||
m_bIsUncompressedDataModified = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RunlengthEntry<uint16_t> rle;
|
|
||||||
rle.length = m_uSideLength*m_uSideLength*m_uSideLength;
|
|
||||||
rle.value = tValue;
|
|
||||||
m_vecCompressedData.clear();
|
|
||||||
m_vecCompressedData.push_back(rle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
//Debug mode validation
|
||||||
assert(isPowerOf2(uSideLength));
|
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
|
||||||
|
|
||||||
//Release mode validation
|
//Release mode validation
|
||||||
if(!isPowerOf2(uSideLength))
|
if(!isPowerOf2(uSideLength))
|
||||||
@ -139,55 +121,86 @@ namespace PolyVox
|
|||||||
m_uSideLength = uSideLength;
|
m_uSideLength = uSideLength;
|
||||||
m_uSideLengthPower = logBase2(uSideLength);
|
m_uSideLengthPower = logBase2(uSideLength);
|
||||||
|
|
||||||
Block<VoxelType>::fill(VoxelType());
|
//Create the block data
|
||||||
|
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||||
|
|
||||||
|
//Clear it (should we bother?)
|
||||||
|
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
|
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, VoxelType());
|
||||||
|
m_bIsUncompressedDataModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
uint32_t Block<VoxelType>::calculateSizeInBytes(void)
|
uint32_t Block<VoxelType>::calculateSizeInBytes(void)
|
||||||
{
|
{
|
||||||
|
//FIXME - This function is incomplete.
|
||||||
uint32_t uSizeInBytes = sizeof(Block<VoxelType>);
|
uint32_t uSizeInBytes = sizeof(Block<VoxelType>);
|
||||||
uSizeInBytes += m_vecCompressedData.capacity() * sizeof(RunlengthEntry<uint16_t>);
|
|
||||||
return uSizeInBytes;
|
return uSizeInBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::compress(void)
|
void Block<VoxelType>::compress(Compressor* pCompressor)
|
||||||
{
|
{
|
||||||
assert(m_bIsCompressed == false);
|
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
||||||
assert(m_tUncompressedData != 0);
|
POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed.");
|
||||||
|
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
|
||||||
|
|
||||||
//If the uncompressed data hasn't actually been
|
//If the uncompressed data hasn't actually been
|
||||||
//modified then we don't need to redo the compression.
|
//modified then we don't need to redo the compression.
|
||||||
if(m_bIsUncompressedDataModified)
|
if(m_bIsUncompressedDataModified)
|
||||||
{
|
{
|
||||||
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
// Delete the old compressed data as we'll create a new one
|
||||||
m_vecCompressedData.clear();
|
delete[] m_pCompressedData;
|
||||||
|
m_pCompressedData = 0;
|
||||||
|
|
||||||
RunlengthEntry<uint16_t> entry;
|
void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData);
|
||||||
entry.length = 1;
|
uint32_t uSrcLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||||
entry.value = m_tUncompressedData[0];
|
|
||||||
|
|
||||||
for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct)
|
uint8_t tempBuffer[10000];
|
||||||
|
void* pDstData = reinterpret_cast<void*>( tempBuffer );
|
||||||
|
uint32_t uDstLength = 10000;
|
||||||
|
|
||||||
|
uint32_t uCompressedLength = 0;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
VoxelType value = m_tUncompressedData[ct];
|
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||||
if((value == entry.value) && (entry.length < entry.maxRunlength()))
|
|
||||||
{
|
// Create new compressed data and copy across
|
||||||
entry.length++;
|
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
|
||||||
}
|
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||||
else
|
m_uCompressedDataLength = uCompressedLength;
|
||||||
{
|
|
||||||
m_vecCompressedData.push_back(entry);
|
|
||||||
entry.value = value;
|
|
||||||
entry.length = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch(std::exception&)
|
||||||
|
{
|
||||||
|
// It is possible for the compression to fail. A common cause for this would be if the destination
|
||||||
|
// buffer is not big enough. So now we try again using a buffer that is definitely big enough.
|
||||||
|
// Note that ideally we will choose our earlier buffer size so that this almost never happens.
|
||||||
|
uint32_t uMaxCompressedSize = pCompressor->getMaxCompressedSize(uSrcLength);
|
||||||
|
uint8_t* buffer = new uint8_t[ uMaxCompressedSize ];
|
||||||
|
|
||||||
m_vecCompressedData.push_back(entry);
|
pDstData = reinterpret_cast<void*>( buffer );
|
||||||
|
uDstLength = uMaxCompressedSize;
|
||||||
|
|
||||||
//Shrink the vectors to their contents (maybe slow?):
|
try
|
||||||
//http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector
|
{
|
||||||
//C++0x may have a shrink_to_fit() function?
|
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||||
std::vector< RunlengthEntry<uint16_t> >(m_vecCompressedData).swap(m_vecCompressedData);
|
|
||||||
|
// Create new compressed data and copy across
|
||||||
|
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
|
||||||
|
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||||
|
m_uCompressedDataLength = uCompressedLength;
|
||||||
|
}
|
||||||
|
catch(std::exception&)
|
||||||
|
{
|
||||||
|
// At this point it didn't work even with a bigger buffer.
|
||||||
|
// Not much more we can do so just rethrow the exception.
|
||||||
|
delete[] buffer;
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Failed to compress block data");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Flag the uncompressed data as no longer being used.
|
//Flag the uncompressed data as no longer being used.
|
||||||
@ -197,18 +210,26 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::uncompress(void)
|
void Block<VoxelType>::uncompress(Compressor* pCompressor)
|
||||||
{
|
{
|
||||||
assert(m_bIsCompressed == true);
|
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
||||||
assert(m_tUncompressedData == 0);
|
POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed.");
|
||||||
|
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
|
||||||
|
|
||||||
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||||
|
|
||||||
VoxelType* pUncompressedData = m_tUncompressedData;
|
void* pSrcData = reinterpret_cast<void*>(m_pCompressedData);
|
||||||
for(uint32_t ct = 0; ct < m_vecCompressedData.size(); ++ct)
|
void* pDstData = reinterpret_cast<void*>(m_tUncompressedData);
|
||||||
{
|
uint32_t uSrcLength = m_uCompressedDataLength;
|
||||||
std::fill(pUncompressedData, pUncompressedData + m_vecCompressedData[ct].length, m_vecCompressedData[ct].value);
|
uint32_t uDstLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||||
pUncompressedData += m_vecCompressedData[ct].length;
|
|
||||||
}
|
//MinizCompressor compressor;
|
||||||
|
//RLECompressor<VoxelType, uint16_t> compressor;
|
||||||
|
uint32_t uUncompressedLength = pCompressor->decompress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||||
|
|
||||||
|
POLYVOX_ASSERT(uUncompressedLength == m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType), "Destination length has changed.");
|
||||||
|
|
||||||
|
//m_tUncompressedData = reinterpret_cast<VoxelType*>(uncompressedResult.ptr);
|
||||||
|
|
||||||
m_bIsCompressed = false;
|
m_bIsCompressed = false;
|
||||||
m_bIsUncompressedDataModified = false;
|
m_bIsUncompressedDataModified = false;
|
||||||
|
@ -21,14 +21,14 @@ misrepresented as being the original software.
|
|||||||
distribution.
|
distribution.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <cassert>
|
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return
|
return
|
||||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||||
m_pDimensions+1, m_pOffsets+1);
|
m_pDimensions+1, m_pOffsets+1);
|
||||||
@ -37,7 +37,7 @@ namespace PolyVox
|
|||||||
template <uint32_t noOfDims, typename ElementType>
|
template <uint32_t noOfDims, typename ElementType>
|
||||||
const SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
const SubArray<noOfDims-1, ElementType> SubArray<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return
|
return
|
||||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||||
m_pDimensions+1, m_pOffsets+1);
|
m_pDimensions+1, m_pOffsets+1);
|
||||||
@ -56,14 +56,14 @@ namespace PolyVox
|
|||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
|
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
const ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex) const
|
const ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex) const
|
||||||
{
|
{
|
||||||
assert(uIndex<m_pDimensions[0]);
|
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "PolyVoxCore/Impl/TypeDef.h"
|
#include "PolyVoxCore/Impl/TypeDef.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
POLYVOX_API uint8_t logBase2(uint32_t uInput);
|
POLYVOX_API uint8_t logBase2(uint32_t uInput);
|
||||||
|
4766
library/PolyVoxCore/include/PolyVoxCore/Impl/miniz.c
Normal file
4766
library/PolyVoxCore/include/PolyVoxCore/Impl/miniz.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -24,8 +24,6 @@ freely, subject to the following restrictions:
|
|||||||
#ifndef __PolyVox_Interpolation_H__
|
#ifndef __PolyVox_Interpolation_H__
|
||||||
#define __PolyVox_Interpolation_H__
|
#define __PolyVox_Interpolation_H__
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
@ -33,7 +31,7 @@ namespace PolyVox
|
|||||||
const Type& v0,const Type& v1,
|
const Type& v0,const Type& v1,
|
||||||
const float x)
|
const float x)
|
||||||
{
|
{
|
||||||
assert((x >= 0.0f) && (x <= 1.0f));
|
POLYVOX_ASSERT((x >= 0.0f) && (x <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
//Interpolate along X
|
//Interpolate along X
|
||||||
Type v0_1 = (v1 - v0) * x + v0;
|
Type v0_1 = (v1 - v0) * x + v0;
|
||||||
@ -46,8 +44,8 @@ namespace PolyVox
|
|||||||
const Type& v00,const Type& v10,const Type& v01,const Type& v11,
|
const Type& v00,const Type& v10,const Type& v01,const Type& v11,
|
||||||
const float x, const float y)
|
const float x, const float y)
|
||||||
{
|
{
|
||||||
assert((x >= 0.0f) && (y >= 0.0f) &&
|
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) &&
|
||||||
(x <= 1.0f) && (y <= 1.0f));
|
(x <= 1.0f) && (y <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
// Linearly interpolate along x
|
// Linearly interpolate along x
|
||||||
Type v00_10 = lerp(v00, v10, x);
|
Type v00_10 = lerp(v00, v10, x);
|
||||||
@ -65,8 +63,8 @@ namespace PolyVox
|
|||||||
const Type& v001,const Type& v101,const Type& v011,const Type& v111,
|
const Type& v001,const Type& v101,const Type& v011,const Type& v111,
|
||||||
const float x, const float y, const float z)
|
const float x, const float y, const float z)
|
||||||
{
|
{
|
||||||
assert((x >= 0.0f) && (y >= 0.0f) && (z >= 0.0f) &&
|
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) && (z >= 0.0f) &&
|
||||||
(x <= 1.0f) && (y <= 1.0f) && (z <= 1.0f));
|
(x <= 1.0f) && (y <= 1.0f) && (z <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
// Bilinearly interpolate along Y
|
// Bilinearly interpolate along Y
|
||||||
Type v000_v100__v010_v110 = bilerp(v000, v100, v010, v110, x, y);
|
Type v000_v100__v010_v110 = bilerp(v000, v100, v010, v110, x, y);
|
||||||
|
@ -26,12 +26,12 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "PolyVoxCore/BaseVolume.h"
|
#include "PolyVoxCore/BaseVolume.h"
|
||||||
#include "Impl/Block.h"
|
#include "Impl/Block.h"
|
||||||
|
#include "PolyVoxCore/Compressor.h"
|
||||||
#include "PolyVoxCore/Log.h"
|
#include "PolyVoxCore/Log.h"
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cassert>
|
|
||||||
#include <cstdlib> //For abort()
|
#include <cstdlib> //For abort()
|
||||||
#include <cstring> //For memcpy
|
#include <cstring> //For memcpy
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -257,6 +257,7 @@ namespace PolyVox
|
|||||||
LargeVolume
|
LargeVolume
|
||||||
(
|
(
|
||||||
const Region& regValid,
|
const Region& regValid,
|
||||||
|
Compressor* pCompressor = 0,
|
||||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
|
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
|
||||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
|
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
|
||||||
bool bPagingEnabled = false,
|
bool bPagingEnabled = false,
|
||||||
@ -278,8 +279,6 @@ namespace PolyVox
|
|||||||
/// Gets a voxel at the position given by a 3D vector
|
/// Gets a voxel at the position given by a 3D vector
|
||||||
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType(0)) const;
|
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType(0)) const;
|
||||||
|
|
||||||
//Sets whether or not blocks are compressed in memory
|
|
||||||
void setCompressionEnabled(bool bCompressionEnabled);
|
|
||||||
/// Sets the number of blocks for which uncompressed data is stored
|
/// Sets the number of blocks for which uncompressed data is stored
|
||||||
void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks);
|
void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks);
|
||||||
/// Sets the number of blocks which can be in memory before the paging system starts unloading them
|
/// Sets the number of blocks which can be in memory before the paging system starts unloading them
|
||||||
@ -313,7 +312,7 @@ namespace PolyVox
|
|||||||
|
|
||||||
struct BlockPositionCompare
|
struct BlockPositionCompare
|
||||||
{
|
{
|
||||||
bool operator() (const PolyVox::Vector3DInt32& a, const PolyVox::Vector3DInt32& b)
|
bool operator() (const PolyVox::Vector3DInt32& a, const PolyVox::Vector3DInt32& b) const
|
||||||
{
|
{
|
||||||
const uint32_t size = 3;
|
const uint32_t size = 3;
|
||||||
for(uint32_t ct = 0; ct < size; ++ct)
|
for(uint32_t ct = 0; ct < size; ++ct)
|
||||||
@ -364,7 +363,9 @@ namespace PolyVox
|
|||||||
uint16_t m_uBlockSideLength;
|
uint16_t m_uBlockSideLength;
|
||||||
uint8_t m_uBlockSideLengthPower;
|
uint8_t m_uBlockSideLengthPower;
|
||||||
|
|
||||||
bool m_bCompressionEnabled;
|
//The compressor used by the Blocks to compress their data if required.
|
||||||
|
Compressor* m_pCompressor;
|
||||||
|
|
||||||
bool m_bPagingEnabled;
|
bool m_bPagingEnabled;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ namespace PolyVox
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// This constructor creates a volume with a fixed size which is specified as a parameter. By default this constructor will not enable paging but you can override this if desired. If you do wish to enable paging then you are required to provide the call back function (see the other LargeVolume constructor).
|
/// This constructor creates a volume with a fixed size which is specified as a parameter. By default this constructor will not enable paging but you can override this if desired. If you do wish to enable paging then you are required to provide the call back function (see the other LargeVolume constructor).
|
||||||
/// \param regValid Specifies the minimum and maximum valid voxel positions.
|
/// \param regValid Specifies the minimum and maximum valid voxel positions.
|
||||||
|
/// \param pCompressor An implementation of the Compressor interface which is used to compress blocks in memory.
|
||||||
/// \param dataRequiredHandler The callback function which will be called when PolyVox tries to use data which is not currently in momory.
|
/// \param dataRequiredHandler The callback function which will be called when PolyVox tries to use data which is not currently in momory.
|
||||||
/// \param dataOverflowHandler The callback function which will be called when PolyVox has too much data and needs to remove some from memory.
|
/// \param dataOverflowHandler The callback function which will be called when PolyVox has too much data and needs to remove some from memory.
|
||||||
/// \param bPagingEnabled Controls whether or not paging is enabled for this LargeVolume.
|
/// \param bPagingEnabled Controls whether or not paging is enabled for this LargeVolume.
|
||||||
@ -62,12 +63,14 @@ namespace PolyVox
|
|||||||
LargeVolume<VoxelType>::LargeVolume
|
LargeVolume<VoxelType>::LargeVolume
|
||||||
(
|
(
|
||||||
const Region& regValid,
|
const Region& regValid,
|
||||||
|
Compressor* pCompressor,
|
||||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
|
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
|
||||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
|
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
|
||||||
bool bPagingEnabled,
|
bool bPagingEnabled,
|
||||||
uint16_t uBlockSideLength
|
uint16_t uBlockSideLength
|
||||||
)
|
)
|
||||||
:BaseVolume<VoxelType>(regValid)
|
:BaseVolume<VoxelType>(regValid)
|
||||||
|
,m_pCompressor(pCompressor)
|
||||||
{
|
{
|
||||||
m_funcDataRequiredHandler = dataRequiredHandler;
|
m_funcDataRequiredHandler = dataRequiredHandler;
|
||||||
m_funcDataOverflowHandler = dataOverflowHandler;
|
m_funcDataOverflowHandler = dataOverflowHandler;
|
||||||
@ -80,14 +83,14 @@ namespace PolyVox
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
|
/// This function should never be called. Copying volumes by value would be expensive, and we want to prevent users from doing
|
||||||
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
|
/// it by accident (such as when passing them as paramenters to functions). That said, there are times when you really do want to
|
||||||
/// make a copy of a volume and in this case you should look at the Volumeresampler.
|
/// make a copy of a volume and in this case you should look at the VolumeResampler.
|
||||||
///
|
///
|
||||||
/// \sa VolumeResampler
|
/// \sa VolumeResampler
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
|
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -109,7 +112,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
LargeVolume<VoxelType>& LargeVolume<VoxelType>::operator=(const LargeVolume<VoxelType>& /*rhs*/)
|
LargeVolume<VoxelType>& LargeVolume<VoxelType>::operator=(const LargeVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -121,7 +124,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
|
|
||||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||||
@ -225,7 +228,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Invlaid case.");
|
||||||
return VoxelType(0);
|
return VoxelType(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,30 +244,6 @@ namespace PolyVox
|
|||||||
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Enabling compression allows significantly more data to be stored in memory.
|
|
||||||
/// \param bCompressionEnabled Specifies whether compression is enabled.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename VoxelType>
|
|
||||||
void LargeVolume<VoxelType>::setCompressionEnabled(bool bCompressionEnabled)
|
|
||||||
{
|
|
||||||
//Early out - nothing to do
|
|
||||||
if(m_bCompressionEnabled == bCompressionEnabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bCompressionEnabled = bCompressionEnabled;
|
|
||||||
|
|
||||||
if(m_bCompressionEnabled)
|
|
||||||
{
|
|
||||||
//If compression has been enabled then we need to start honouring the max number of
|
|
||||||
//uncompressed blocks. Because compression has been disabled for a while we might have
|
|
||||||
//gone above that limit. Easiest solution is just to clear the cache and start again.
|
|
||||||
clearBlockCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Increasing the size of the block cache will increase memory but may improve performance.
|
/// Increasing the size of the block cache will increase memory but may improve performance.
|
||||||
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
|
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
|
||||||
@ -303,7 +282,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
bool LargeVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
bool LargeVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||||
{
|
{
|
||||||
assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
|
|
||||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||||
@ -456,7 +435,7 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
||||||
{
|
{
|
||||||
m_vecUncompressedBlockCache[ct]->block.compress();
|
m_vecUncompressedBlockCache[ct]->block.compress(m_pCompressor);
|
||||||
}
|
}
|
||||||
m_vecUncompressedBlockCache.clear();
|
m_vecUncompressedBlockCache.clear();
|
||||||
}
|
}
|
||||||
@ -468,7 +447,9 @@ namespace PolyVox
|
|||||||
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
//Debug mode validation
|
||||||
assert(uBlockSideLength > 0);
|
POLYVOX_ASSERT(uBlockSideLength > 0, "Block side length cannot be zero.");
|
||||||
|
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
|
||||||
|
POLYVOX_ASSERT(m_pCompressor, "You must provide a compressor for the LargeVolume to use.");
|
||||||
|
|
||||||
//Release mode validation
|
//Release mode validation
|
||||||
if(uBlockSideLength == 0)
|
if(uBlockSideLength == 0)
|
||||||
@ -479,6 +460,10 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two.");
|
POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two.");
|
||||||
}
|
}
|
||||||
|
if(!m_pCompressor)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "You must provide a compressor for the LargeVolume to use.");
|
||||||
|
}
|
||||||
|
|
||||||
m_uTimestamper = 0;
|
m_uTimestamper = 0;
|
||||||
m_uMaxNumberOfUncompressedBlocks = 16;
|
m_uMaxNumberOfUncompressedBlocks = 16;
|
||||||
@ -486,7 +471,6 @@ namespace PolyVox
|
|||||||
m_uMaxNumberOfBlocksInMemory = 1024;
|
m_uMaxNumberOfBlocksInMemory = 1024;
|
||||||
m_v3dLastAccessedBlockPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedBlock pointer will be null;
|
m_v3dLastAccessedBlockPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedBlock pointer will be null;
|
||||||
m_pLastAccessedBlock = 0;
|
m_pLastAccessedBlock = 0;
|
||||||
m_bCompressionEnabled = true;
|
|
||||||
|
|
||||||
this->m_regValidRegion = regValidRegion;
|
this->m_regValidRegion = regValidRegion;
|
||||||
|
|
||||||
@ -529,14 +513,15 @@ namespace PolyVox
|
|||||||
|
|
||||||
m_funcDataOverflowHandler(ConstVolumeProxy, reg);
|
m_funcDataOverflowHandler(ConstVolumeProxy, reg);
|
||||||
}
|
}
|
||||||
if(m_bCompressionEnabled) {
|
if(m_pCompressor)
|
||||||
|
{
|
||||||
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
||||||
{
|
{
|
||||||
// find the block in the uncompressed cache
|
// find the block in the uncompressed cache
|
||||||
if(m_vecUncompressedBlockCache[ct] == &(itBlock->second))
|
if(m_vecUncompressedBlockCache[ct] == &(itBlock->second))
|
||||||
{
|
{
|
||||||
// TODO: compression is unneccessary? or will not compressing this cause a memleak?
|
// TODO: compression is unneccessary? or will not compressing this cause a memleak?
|
||||||
itBlock->second.block.compress();
|
itBlock->second.block.compress(m_pCompressor);
|
||||||
// put last object in cache here
|
// put last object in cache here
|
||||||
m_vecUncompressedBlockCache[ct] = m_vecUncompressedBlockCache.back();
|
m_vecUncompressedBlockCache[ct] = m_vecUncompressedBlockCache.back();
|
||||||
// decrease cache size by one since last element is now in here twice
|
// decrease cache size by one since last element is now in here twice
|
||||||
@ -583,7 +568,7 @@ namespace PolyVox
|
|||||||
//This check should also provide a significant speed boost as usually it is true.
|
//This check should also provide a significant speed boost as usually it is true.
|
||||||
if((v3dBlockPos == m_v3dLastAccessedBlockPos) && (m_pLastAccessedBlock != 0))
|
if((v3dBlockPos == m_v3dLastAccessedBlockPos) && (m_pLastAccessedBlock != 0))
|
||||||
{
|
{
|
||||||
assert(m_pLastAccessedBlock->m_tUncompressedData);
|
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||||
return m_pLastAccessedBlock;
|
return m_pLastAccessedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,6 +600,12 @@ namespace PolyVox
|
|||||||
|
|
||||||
// create the new block
|
// create the new block
|
||||||
LoadedBlock newBlock(m_uBlockSideLength);
|
LoadedBlock newBlock(m_uBlockSideLength);
|
||||||
|
|
||||||
|
// Blocks start out compressed - should we change this?
|
||||||
|
// Or maybe we should just 'seed' them with compressed data,
|
||||||
|
// rather than creating an empty block and then compressing?
|
||||||
|
newBlock.block.compress(m_pCompressor);
|
||||||
|
|
||||||
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
||||||
|
|
||||||
//We have created the new block. If paging is enabled it should be used to
|
//We have created the new block. If paging is enabled it should be used to
|
||||||
@ -643,12 +634,12 @@ namespace PolyVox
|
|||||||
|
|
||||||
if(loadedBlock.block.m_bIsCompressed == false)
|
if(loadedBlock.block.m_bIsCompressed == false)
|
||||||
{
|
{
|
||||||
assert(m_pLastAccessedBlock->m_tUncompressedData);
|
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||||
return m_pLastAccessedBlock;
|
return m_pLastAccessedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we are allowed to compress then check whether we need to
|
//If we are allowed to compress then check whether we need to
|
||||||
if((m_bCompressionEnabled) && (m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks))
|
if((m_pCompressor) && (m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks))
|
||||||
{
|
{
|
||||||
int32_t leastRecentlyUsedBlockIndex = -1;
|
int32_t leastRecentlyUsedBlockIndex = -1;
|
||||||
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)();
|
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)();
|
||||||
@ -666,7 +657,7 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Compress the least recently used block.
|
//Compress the least recently used block.
|
||||||
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress();
|
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress(m_pCompressor);
|
||||||
|
|
||||||
//We don't actually remove any elements from this vector, we
|
//We don't actually remove any elements from this vector, we
|
||||||
//simply change the pointer to point at the new uncompressed bloack.
|
//simply change the pointer to point at the new uncompressed bloack.
|
||||||
@ -677,10 +668,10 @@ namespace PolyVox
|
|||||||
m_vecUncompressedBlockCache.push_back(&loadedBlock);
|
m_vecUncompressedBlockCache.push_back(&loadedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedBlock.block.uncompress();
|
loadedBlock.block.uncompress(m_pCompressor);
|
||||||
|
|
||||||
m_pLastAccessedBlock = &(loadedBlock.block);
|
m_pLastAccessedBlock = &(loadedBlock.block);
|
||||||
assert(m_pLastAccessedBlock->m_tUncompressedData);
|
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||||
return m_pLastAccessedBlock;
|
return m_pLastAccessedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ namespace PolyVox
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
//Need to think what effect this has on any existing iterators.
|
//Need to think what effect this has on any existing iterators.
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "This function cnnot be used on LargeVolume samplers.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,11 @@ namespace PolyVox
|
|||||||
,m_uKernelSize(uKernelSize)
|
,m_uKernelSize(uKernelSize)
|
||||||
{
|
{
|
||||||
//Kernel size must be at least three
|
//Kernel size must be at least three
|
||||||
assert(m_uKernelSize >= 3);
|
POLYVOX_ASSERT(m_uKernelSize >= 3, "Kernel size must be at least three");
|
||||||
m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3)); //For release builds
|
m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3)); //For release builds
|
||||||
|
|
||||||
//Kernel size must be odd
|
//Kernel size must be odd
|
||||||
assert(m_uKernelSize % 2 == 1);
|
POLYVOX_ASSERT(m_uKernelSize % 2 == 1, "Kernel size must be odd");
|
||||||
if(m_uKernelSize % 2 == 0) //For release builds
|
if(m_uKernelSize % 2 == 0) //For release builds
|
||||||
{
|
{
|
||||||
m_uKernelSize++;
|
m_uKernelSize++;
|
||||||
|
@ -570,62 +570,50 @@ namespace PolyVox
|
|||||||
if (edgeTable[iCubeIndex] & 1)
|
if (edgeTable[iCubeIndex] & 1)
|
||||||
{
|
{
|
||||||
indlist[0] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace];
|
indlist[0] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace];
|
||||||
//assert(indlist[0] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 2)
|
if (edgeTable[iCubeIndex] & 2)
|
||||||
{
|
{
|
||||||
indlist[1] = m_pPreviousVertexIndicesY[uXRegSpace+1][uYRegSpace];
|
indlist[1] = m_pPreviousVertexIndicesY[uXRegSpace+1][uYRegSpace];
|
||||||
//assert(indlist[1] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 4)
|
if (edgeTable[iCubeIndex] & 4)
|
||||||
{
|
{
|
||||||
indlist[2] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace+1];
|
indlist[2] = m_pPreviousVertexIndicesX[uXRegSpace][uYRegSpace+1];
|
||||||
//assert(indlist[2] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 8)
|
if (edgeTable[iCubeIndex] & 8)
|
||||||
{
|
{
|
||||||
indlist[3] = m_pPreviousVertexIndicesY[uXRegSpace][uYRegSpace];
|
indlist[3] = m_pPreviousVertexIndicesY[uXRegSpace][uYRegSpace];
|
||||||
//assert(indlist[3] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 16)
|
if (edgeTable[iCubeIndex] & 16)
|
||||||
{
|
{
|
||||||
indlist[4] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace];
|
indlist[4] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace];
|
||||||
//assert(indlist[4] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 32)
|
if (edgeTable[iCubeIndex] & 32)
|
||||||
{
|
{
|
||||||
indlist[5] = m_pCurrentVertexIndicesY[uXRegSpace+1][uYRegSpace];
|
indlist[5] = m_pCurrentVertexIndicesY[uXRegSpace+1][uYRegSpace];
|
||||||
//assert(indlist[5] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 64)
|
if (edgeTable[iCubeIndex] & 64)
|
||||||
{
|
{
|
||||||
indlist[6] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace+1];
|
indlist[6] = m_pCurrentVertexIndicesX[uXRegSpace][uYRegSpace+1];
|
||||||
//assert(indlist[6] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 128)
|
if (edgeTable[iCubeIndex] & 128)
|
||||||
{
|
{
|
||||||
indlist[7] = m_pCurrentVertexIndicesY[uXRegSpace][uYRegSpace];
|
indlist[7] = m_pCurrentVertexIndicesY[uXRegSpace][uYRegSpace];
|
||||||
//assert(indlist[7] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 256)
|
if (edgeTable[iCubeIndex] & 256)
|
||||||
{
|
{
|
||||||
indlist[8] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace];
|
indlist[8] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace];
|
||||||
//assert(indlist[8] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 512)
|
if (edgeTable[iCubeIndex] & 512)
|
||||||
{
|
{
|
||||||
indlist[9] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace];
|
indlist[9] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace];
|
||||||
//assert(indlist[9] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 1024)
|
if (edgeTable[iCubeIndex] & 1024)
|
||||||
{
|
{
|
||||||
indlist[10] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace+1];
|
indlist[10] = m_pPreviousVertexIndicesZ[uXRegSpace+1][uYRegSpace+1];
|
||||||
//assert(indlist[10] != -1);
|
|
||||||
}
|
}
|
||||||
if (edgeTable[iCubeIndex] & 2048)
|
if (edgeTable[iCubeIndex] & 2048)
|
||||||
{
|
{
|
||||||
indlist[11] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace+1];
|
indlist[11] = m_pPreviousVertexIndicesZ[uXRegSpace][uYRegSpace+1];
|
||||||
//assert(indlist[11] != -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3)
|
for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3)
|
||||||
|
@ -28,8 +28,6 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "PolyVoxCore/DefaultIsQuadNeeded.h" //we'll specialise this function for this voxel type
|
#include "PolyVoxCore/DefaultIsQuadNeeded.h" //we'll specialise this function for this voxel type
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
///This class represents a voxel storing only a material.
|
///This class represents a voxel storing only a material.
|
||||||
|
20
library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h
Normal file
20
library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef __PolyVox_MinizCompressor_H__
|
||||||
|
#define __PolyVox_MinizCompressor_H__
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Compressor.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
class MinizCompressor : public Compressor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MinizCompressor();
|
||||||
|
~MinizCompressor();
|
||||||
|
|
||||||
|
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||||
|
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
|
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__PolyVox_MinizCompressor_H__
|
@ -60,6 +60,11 @@ namespace PolyVox
|
|||||||
typedef Array<3,int32_t> Array3DInt32;
|
typedef Array<3,int32_t> Array3DInt32;
|
||||||
typedef Array<3,uint32_t> Array3DUint32;
|
typedef Array<3,uint32_t> Array3DUint32;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Compressor
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
class Compressor;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// CubicSurfaceExtractor
|
// CubicSurfaceExtractor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
28
library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h
Normal file
28
library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __PolyVox_RLECompressor_H__
|
||||||
|
#define __PolyVox_RLECompressor_H__
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Compressor.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
class RLECompressor : public Compressor
|
||||||
|
{
|
||||||
|
struct Run
|
||||||
|
{
|
||||||
|
ValueType value;
|
||||||
|
LengthType length;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
RLECompressor();
|
||||||
|
~RLECompressor();
|
||||||
|
|
||||||
|
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||||
|
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
|
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "RLECompressor.inl"
|
||||||
|
|
||||||
|
#endif //__PolyVox_RLECompressor_H__
|
126
library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl
Normal file
126
library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
RLECompressor<ValueType, LengthType>::RLECompressor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
RLECompressor<ValueType, LengthType>::~RLECompressor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
uint32_t RLECompressor<ValueType, LengthType>::getMaxCompressedSize(uint32_t uUncompressedInputSize)
|
||||||
|
{
|
||||||
|
// In the worst case we will have a seperate Run (of length one) for each element of the input data.
|
||||||
|
return uUncompressedInputSize * sizeof(Run);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
uint32_t RLECompressor<ValueType, LengthType>::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
|
{
|
||||||
|
if(uSrcLength % sizeof(ValueType) != 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the ValueType size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lengths provided are in bytes, so convert them to be in terms of our types.
|
||||||
|
uSrcLength /= sizeof(ValueType);
|
||||||
|
uDstLength /= sizeof(Run);
|
||||||
|
|
||||||
|
// Get data pointers in the appropriate type
|
||||||
|
ValueType* pSrcDataAsType = reinterpret_cast<ValueType*>(pSrcData);
|
||||||
|
Run* pDstDataAsRun = reinterpret_cast<Run*>(pDstData);
|
||||||
|
|
||||||
|
// Pointers to just past the end of the data
|
||||||
|
ValueType* pSrcDataEnd = pSrcDataAsType + uSrcLength;
|
||||||
|
Run* pDstDataEnd = pDstDataAsRun + uDstLength;
|
||||||
|
|
||||||
|
//Counter for the output length
|
||||||
|
uint32_t uDstLengthInBytes = 0;
|
||||||
|
|
||||||
|
// Read the first element of the source and set up the first run based on it.
|
||||||
|
pDstDataAsRun->value = *pSrcDataAsType;
|
||||||
|
pSrcDataAsType++;
|
||||||
|
pDstDataAsRun->length = 1;
|
||||||
|
uDstLengthInBytes += sizeof(Run);
|
||||||
|
|
||||||
|
//Now process all remaining elements of the source.
|
||||||
|
while(pSrcDataAsType < pSrcDataEnd)
|
||||||
|
{
|
||||||
|
// If the value is the same as the current run (and we have not
|
||||||
|
// reached the maximum run length) then extend the current run.
|
||||||
|
if((*pSrcDataAsType == pDstDataAsRun->value) && (pDstDataAsRun->length < (std::numeric_limits<LengthType>::max)()))
|
||||||
|
{
|
||||||
|
pDstDataAsRun->length++;
|
||||||
|
}
|
||||||
|
// Otherwise we need to start a new Run.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pDstDataAsRun++;
|
||||||
|
|
||||||
|
// Check if we have enough space in the destination buffer.
|
||||||
|
if(pDstDataAsRun >= pDstDataEnd)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Insufficient space in destination buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new run.
|
||||||
|
pDstDataAsRun->value = *pSrcDataAsType;
|
||||||
|
pDstDataAsRun->length = 1;
|
||||||
|
uDstLengthInBytes += sizeof(Run);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrcDataAsType++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uDstLengthInBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
uint32_t RLECompressor<ValueType, LengthType>::decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
|
{
|
||||||
|
if(uSrcLength % sizeof(Run) != 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the Run size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lengths provided are in bytes, so convert them to be in terms of our types.
|
||||||
|
uSrcLength /= sizeof(Run);
|
||||||
|
uDstLength /= sizeof(ValueType);
|
||||||
|
|
||||||
|
// Get data pointers in the appropriate type
|
||||||
|
Run* pSrcDataAsRun = reinterpret_cast<Run*>(pSrcData);
|
||||||
|
ValueType* pDstDataAsType = reinterpret_cast<ValueType*>(pDstData);
|
||||||
|
|
||||||
|
// Pointers to just past the end of the data
|
||||||
|
Run* pSrcDataEnd = pSrcDataAsRun + uSrcLength;
|
||||||
|
ValueType* pDstDataEnd = pDstDataAsType + uDstLength;
|
||||||
|
|
||||||
|
//Counter for the output length
|
||||||
|
uint32_t uDstLengthInBytes = 0;
|
||||||
|
|
||||||
|
while(pSrcDataAsRun < pSrcDataEnd)
|
||||||
|
{
|
||||||
|
// Check if we have enough space in the destination buffer.
|
||||||
|
if(pDstDataAsType + pSrcDataAsRun->length > pDstDataEnd)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Insufficient space in destination buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the run into the destination
|
||||||
|
std::fill(pDstDataAsType, pDstDataAsType + pSrcDataAsRun->length, pSrcDataAsRun->value);
|
||||||
|
pDstDataAsType += pSrcDataAsRun->length;
|
||||||
|
|
||||||
|
uDstLengthInBytes += pSrcDataAsRun->length * sizeof(ValueType);
|
||||||
|
pSrcDataAsRun++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uDstLengthInBytes;
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,6 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdlib> //For abort()
|
#include <cstdlib> //For abort()
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -47,7 +47,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
RawVolume<VoxelType>::RawVolume(const RawVolume<VoxelType>& /*rhs*/)
|
RawVolume<VoxelType>::RawVolume(const RawVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -70,7 +70,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
RawVolume<VoxelType>& RawVolume<VoxelType>::operator=(const RawVolume<VoxelType>& /*rhs*/)
|
RawVolume<VoxelType>& RawVolume<VoxelType>::operator=(const RawVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -82,7 +82,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
|
|
||||||
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
|
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
|
||||||
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
|
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
|
||||||
@ -186,7 +186,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Invalid case.");
|
||||||
return VoxelType(0);
|
return VoxelType(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,9 +255,9 @@ namespace PolyVox
|
|||||||
this->m_regValidRegion = regValidRegion;
|
this->m_regValidRegion = regValidRegion;
|
||||||
|
|
||||||
//Ensure dimensions of the specified Region are valid
|
//Ensure dimensions of the specified Region are valid
|
||||||
assert(this->getWidth() > 0);
|
POLYVOX_ASSERT(this->getWidth() > 0, "Volume width must be greater than zero.");
|
||||||
assert(this->getHeight() > 0);
|
POLYVOX_ASSERT(this->getHeight() > 0, "Volume width must be greater than zero.");
|
||||||
assert(this->getDepth() > 0);
|
POLYVOX_ASSERT(this->getDepth() > 0, "Volume width must be greater than zero.");
|
||||||
|
|
||||||
//Create the data
|
//Create the data
|
||||||
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];
|
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];
|
||||||
|
@ -31,7 +31,6 @@ freely, subject to the following restrictions:
|
|||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdlib> //For abort()
|
#include <cstdlib> //For abort()
|
||||||
#include <cstring> //For memcpy
|
#include <cstring> //For memcpy
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -48,7 +48,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
SimpleVolume<VoxelType>::SimpleVolume(const SimpleVolume<VoxelType>& /*rhs*/)
|
SimpleVolume<VoxelType>::SimpleVolume(const SimpleVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -70,7 +70,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
SimpleVolume<VoxelType>& SimpleVolume<VoxelType>::operator=(const SimpleVolume<VoxelType>& /*rhs*/)
|
SimpleVolume<VoxelType>& SimpleVolume<VoxelType>::operator=(const SimpleVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
assert(false); // See function comment above.
|
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -82,7 +82,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
|
|
||||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||||
@ -186,7 +186,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
assert(false);
|
POLYVOX_ASSERT(false, "Invalid case.");
|
||||||
return VoxelType(0);
|
return VoxelType(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
bool SimpleVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
bool SimpleVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
|
||||||
{
|
{
|
||||||
assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||||
|
|
||||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||||
@ -248,9 +248,9 @@ namespace PolyVox
|
|||||||
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
//Debug mode validation
|
||||||
assert(uBlockSideLength >= 8);
|
POLYVOX_ASSERT(uBlockSideLength >= 8, "Block side length should be at least 8");
|
||||||
assert(uBlockSideLength <= 256);
|
POLYVOX_ASSERT(uBlockSideLength <= 256, "Block side length should not be more than 256");
|
||||||
assert(isPowerOf2(uBlockSideLength));
|
POLYVOX_ASSERT(isPowerOf2(uBlockSideLength), "Block side length must be a power of two.");
|
||||||
|
|
||||||
//Release mode validation
|
//Release mode validation
|
||||||
if(uBlockSideLength < 8)
|
if(uBlockSideLength < 8)
|
||||||
@ -308,9 +308,9 @@ namespace PolyVox
|
|||||||
uBlockY -= m_regValidRegionInBlocks.getLowerCorner().getY();
|
uBlockY -= m_regValidRegionInBlocks.getLowerCorner().getY();
|
||||||
uBlockZ -= m_regValidRegionInBlocks.getLowerCorner().getZ();
|
uBlockZ -= m_regValidRegionInBlocks.getLowerCorner().getZ();
|
||||||
|
|
||||||
assert(uBlockX >= 0);
|
POLYVOX_ASSERT(uBlockX >= 0, "Block coordinate must not be negative.");
|
||||||
assert(uBlockY >= 0);
|
POLYVOX_ASSERT(uBlockY >= 0, "Block coordinate must not be negative.");
|
||||||
assert(uBlockZ >= 0);
|
POLYVOX_ASSERT(uBlockZ >= 0, "Block coordinate must not be negative.");
|
||||||
|
|
||||||
//Compute the block index
|
//Compute the block index
|
||||||
uint32_t uBlockIndex =
|
uint32_t uBlockIndex =
|
||||||
|
@ -52,11 +52,11 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType SimpleVolume<VoxelType>::Block::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
VoxelType SimpleVolume<VoxelType>::Block::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||||
{
|
{
|
||||||
assert(uXPos < m_uSideLength);
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||||
assert(uYPos < m_uSideLength);
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||||
assert(uZPos < m_uSideLength);
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||||
|
|
||||||
assert(m_tUncompressedData);
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||||
|
|
||||||
return m_tUncompressedData
|
return m_tUncompressedData
|
||||||
[
|
[
|
||||||
@ -75,11 +75,11 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void SimpleVolume<VoxelType>::Block::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
void SimpleVolume<VoxelType>::Block::setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
||||||
{
|
{
|
||||||
assert(uXPos < m_uSideLength);
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||||
assert(uYPos < m_uSideLength);
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||||
assert(uZPos < m_uSideLength);
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||||
|
|
||||||
assert(m_tUncompressedData);
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||||
|
|
||||||
m_tUncompressedData
|
m_tUncompressedData
|
||||||
[
|
[
|
||||||
@ -106,7 +106,7 @@ namespace PolyVox
|
|||||||
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
|
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
//Debug mode validation
|
||||||
assert(isPowerOf2(uSideLength));
|
POLYVOX_ASSERT(isPowerOf2(uSideLength), "Block side length must be a power of two.");
|
||||||
|
|
||||||
//Release mode validation
|
//Release mode validation
|
||||||
if(!isPowerOf2(uSideLength))
|
if(!isPowerOf2(uSideLength))
|
||||||
|
@ -21,8 +21,6 @@ freely, subject to the following restrictions:
|
|||||||
distribution.
|
distribution.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
@ -103,9 +101,9 @@ namespace PolyVox
|
|||||||
void SurfaceMesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
|
void SurfaceMesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
|
||||||
{
|
{
|
||||||
//Make sure the specified indices correspond to valid vertices.
|
//Make sure the specified indices correspond to valid vertices.
|
||||||
assert(index0 < m_vecVertices.size());
|
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
assert(index1 < m_vecVertices.size());
|
POLYVOX_ASSERT(index1 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
assert(index2 < m_vecVertices.size());
|
POLYVOX_ASSERT(index2 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
|
|
||||||
m_vecTriangleIndices.push_back(index0);
|
m_vecTriangleIndices.push_back(index0);
|
||||||
m_vecTriangleIndices.push_back(index1);
|
m_vecTriangleIndices.push_back(index1);
|
||||||
@ -116,9 +114,9 @@ namespace PolyVox
|
|||||||
void SurfaceMesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2)
|
void SurfaceMesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2)
|
||||||
{
|
{
|
||||||
//Make sure the specified indices correspond to valid vertices.
|
//Make sure the specified indices correspond to valid vertices.
|
||||||
assert(index0 < m_vecVertices.size());
|
POLYVOX_ASSERT(index0 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
assert(index1 < m_vecVertices.size());
|
POLYVOX_ASSERT(index1 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
assert(index2 < m_vecVertices.size());
|
POLYVOX_ASSERT(index2 < m_vecVertices.size(), "Index points at an invalid vertex.");
|
||||||
|
|
||||||
m_vecTriangleIndices.push_back(index0);
|
m_vecTriangleIndices.push_back(index0);
|
||||||
m_vecTriangleIndices.push_back(index1);
|
m_vecTriangleIndices.push_back(index1);
|
||||||
@ -408,7 +406,7 @@ namespace PolyVox
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(inputMesh.m_vecLodRecords.size() == 1);
|
POLYVOX_ASSERT(inputMesh.m_vecLodRecords.size() == 1, "Number of LOD records must equal one.");
|
||||||
if(inputMesh.m_vecLodRecords.size() != 1)
|
if(inputMesh.m_vecLodRecords.size() != 1)
|
||||||
{
|
{
|
||||||
//If we have done progressive LOD then it's too late to split into subsets.
|
//If we have done progressive LOD then it's too late to split into subsets.
|
||||||
|
68
library/PolyVoxCore/source/MinizCompressor.cpp
Normal file
68
library/PolyVoxCore/source/MinizCompressor.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "PolyVoxCore/MinizCompressor.h"
|
||||||
|
|
||||||
|
// Diable things we don't need, and in particular the zlib compatible names which
|
||||||
|
// would cause conflicts if a user application is using both PolyVox and zlib.
|
||||||
|
#define MINIZ_NO_STDIO
|
||||||
|
#define MINIZ_NO_ARCHIVE_APIS
|
||||||
|
#define MINIZ_NO_TIME
|
||||||
|
//#define MINIZ_NO_ZLIB_APIS
|
||||||
|
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||||
|
//#define MINIZ_NO_MALLOC
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||||
|
// For some unknown reason the miniz library is supplied only as a
|
||||||
|
// single .c file without a header. Apparently the only way to use
|
||||||
|
// it is then to #include it directly which is what the examples do.
|
||||||
|
#include "PolyVoxCore/Impl/miniz.c"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
MinizCompressor::MinizCompressor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MinizCompressor::~MinizCompressor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MinizCompressor::getMaxCompressedSize(uint32_t uUncompressedInputSize)
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(mz_compressBound(static_cast<mz_ulong>(uUncompressedInputSize)));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MinizCompressor::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
|
{
|
||||||
|
mz_ulong ulDstLength = uDstLength;
|
||||||
|
|
||||||
|
// Do the compression
|
||||||
|
int result = mz_compress((unsigned char*)pDstData, &ulDstLength, (const unsigned char*) pSrcData, uSrcLength);
|
||||||
|
if(result != MZ_OK)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << "mz_compress() failed with return code '" << result << "'";
|
||||||
|
POLYVOX_THROW(std::runtime_error, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the number of bytes written to the output.
|
||||||
|
return ulDstLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MinizCompressor::decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
|
{
|
||||||
|
mz_ulong ulDstLength = uDstLength;
|
||||||
|
|
||||||
|
int result = mz_uncompress((unsigned char*) pDstData, &ulDstLength, (const unsigned char*) pSrcData, uSrcLength);
|
||||||
|
if(result != MZ_OK)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << "mz_uncompress() failed with return code '" << result << "'";
|
||||||
|
POLYVOX_THROW(std::runtime_error, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulDstLength;
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,6 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
@ -79,7 +78,7 @@ namespace PolyVox
|
|||||||
*/
|
*/
|
||||||
void Region::accumulate(const Region& reg)
|
void Region::accumulate(const Region& reg)
|
||||||
{
|
{
|
||||||
assert(reg.isValid()); //The result of accumulating an invalid region is not defined.
|
POLYVOX_ASSERT(reg.isValid(), "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
|
||||||
|
|
||||||
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
|
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
|
||||||
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));
|
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));
|
||||||
|
@ -49,8 +49,8 @@ if(ENABLE_BINDINGS)
|
|||||||
#set_target_properties(${SWIG_MODULE_PolyVoxCore_REAL_NAME} PROPERTIES SUFFIX ".pyd")
|
#set_target_properties(${SWIG_MODULE_PolyVoxCore_REAL_NAME} PROPERTIES SUFFIX ".pyd")
|
||||||
SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCorePython_REAL_NAME} PROPERTY FOLDER "Bindings")
|
SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCorePython_REAL_NAME} PROPERTY FOLDER "Bindings")
|
||||||
|
|
||||||
swig_add_module(PolyVoxCoreCSharp csharp PolyVoxCore.i)
|
|
||||||
set(SWIG_MODULE_PolyVoxCoreCSharp_EXTRA_FLAGS "-dllimport;PolyVoxCoreCSharp") #This _should_ be inside UseSWIG.cmake - http://www.cmake.org/Bug/view.php?id=13814
|
set(SWIG_MODULE_PolyVoxCoreCSharp_EXTRA_FLAGS "-dllimport;PolyVoxCoreCSharp") #This _should_ be inside UseSWIG.cmake - http://www.cmake.org/Bug/view.php?id=13814
|
||||||
|
swig_add_module(PolyVoxCoreCSharp csharp PolyVoxCore.i)
|
||||||
swig_link_libraries(PolyVoxCoreCSharp PolyVoxCore)
|
swig_link_libraries(PolyVoxCoreCSharp PolyVoxCore)
|
||||||
SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCoreCSharp_REAL_NAME} PROPERTY FOLDER "Bindings")
|
SET_PROPERTY(TARGET ${SWIG_MODULE_PolyVoxCoreCSharp_REAL_NAME} PROPERTY FOLDER "Bindings")
|
||||||
else()
|
else()
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
|
|
||||||
%include "CubicSurfaceExtractor.h"
|
%include "CubicSurfaceExtractor.h"
|
||||||
|
|
||||||
EXTRACTORS(CubicSurfaceExtractor)
|
%template(CubicSurfaceExtractorSimpleVolumeuint8) PolyVox::CubicSurfaceExtractor<PolyVox::SimpleVolume<uint8_t>, PolyVox::DefaultIsQuadNeeded<uint8_t> >;
|
||||||
|
//EXTRACTORS(CubicSurfaceExtractor)
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
%module CubicSurfaceExtractorWithNormals
|
%module CubicSurfaceExtractorWithNormals
|
||||||
%{
|
%{
|
||||||
#include "SimpleVolume.h"
|
|
||||||
//#include "CubicSurfaceExtractor.h"
|
|
||||||
#include "CubicSurfaceExtractorWithNormals.h"
|
#include "CubicSurfaceExtractorWithNormals.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "SimpleVolume.h"
|
|
||||||
//%include "CubicSurfaceExtractor.h"
|
|
||||||
%include "CubicSurfaceExtractorWithNormals.h"
|
%include "CubicSurfaceExtractorWithNormals.h"
|
||||||
|
|
||||||
%template(CubicSurfaceExtractorWithNormalsMaterial8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::Material8>;
|
%template(CubicSurfaceExtractorWithNormalsSimpleVolumeuint8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::SimpleVolume<uint8_t>, PolyVox::DefaultIsQuadNeeded<uint8_t> >;
|
||||||
%template(CubicSurfaceExtractorWithNormalsDensity8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::Density8>;
|
|
||||||
|
@ -61,6 +61,14 @@ EXTRACTOR(shortname, LargeVolume)
|
|||||||
//This will rename "operator=" to "assign" since Python doesn't have assignment
|
//This will rename "operator=" to "assign" since Python doesn't have assignment
|
||||||
%rename(assign) *::operator=;
|
%rename(assign) *::operator=;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SWIGCSHARP
|
||||||
|
//These operators are not wrappable in C# and their function is provided by other means
|
||||||
|
%ignore *::operator=;
|
||||||
|
%ignore *::operator+=;
|
||||||
|
%ignore *::operator-=;
|
||||||
|
%ignore *::operator*=;
|
||||||
|
%ignore *::operator/=;
|
||||||
|
#endif
|
||||||
|
|
||||||
%include "stdint.i"
|
%include "stdint.i"
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
@ -76,5 +84,6 @@ EXTRACTOR(shortname, LargeVolume)
|
|||||||
%include "VertexTypes.i"
|
%include "VertexTypes.i"
|
||||||
%include "SurfaceMesh.i"
|
%include "SurfaceMesh.i"
|
||||||
%include "MarchingCubesSurfaceExtractor.i"
|
%include "MarchingCubesSurfaceExtractor.i"
|
||||||
//%include "CubicSurfaceExtractor.i"
|
%include "CubicSurfaceExtractor.i"
|
||||||
|
%include "CubicSurfaceExtractorWithNormals.i"
|
||||||
%include "Raycast.i"
|
%include "Raycast.i"
|
||||||
|
@ -12,7 +12,15 @@ PROPERTY(PolyVox::Vector, y, getY, setY)
|
|||||||
PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
%rename(Plus) operator +;
|
||||||
|
%rename(Minus) operator -;
|
||||||
|
%rename(Multiply) operator *;
|
||||||
|
%rename(Divide) operator /;
|
||||||
|
%rename(Equal) operator ==;
|
||||||
|
%rename(NotEqual) operator !=;
|
||||||
|
|
||||||
%extend PolyVox::Vector {
|
%extend PolyVox::Vector {
|
||||||
|
#ifdef SWIGPYTHON
|
||||||
PolyVox::Vector __add__(const PolyVox::Vector& rhs) {
|
PolyVox::Vector __add__(const PolyVox::Vector& rhs) {
|
||||||
return *$self + rhs;
|
return *$self + rhs;
|
||||||
}
|
}
|
||||||
@ -31,6 +39,7 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
|||||||
PolyVox::Vector __mul__(const StorageType& rhs) {
|
PolyVox::Vector __mul__(const StorageType& rhs) {
|
||||||
return *$self * rhs;
|
return *$self * rhs;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
STR()
|
STR()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,12 +51,62 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
|||||||
//%csattributes PolyVox::Vector::operator< "[System.Obsolete(\"deprecated\")]"
|
//%csattributes PolyVox::Vector::operator< "[System.Obsolete(\"deprecated\")]"
|
||||||
|
|
||||||
%define VECTOR3(StorageType,OperationType,ReducedStorageType)
|
%define VECTOR3(StorageType,OperationType,ReducedStorageType)
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
#if SWIGCSHARP
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType);
|
%extend PolyVox::Vector<3,StorageType,OperationType> {
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const;
|
PolyVox::Vector<3,StorageType,OperationType> operator+(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self + rhs;}
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType);
|
PolyVox::Vector<3,StorageType,OperationType> operator-(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self - rhs;}
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
PolyVox::Vector<3,StorageType,OperationType> operator*(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self * rhs;}
|
||||||
%template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>;
|
PolyVox::Vector<3,StorageType,OperationType> operator/(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self / rhs;}
|
||||||
|
PolyVox::Vector<3,StorageType,OperationType> operator*(const StorageType& rhs) {return *$self * rhs;}
|
||||||
|
PolyVox::Vector<3,StorageType,OperationType> operator/(const StorageType& rhs) {return *$self / rhs;}
|
||||||
|
};
|
||||||
|
%typemap(cscode) PolyVox::Vector<3,StorageType,OperationType> %{
|
||||||
|
public static Vector3D##StorageType operator+(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Plus(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator-(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Minus(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Multiply(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Divide(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Multiply(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Divide(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public bool Equals(Vector3D##StorageType rhs) {
|
||||||
|
if ((object)rhs == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Equal(rhs);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::operator<; //This is deprecated
|
||||||
|
#endif
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const;
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
||||||
|
%template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>;
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
VECTOR3(float,float,float)
|
VECTOR3(float,float,float)
|
||||||
|
@ -97,13 +97,32 @@ ADD_TEST(VectorEqualityTest ${LATEST_TEST} testEquality)
|
|||||||
# Volume tests
|
# Volume tests
|
||||||
CREATE_TEST(testvolume.h testvolume.cpp testvolume)
|
CREATE_TEST(testvolume.h testvolume.cpp testvolume)
|
||||||
|
|
||||||
ADD_TEST(RawVolumeDirectAccessTest ${LATEST_TEST} testRawVolumeDirectAccess)
|
ADD_TEST(RawVolumeDirectAccessAllInternalForwards ${LATEST_TEST} testRawVolumeDirectAccessAllInternalForwards)
|
||||||
ADD_TEST(SimpleVolumeDirectAccessTest ${LATEST_TEST} testSimpleVolumeDirectAccess)
|
ADD_TEST(RawVolumeSamplersAllInternalForwards ${LATEST_TEST} testRawVolumeSamplersAllInternalForwards)
|
||||||
ADD_TEST(LargeVolumeDirectAccessTest ${LATEST_TEST} testLargeVolumeDirectAccess)
|
ADD_TEST(RawVolumeDirectAccessWithExternalForwards ${LATEST_TEST} testRawVolumeDirectAccessWithExternalForwards)
|
||||||
|
ADD_TEST(RawVolumeSamplersWithExternalForwards ${LATEST_TEST} testRawVolumeSamplersWithExternalForwards)
|
||||||
|
ADD_TEST(RawVolumeDirectAccessAllInternalBackwards ${LATEST_TEST} testRawVolumeDirectAccessAllInternalBackwards)
|
||||||
|
ADD_TEST(RawVolumeSamplersAllInternalBackwards ${LATEST_TEST} testRawVolumeSamplersAllInternalBackwards)
|
||||||
|
ADD_TEST(RawVolumeDirectAccessWithExternalBackwards ${LATEST_TEST} testRawVolumeDirectAccessWithExternalBackwards)
|
||||||
|
ADD_TEST(RawVolumeSamplersWithExternalBackwards ${LATEST_TEST} testRawVolumeSamplersWithExternalBackwards)
|
||||||
|
|
||||||
ADD_TEST(RawVolumeSamplersTest ${LATEST_TEST} testRawVolumeSamplers)
|
ADD_TEST(SimpleVolumeDirectAccessAllInternalForwards ${LATEST_TEST} testSimpleVolumeDirectAccessAllInternalForwards)
|
||||||
ADD_TEST(SimpleVolumeSamplersTest ${LATEST_TEST} testSimpleVolumeSamplers)
|
ADD_TEST(SimpleVolumeSamplersAllInternalForwards ${LATEST_TEST} testSimpleVolumeSamplersAllInternalForwards)
|
||||||
ADD_TEST(LargeVolumeSamplersTest ${LATEST_TEST} testLargeVolumeSamplers)
|
ADD_TEST(SimpleVolumeDirectAccessWithExternalForwards ${LATEST_TEST} testSimpleVolumeDirectAccessWithExternalForwards)
|
||||||
|
ADD_TEST(SimpleVolumeSamplersWithExternalForwards ${LATEST_TEST} testSimpleVolumeSamplersWithExternalForwards)
|
||||||
|
ADD_TEST(SimpleVolumeDirectAccessAllInternalBackwards ${LATEST_TEST} testSimpleVolumeDirectAccessAllInternalBackwards)
|
||||||
|
ADD_TEST(SimpleVolumeSamplersAllInternalBackwards ${LATEST_TEST} testSimpleVolumeSamplersAllInternalBackwards)
|
||||||
|
ADD_TEST(SimpleVolumeDirectAccessWithExternalBackwards ${LATEST_TEST} testSimpleVolumeDirectAccessWithExternalBackwards)
|
||||||
|
ADD_TEST(SimpleVolumeSamplersWithExternalBackwards ${LATEST_TEST} testSimpleVolumeSamplersWithExternalBackwards)
|
||||||
|
|
||||||
|
ADD_TEST(LargeVolumeDirectAccessAllInternalForwards ${LATEST_TEST} testLargeVolumeDirectAccessAllInternalForwards)
|
||||||
|
ADD_TEST(LargeVolumeSamplersAllInternalForwards ${LATEST_TEST} testLargeVolumeSamplersAllInternalForwards)
|
||||||
|
ADD_TEST(LargeVolumeDirectAccessWithExternalForwards ${LATEST_TEST} testLargeVolumeDirectAccessWithExternalForwards)
|
||||||
|
ADD_TEST(LargeVolumeSamplersWithExternalForwards ${LATEST_TEST} testLargeVolumeSamplersWithExternalForwards)
|
||||||
|
ADD_TEST(LargeVolumeDirectAccessAllInternalBackwards ${LATEST_TEST} testLargeVolumeDirectAccessAllInternalBackwards)
|
||||||
|
ADD_TEST(LargeVolumeSamplersAllInternalBackwards ${LATEST_TEST} testLargeVolumeSamplersAllInternalBackwards)
|
||||||
|
ADD_TEST(LargeVolumeDirectAccessWithExternalBackwards ${LATEST_TEST} testLargeVolumeDirectAccessWithExternalBackwards)
|
||||||
|
ADD_TEST(LargeVolumeSamplersWithExternalBackwards ${LATEST_TEST} testLargeVolumeSamplersWithExternalBackwards)
|
||||||
|
|
||||||
# Volume subclass tests
|
# Volume subclass tests
|
||||||
CREATE_TEST(TestVolumeSubclass.h TestVolumeSubclass.cpp TestVolumeSubclass)
|
CREATE_TEST(TestVolumeSubclass.h TestVolumeSubclass.cpp TestVolumeSubclass)
|
||||||
|
32
tests/TestSurfaceExtractor.cs
Normal file
32
tests/TestSurfaceExtractor.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
public class test
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
Region r = new Region(new Vector3Dint32_t(0,0,0), new Vector3Dint32_t(31,31,31));
|
||||||
|
SimpleVolumeuint8 vol = new SimpleVolumeuint8(r);
|
||||||
|
//Set one single voxel to have a reasonably high density
|
||||||
|
vol.setVoxelAt(new Vector3Dint32_t(5, 5, 5), 200);
|
||||||
|
SurfaceMeshPositionMaterialNormal mesh = new SurfaceMeshPositionMaterialNormal();
|
||||||
|
MarchingCubesSurfaceExtractorSimpleVolumeuint8 extractor = new MarchingCubesSurfaceExtractorSimpleVolumeuint8(vol, r, mesh);
|
||||||
|
extractor.execute();
|
||||||
|
|
||||||
|
Debug.Assert(mesh.getNoOfVertices() == 6);
|
||||||
|
|
||||||
|
Vector3Dint32_t v1 = new Vector3Dint32_t(1,2,3);
|
||||||
|
Vector3Dint32_t v2 = new Vector3Dint32_t(6,8,12);
|
||||||
|
Vector3Dint32_t v3 = v1 + v2;
|
||||||
|
|
||||||
|
Vector3Dint32_t v11 = new Vector3Dint32_t(1,2,3);
|
||||||
|
|
||||||
|
Debug.Assert(v3.getX() == 7);
|
||||||
|
Debug.Assert((v3*5).getX() == 35);
|
||||||
|
Debug.Assert(v1.Equals(v11));
|
||||||
|
Debug.Assert(v1 != v11);
|
||||||
|
Debug.Assert(!v1.Equals(v2));
|
||||||
|
Debug.Assert(!v1.Equals(null));
|
||||||
|
|
||||||
|
System.Console.WriteLine("Success");
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,9 @@ freely, subject to the following restrictions:
|
|||||||
#include "testvolume.h"
|
#include "testvolume.h"
|
||||||
|
|
||||||
#include "PolyVoxCore/LargeVolume.h"
|
#include "PolyVoxCore/LargeVolume.h"
|
||||||
|
#include "PolyVoxCore/MinizCompressor.h"
|
||||||
#include "PolyVoxCore/RawVolume.h"
|
#include "PolyVoxCore/RawVolume.h"
|
||||||
|
#include "PolyVoxCore/RLECompressor.h"
|
||||||
#include "PolyVoxCore/SimpleVolume.h"
|
#include "PolyVoxCore/SimpleVolume.h"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
@ -39,37 +41,25 @@ inline int32_t cantorTupleFunction(int32_t previousResult, int32_t value)
|
|||||||
return (( previousResult + value ) * ( previousResult + value + 1 ) + value ) / 2;
|
return (( previousResult + value ) * ( previousResult + value + 1 ) + value ) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Funtions for testing iteration in a forwards direction
|
||||||
|
*/
|
||||||
|
|
||||||
|
// We allow user provided offset in this function so we can test the case when all samples are inside a volume and also the case when some samples are outside.
|
||||||
|
// This is important because samplers are often slower when outside the volume as they have to fall back on directly accessing the volume data.
|
||||||
template <typename VolumeType>
|
template <typename VolumeType>
|
||||||
VolumeType* createAndFillVolume(void)
|
int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||||
{
|
|
||||||
//Create the volume
|
|
||||||
VolumeType* volume = new VolumeType(Region(-57, -31, 12, 64, 96, 131)); // Deliberatly awkward size
|
|
||||||
|
|
||||||
//Fill the volume with some data
|
|
||||||
for(int z = volume->getEnclosingRegion().getLowerZ(); z <= volume->getEnclosingRegion().getUpperZ(); z++)
|
|
||||||
{
|
|
||||||
for(int y = volume->getEnclosingRegion().getLowerY(); y <= volume->getEnclosingRegion().getUpperY(); y++)
|
|
||||||
{
|
|
||||||
for(int x = volume->getEnclosingRegion().getLowerX(); x <= volume->getEnclosingRegion().getUpperX(); x++)
|
|
||||||
{
|
|
||||||
volume->setVoxelAt(x, y, z, x + y + z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VolumeType>
|
|
||||||
int32_t testDirectAccessWithWrapping(const VolumeType* volume)
|
|
||||||
{
|
{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
for(int z = volume->getEnclosingRegion().getLowerZ() - 2; z <= volume->getEnclosingRegion().getUpperZ() + 4; z++)
|
// If we know that we are only iterating over voxels internal to the volume then we can avoid calling the 'wrapping' function. This should be faster.
|
||||||
|
bool bAllVoxelsInternal = (lowXOffset > 0) && (lowYOffset > 0) && (lowZOffset > 0) && (highXOffset < 0) && (highYOffset < 0) && (highZOffset < 0);
|
||||||
|
|
||||||
|
for(int z = volume->getEnclosingRegion().getLowerZ() + lowZOffset; z <= volume->getEnclosingRegion().getUpperZ() + highZOffset; z++)
|
||||||
{
|
{
|
||||||
for(int y = volume->getEnclosingRegion().getLowerY() - 3; y <= volume->getEnclosingRegion().getUpperY() + 5; y++)
|
for(int y = volume->getEnclosingRegion().getLowerY() + lowYOffset; y <= volume->getEnclosingRegion().getUpperY() + highYOffset; y++)
|
||||||
{
|
{
|
||||||
for(int x = volume->getEnclosingRegion().getLowerX() - 1; x <= volume->getEnclosingRegion().getUpperX() + 2; x++)
|
for(int x = volume->getEnclosingRegion().getLowerX() + lowXOffset; x <= volume->getEnclosingRegion().getUpperX() + highXOffset; x++)
|
||||||
{
|
{
|
||||||
//Three level loop now processes 27 voxel neighbourhood
|
//Three level loop now processes 27 voxel neighbourhood
|
||||||
for(int innerZ = -1; innerZ <=1; innerZ++)
|
for(int innerZ = -1; innerZ <=1; innerZ++)
|
||||||
@ -78,7 +68,16 @@ int32_t testDirectAccessWithWrapping(const VolumeType* volume)
|
|||||||
{
|
{
|
||||||
for(int innerX = -1; innerX <=1; innerX++)
|
for(int innerX = -1; innerX <=1; innerX++)
|
||||||
{
|
{
|
||||||
result = cantorTupleFunction(result, volume->getVoxelWithWrapping(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
|
// Deeply nested 'if', but this is just a unit test and we should still
|
||||||
|
// see some performance improvement by skipping the wrapping versions.
|
||||||
|
if(bAllVoxelsInternal)
|
||||||
|
{
|
||||||
|
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = cantorTupleFunction(result, volume->getVoxelWithWrapping(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,50 +90,111 @@ int32_t testDirectAccessWithWrapping(const VolumeType* volume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename VolumeType>
|
template <typename VolumeType>
|
||||||
int32_t testSamplersWithWrapping(VolumeType* volume)
|
int32_t testSamplersWithWrappingForwards(VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||||
{
|
{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
typename VolumeType::Sampler sampler(volume);
|
//Test the sampler move functions
|
||||||
sampler.setWrapMode(WrapModes::Border, 3);
|
typename VolumeType::Sampler xSampler(volume);
|
||||||
|
typename VolumeType::Sampler ySampler(volume);
|
||||||
|
typename VolumeType::Sampler zSampler(volume);
|
||||||
|
|
||||||
for(int z = volume->getEnclosingRegion().getLowerZ() - 2; z <= volume->getEnclosingRegion().getUpperZ() + 4; z++)
|
xSampler.setWrapMode(WrapModes::Border, 3);
|
||||||
|
ySampler.setWrapMode(WrapModes::Border, 3);
|
||||||
|
zSampler.setWrapMode(WrapModes::Border, 3);
|
||||||
|
|
||||||
|
zSampler.setPosition(volume->getEnclosingRegion().getLowerX() + lowXOffset, volume->getEnclosingRegion().getLowerY() + lowYOffset, volume->getEnclosingRegion().getLowerZ() + lowZOffset);
|
||||||
|
for(int z = volume->getEnclosingRegion().getLowerZ() + lowZOffset; z <= volume->getEnclosingRegion().getUpperZ() + highZOffset; z++)
|
||||||
{
|
{
|
||||||
for(int y = volume->getEnclosingRegion().getLowerY() - 3; y <= volume->getEnclosingRegion().getUpperY() + 5; y++)
|
ySampler = zSampler;
|
||||||
|
for(int y = volume->getEnclosingRegion().getLowerY() + lowYOffset; y <= volume->getEnclosingRegion().getUpperY() + highYOffset; y++)
|
||||||
{
|
{
|
||||||
for(int x = volume->getEnclosingRegion().getLowerX() - 1; x <= volume->getEnclosingRegion().getUpperX() + 2; x++)
|
xSampler = ySampler;
|
||||||
|
for(int x = volume->getEnclosingRegion().getLowerX() + lowXOffset; x <= volume->getEnclosingRegion().getUpperX() + highXOffset; x++)
|
||||||
{
|
{
|
||||||
sampler.setPosition(x, y, z);
|
xSampler.setPosition(x, y, z); // HACK - Accessing a volume through multiple samplers currently breaks the LargeVolume.
|
||||||
|
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1ny1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1ny1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1ny1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx0py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px0py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px0py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1nz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1py1nz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1nz());
|
||||||
|
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1ny0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1ny0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1ny0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx0py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px0py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px0py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py0pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1py0pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py0pz());
|
||||||
|
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1ny1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1ny1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1ny1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx0py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px0py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px0py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1nx1py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel0px1py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1pz());
|
||||||
result = cantorTupleFunction(result, sampler.peekVoxel1px1py1pz());
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1pz());
|
||||||
|
|
||||||
|
xSampler.movePositiveX();
|
||||||
|
}
|
||||||
|
ySampler.movePositiveY();
|
||||||
|
}
|
||||||
|
zSampler.movePositiveZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Funtions for testing iteration in a backwards direction
|
||||||
|
*/
|
||||||
|
|
||||||
|
// We allow user provided offset in this function so we can test the case when all samples are inside a volume and also the case when some samples are outside.
|
||||||
|
// This is important because samplers are often slower when outside the volume as they have to fall back on directly accessing the volume data.
|
||||||
|
template <typename VolumeType>
|
||||||
|
int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
// If we know that we are only iterating over voxels internal to the volume then we can avoid calling the 'wrapping' function. This should be faster.
|
||||||
|
bool bAllVoxelsInternal = (lowXOffset > 0) && (lowYOffset > 0) && (lowZOffset > 0) && (highXOffset < 0) && (highYOffset < 0) && (highZOffset < 0);
|
||||||
|
|
||||||
|
for(int z = volume->getEnclosingRegion().getUpperZ() + highZOffset; z >= volume->getEnclosingRegion().getLowerZ() + lowZOffset; z--)
|
||||||
|
{
|
||||||
|
for(int y = volume->getEnclosingRegion().getUpperY() + highYOffset; y >= volume->getEnclosingRegion().getLowerY() + lowYOffset; y--)
|
||||||
|
{
|
||||||
|
for(int x = volume->getEnclosingRegion().getUpperX() + highXOffset; x >= volume->getEnclosingRegion().getLowerX() + lowXOffset; x--)
|
||||||
|
{
|
||||||
|
//Three level loop now processes 27 voxel neighbourhood
|
||||||
|
for(int innerZ = -1; innerZ <=1; innerZ++)
|
||||||
|
{
|
||||||
|
for(int innerY = -1; innerY <=1; innerY++)
|
||||||
|
{
|
||||||
|
for(int innerX = -1; innerX <=1; innerX++)
|
||||||
|
{
|
||||||
|
// Deeply nested 'if', but this is just a unit test and we should still
|
||||||
|
// see some performance improvement by skipping the wrapping versions.
|
||||||
|
if(bAllVoxelsInternal)
|
||||||
|
{
|
||||||
|
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = cantorTupleFunction(result, volume->getVoxelWithWrapping(x + innerX, y + innerY, z + innerZ, WrapModes::Border, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//End of inner loops
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,106 +203,60 @@ int32_t testSamplersWithWrapping(VolumeType* volume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename VolumeType>
|
template <typename VolumeType>
|
||||||
int32_t complexVolumeTest(void)
|
int32_t testSamplersWithWrappingBackwards(VolumeType* volume, int lowXOffset, int lowYOffset, int lowZOffset, int highXOffset, int highYOffset, int highZOffset)
|
||||||
{
|
{
|
||||||
VolumeType* testVolume = createAndFillVolume<VolumeType>();
|
|
||||||
|
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
//Test the getVoxel function
|
|
||||||
for(int z = testVolume->getEnclosingRegion().getLowerZ(); z <= testVolume->getEnclosingRegion().getUpperZ(); z++)
|
|
||||||
{
|
|
||||||
for(int y = testVolume->getEnclosingRegion().getLowerY(); y <= testVolume->getEnclosingRegion().getUpperY(); y++)
|
|
||||||
{
|
|
||||||
for(int x = testVolume->getEnclosingRegion().getLowerX(); x <= testVolume->getEnclosingRegion().getUpperX(); x++)
|
|
||||||
{
|
|
||||||
result = cantorTupleFunction(result, testVolume->getVoxel(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Test border wrap mode
|
|
||||||
for(int z = testVolume->getEnclosingRegion().getLowerZ(); z <= testVolume->getEnclosingRegion().getUpperZ(); z++)
|
|
||||||
{
|
|
||||||
//Extending outside in y
|
|
||||||
for(int y = testVolume->getEnclosingRegion().getLowerY() - 3; y <= testVolume->getEnclosingRegion().getUpperY() + 5; y++)
|
|
||||||
{
|
|
||||||
for(int x = testVolume->getEnclosingRegion().getLowerX(); x <= testVolume->getEnclosingRegion().getUpperX(); x++)
|
|
||||||
{
|
|
||||||
result = cantorTupleFunction(result, testVolume->getVoxelWithWrapping(x, y, z, WrapModes::Border, 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Test clamp wrap mode
|
|
||||||
for(int z = testVolume->getEnclosingRegion().getLowerZ(); z <= testVolume->getEnclosingRegion().getUpperZ(); z++)
|
|
||||||
{
|
|
||||||
for(int y = testVolume->getEnclosingRegion().getLowerY(); y <= testVolume->getEnclosingRegion().getUpperY(); y++)
|
|
||||||
{
|
|
||||||
//Extending outside in x
|
|
||||||
for(int x = testVolume->getEnclosingRegion().getLowerX() - 2; x <= testVolume->getEnclosingRegion().getUpperX() + 4; x++)
|
|
||||||
{
|
|
||||||
result = cantorTupleFunction(result, testVolume->getVoxelWithWrapping(x, y, z, WrapModes::Clamp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Test the sampler setPosition
|
|
||||||
typename VolumeType::Sampler sampler(testVolume);
|
|
||||||
sampler.setWrapMode(WrapModes::Border, 1);
|
|
||||||
|
|
||||||
for(int z = testVolume->getEnclosingRegion().getLowerZ() - 2; z <= testVolume->getEnclosingRegion().getUpperZ() + 1; z++)
|
|
||||||
{
|
|
||||||
for(int y = testVolume->getEnclosingRegion().getLowerY() - 1; y <= testVolume->getEnclosingRegion().getUpperY() + 3; y++)
|
|
||||||
{
|
|
||||||
for(int x = testVolume->getEnclosingRegion().getLowerX() - 4; x <= testVolume->getEnclosingRegion().getUpperX() + 2; x++)
|
|
||||||
{
|
|
||||||
sampler.setPosition(x,y,z);
|
|
||||||
result = cantorTupleFunction(result, sampler.getVoxel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Test the sampler move functions
|
//Test the sampler move functions
|
||||||
typename VolumeType::Sampler xSampler(testVolume);
|
typename VolumeType::Sampler xSampler(volume);
|
||||||
typename VolumeType::Sampler ySampler(testVolume);
|
typename VolumeType::Sampler ySampler(volume);
|
||||||
typename VolumeType::Sampler zSampler(testVolume);
|
typename VolumeType::Sampler zSampler(volume);
|
||||||
|
|
||||||
xSampler.setWrapMode(WrapModes::Border, 1);
|
xSampler.setWrapMode(WrapModes::Border, 3);
|
||||||
ySampler.setWrapMode(WrapModes::Clamp, 1);
|
ySampler.setWrapMode(WrapModes::Border, 3);
|
||||||
zSampler.setWrapMode(WrapModes::Border, -3);
|
zSampler.setWrapMode(WrapModes::Border, 3);
|
||||||
|
|
||||||
zSampler.setPosition(testVolume->getEnclosingRegion().getLowerX() - 4, testVolume->getEnclosingRegion().getLowerY() - 1, testVolume->getEnclosingRegion().getLowerZ() - 2);
|
zSampler.setPosition(volume->getEnclosingRegion().getUpperX() + highXOffset, volume->getEnclosingRegion().getUpperY() + highYOffset, volume->getEnclosingRegion().getUpperZ() + highZOffset);
|
||||||
for(int z = testVolume->getEnclosingRegion().getLowerZ() - 2; z <= testVolume->getEnclosingRegion().getUpperZ() + 1; z++)
|
for(int z = volume->getEnclosingRegion().getUpperZ() + highZOffset; z >= volume->getEnclosingRegion().getLowerZ() + lowZOffset; z--)
|
||||||
{
|
{
|
||||||
ySampler = zSampler;
|
ySampler = zSampler;
|
||||||
for(int y = testVolume->getEnclosingRegion().getLowerY() - 1; y <= testVolume->getEnclosingRegion().getUpperY() + 3; y++)
|
for(int y = volume->getEnclosingRegion().getUpperY() + highYOffset; y >= volume->getEnclosingRegion().getLowerY() + lowYOffset; y--)
|
||||||
{
|
{
|
||||||
xSampler = ySampler;
|
xSampler = ySampler;
|
||||||
for(int x = testVolume->getEnclosingRegion().getLowerX() - 4; x <= testVolume->getEnclosingRegion().getUpperX() + 2; x++)
|
for(int x = volume->getEnclosingRegion().getUpperX() + highXOffset; x >= volume->getEnclosingRegion().getLowerX() + lowXOffset; x--)
|
||||||
{
|
{
|
||||||
result = cantorTupleFunction(result, xSampler.getVoxel());
|
xSampler.setPosition(x, y, z); // HACK - Accessing a volume through multiple samplers currently breaks the LargeVolume.
|
||||||
xSampler.movePositiveX();
|
|
||||||
}
|
|
||||||
ySampler.movePositiveY();
|
|
||||||
}
|
|
||||||
zSampler.movePositiveZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
xSampler.setWrapMode(WrapModes::Clamp);
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1nz());
|
||||||
ySampler.setWrapMode(WrapModes::Border, 1);
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1nz());
|
||||||
zSampler.setWrapMode(WrapModes::Clamp, -1);
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1nz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1nz());
|
||||||
|
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py0pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py0pz());
|
||||||
|
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1ny1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1ny1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1ny1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx0py1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px0py1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px0py1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1nx1py1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel0px1py1pz());
|
||||||
|
result = cantorTupleFunction(result, xSampler.peekVoxel1px1py1pz());
|
||||||
|
|
||||||
zSampler.setPosition(testVolume->getEnclosingRegion().getUpperX() + 2, testVolume->getEnclosingRegion().getUpperY() + 3, testVolume->getEnclosingRegion().getUpperZ() + 1);
|
|
||||||
for(int z = 0; z < testVolume->getEnclosingRegion().getDepthInVoxels() + 8; z++)
|
|
||||||
{
|
|
||||||
ySampler = zSampler;
|
|
||||||
for(int y = 0; y < testVolume->getEnclosingRegion().getHeightInVoxels() + 3; y++)
|
|
||||||
{
|
|
||||||
xSampler = ySampler;
|
|
||||||
for(int x = 0; x < testVolume->getEnclosingRegion().getWidthInVoxels() + 5; x++)
|
|
||||||
{
|
|
||||||
result = cantorTupleFunction(result, xSampler.getVoxel());
|
|
||||||
xSampler.moveNegativeX();
|
xSampler.moveNegativeX();
|
||||||
}
|
}
|
||||||
ySampler.moveNegativeY();
|
ySampler.moveNegativeY();
|
||||||
@ -250,8 +264,6 @@ int32_t complexVolumeTest(void)
|
|||||||
zSampler.moveNegativeZ();
|
zSampler.moveNegativeZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete testVolume;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +271,17 @@ TestVolume::TestVolume()
|
|||||||
{
|
{
|
||||||
Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
|
Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
|
||||||
|
|
||||||
|
//m_pCompressor = new RLECompressor<int32_t, uint16_t>;
|
||||||
|
m_pCompressor = new MinizCompressor;
|
||||||
|
|
||||||
//Create the volumes
|
//Create the volumes
|
||||||
m_pRawVolume = new RawVolume<int32_t>(region);
|
m_pRawVolume = new RawVolume<int32_t>(region);
|
||||||
m_pSimpleVolume = new SimpleVolume<int32_t>(region);
|
m_pSimpleVolume = new SimpleVolume<int32_t>(region);
|
||||||
m_pLargeVolume = new LargeVolume<int32_t>(region);
|
m_pLargeVolume = new LargeVolume<int32_t>(region, m_pCompressor);
|
||||||
|
|
||||||
|
// LargeVolume currently fails a test if compression is enabled. It
|
||||||
|
// may be related to accessing the data through more than one sampler?
|
||||||
|
//m_pLargeVolume->setCompressionEnabled(false);
|
||||||
|
|
||||||
//Fill the volume with some data
|
//Fill the volume with some data
|
||||||
for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
|
||||||
@ -285,69 +304,272 @@ TestVolume::~TestVolume()
|
|||||||
delete m_pRawVolume;
|
delete m_pRawVolume;
|
||||||
delete m_pSimpleVolume;
|
delete m_pSimpleVolume;
|
||||||
delete m_pLargeVolume;
|
delete m_pLargeVolume;
|
||||||
|
|
||||||
|
delete m_pCompressor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVolume::testRawVolumeDirectAccess()
|
/*
|
||||||
|
* RawVolume Tests
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeDirectAccessAllInternalForwards()
|
||||||
{
|
{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
QBENCHMARK
|
QBENCHMARK
|
||||||
{
|
{
|
||||||
result = testDirectAccessWithWrapping(m_pRawVolume);
|
result = testDirectAccessWithWrappingForwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||||
}
|
}
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVolume::testRawVolumeSamplers()
|
void TestVolume::testRawVolumeSamplersAllInternalForwards()
|
||||||
{
|
{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
QBENCHMARK
|
QBENCHMARK
|
||||||
{
|
{
|
||||||
result = testSamplersWithWrapping(m_pRawVolume);
|
result = testSamplersWithWrappingForwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||||
}
|
}
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVolume::testSimpleVolumeDirectAccess()
|
void TestVolume::testRawVolumeDirectAccessWithExternalForwards()
|
||||||
{
|
|
||||||
int32_t result = 0;
|
|
||||||
QBENCHMARK
|
|
||||||
{
|
|
||||||
result = testDirectAccessWithWrapping(m_pSimpleVolume);
|
|
||||||
}
|
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestVolume::testSimpleVolumeSamplers()
|
|
||||||
{
|
|
||||||
int32_t result = 0;
|
|
||||||
QBENCHMARK
|
|
||||||
{
|
|
||||||
result = testSamplersWithWrapping(m_pSimpleVolume);
|
|
||||||
}
|
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestVolume::testLargeVolumeDirectAccess()
|
|
||||||
{
|
|
||||||
int32_t result = 0;
|
|
||||||
QBENCHMARK
|
|
||||||
{
|
|
||||||
result = testDirectAccessWithWrapping(m_pLargeVolume);
|
|
||||||
}
|
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestVolume::testLargeVolumeSamplers()
|
|
||||||
{
|
{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
QBENCHMARK
|
QBENCHMARK
|
||||||
{
|
{
|
||||||
result = testSamplersWithWrapping(m_pLargeVolume);
|
result = testDirectAccessWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||||
}
|
}
|
||||||
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeSamplersWithExternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingForwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeDirectAccessAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeSamplersAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pRawVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeDirectAccessWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testRawVolumeSamplersWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SimpleVolume Tests
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeDirectAccessAllInternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingForwards(m_pSimpleVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeSamplersAllInternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingForwards(m_pSimpleVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeDirectAccessWithExternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingForwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeSamplersWithExternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingForwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeDirectAccessAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pSimpleVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeSamplersAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pSimpleVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeDirectAccessWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testSimpleVolumeSamplersWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LargeVolume Tests
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeDirectAccessAllInternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingForwards(m_pLargeVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeSamplersAllInternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingForwards(m_pLargeVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(1004598054));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeDirectAccessWithExternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingForwards(m_pLargeVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeSamplersWithExternalForwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingForwards(m_pLargeVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-928601007));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeDirectAccessAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pLargeVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeSamplersAllInternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pLargeVolume, 4, 2, 2, -3, -1, -2);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-269366578));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeDirectAccessWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testDirectAccessWithWrappingBackwards(m_pLargeVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVolume::testLargeVolumeSamplersWithExternalBackwards()
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
QBENCHMARK
|
||||||
|
{
|
||||||
|
result = testSamplersWithWrappingBackwards(m_pLargeVolume, -1, -3, -2, 2, 5, 4);
|
||||||
|
}
|
||||||
|
QCOMPARE(result, static_cast<int32_t>(-769775893));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(TestVolume)
|
QTEST_MAIN(TestVolume)
|
||||||
|
@ -37,16 +37,35 @@ public:
|
|||||||
~TestVolume();
|
~TestVolume();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void testRawVolumeDirectAccess();
|
void testRawVolumeDirectAccessAllInternalForwards();
|
||||||
void testRawVolumeSamplers();
|
void testRawVolumeSamplersAllInternalForwards();
|
||||||
|
void testRawVolumeDirectAccessWithExternalForwards();
|
||||||
|
void testRawVolumeSamplersWithExternalForwards();
|
||||||
|
void testRawVolumeDirectAccessAllInternalBackwards();
|
||||||
|
void testRawVolumeSamplersAllInternalBackwards();
|
||||||
|
void testRawVolumeDirectAccessWithExternalBackwards();
|
||||||
|
void testRawVolumeSamplersWithExternalBackwards();
|
||||||
|
|
||||||
void testSimpleVolumeDirectAccess();
|
void testSimpleVolumeDirectAccessAllInternalForwards();
|
||||||
void testSimpleVolumeSamplers();
|
void testSimpleVolumeSamplersAllInternalForwards();
|
||||||
|
void testSimpleVolumeDirectAccessWithExternalForwards();
|
||||||
|
void testSimpleVolumeSamplersWithExternalForwards();
|
||||||
|
void testSimpleVolumeDirectAccessAllInternalBackwards();
|
||||||
|
void testSimpleVolumeSamplersAllInternalBackwards();
|
||||||
|
void testSimpleVolumeDirectAccessWithExternalBackwards();
|
||||||
|
void testSimpleVolumeSamplersWithExternalBackwards();
|
||||||
|
|
||||||
void testLargeVolumeDirectAccess();
|
void testLargeVolumeDirectAccessAllInternalForwards();
|
||||||
void testLargeVolumeSamplers();
|
void testLargeVolumeSamplersAllInternalForwards();
|
||||||
|
void testLargeVolumeDirectAccessWithExternalForwards();
|
||||||
|
void testLargeVolumeSamplersWithExternalForwards();
|
||||||
|
void testLargeVolumeDirectAccessAllInternalBackwards();
|
||||||
|
void testLargeVolumeSamplersAllInternalBackwards();
|
||||||
|
void testLargeVolumeDirectAccessWithExternalBackwards();
|
||||||
|
void testLargeVolumeSamplersWithExternalBackwards();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PolyVox::Compressor* m_pCompressor;
|
||||||
PolyVox::RawVolume<int32_t>* m_pRawVolume;
|
PolyVox::RawVolume<int32_t>* m_pRawVolume;
|
||||||
PolyVox::SimpleVolume<int32_t>* m_pSimpleVolume;
|
PolyVox::SimpleVolume<int32_t>* m_pSimpleVolume;
|
||||||
PolyVox::LargeVolume<int32_t>* m_pLargeVolume;
|
PolyVox::LargeVolume<int32_t>* m_pLargeVolume;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user