Merge branch 'develop' into feature/cubiquity-version
This commit is contained in:
commit
fa29a83ebd
68
documentation/ErrorHandling.rst
Normal file
68
documentation/ErrorHandling.rst
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
**************
|
||||||
|
Error Handling
|
||||||
|
**************
|
||||||
|
PolyVox includes a number of error handling features designed to help you identify and/or recover from problematic scenarios. This document describes these features and how they affect you as a user of the library.
|
||||||
|
|
||||||
|
Logging
|
||||||
|
=======
|
||||||
|
PolyVox has a simple logging mechanism which allows it to write messages with an associated severity (from Debug up to Fatal). It is possible to redirect the output of these logging functions so you can integrate them with your applications logging framework or suppress them completely.
|
||||||
|
|
||||||
|
The following functions are called at various points in the PolyVox codebase:
|
||||||
|
|
||||||
|
.. sourcecode :: c++
|
||||||
|
|
||||||
|
void logDebug (const std::string& message);
|
||||||
|
void logInfo (const std::string& message);
|
||||||
|
void logWarning(const std::string& message);
|
||||||
|
void logError (const std::string& message);
|
||||||
|
void logFatal (const std::string& message);
|
||||||
|
|
||||||
|
Fatal messages are only issued in non-recoverable scenarios when the application is about to crash, and may provide the last peice of information you have about what went wrong. Error messages are issued when something has happened which prevents sucessful completion of a task, for example if you provide invalid parameters to a function (Error messages are also issued whenever an exception is thrown). Warning messages mean the system was able to continue but the results may not be what you expected. Info and Debug messages are both used for general information about what PolyVox is doing. The differentiating factor is that Debug is used if the output is very frequent so that it can be easily suppressed.
|
||||||
|
|
||||||
|
PolyVox defines a LogHandler function pointer which looks like this:
|
||||||
|
|
||||||
|
.. sourcecode :: c++
|
||||||
|
|
||||||
|
typedef void (*LogHandler)(const std::string& message, LogLevel logLevel);
|
||||||
|
|
||||||
|
There is a function called 'defaultLogHandler()' which matches this signature and writes the messages to cout/cerr (note that it suppresses Debug messages). To redirect log messages you can write your own fuction which matches this signature and the apply it with setLogHandler:
|
||||||
|
|
||||||
|
.. sourcecode :: c++
|
||||||
|
|
||||||
|
setLogHandler(&myLogHandler);
|
||||||
|
|
||||||
|
Note that you can disable logging completely by passing a value of '0' to setLogHandler().
|
||||||
|
|
||||||
|
Exceptions
|
||||||
|
==========
|
||||||
|
Error handling in PolyVox is provided by using the C++ exception mechanism. Exceptions can be thrown for a variety of reasons and your code should be prepared to handle them to prevent your application from crashing. It is possible to disable the throwing of exeptions if they are not supported by your compiler.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
Most functions in PolyVox will validate their input parameters and throw an exception if the provided values do not meet the function's requirements (which should be specified in the API documentation). However, in certain performance critical cases we choose not to spend time validating the parameters and an exception will not be thrown, though we do still use an assertion if these are enabled.
|
||||||
|
|
||||||
|
The most notable example of this is when accessing volume data through the get/setVoxel() functions, as these are designed to be very fast. Validating an input position would require multiple conditional operations which we chose to avoid. Therefore, **accessing a voxel outside of a volume will cause undefined behaviour.** When reading voxels it is safer to use the function getVoxelWithWrapping() as this lets you specify how out-of-bounds voxels should be handled.
|
||||||
|
|
||||||
|
Disabling exceptions
|
||||||
|
--------------------
|
||||||
|
Some platforms may not support the use of C++ exceptions (older Android SDKs are the only place we have seen this) so you may need to disable them completely. This is highly undesirable but you may have no choice. To do this you should undefine 'POLYVOX_THROW_ENABLED' in Config.h (we may expose this through CMake in the future).
|
||||||
|
|
||||||
|
If exceptions are disabled then PolyVox will call a 'ThrowHandler' instead of throwing an exception. This is defined as follows:
|
||||||
|
|
||||||
|
.. sourcecode :: c++
|
||||||
|
|
||||||
|
typedef void (*ThrowHandler)(std::exception& e, const char* file, int line);
|
||||||
|
|
||||||
|
The default throw handler will print an error and then terminate, but you can provide a custom throw handler matching the function definition above:
|
||||||
|
|
||||||
|
.. sourcecode :: c++
|
||||||
|
|
||||||
|
setThrowHandler(&myThrowHandler);
|
||||||
|
|
||||||
|
Asserts
|
||||||
|
=======
|
||||||
|
In addition to the C++ exception handling mechanism, PolyVox also makes use of assertions to verify the internal state of the library at various points. This functionality is provided by out own POLYVOX_ASSERT() macro rather than the standard C++ assert() as this has a number of advantages described `here <http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/>`_.
|
||||||
|
|
||||||
|
Assertions inside PolyVox are enabled by defining 'POLYVOX_ASSERTS_ENABLED' in Config.h and again we may expose this through CMake. Note that the presence of assertions is independant of whether you are building a debug or release version of your application.
|
||||||
|
|
||||||
|
As a user you are not really expected to encounter an assertions inside PolyVox - they are mostly there for our purposes as developers of the library. So if you hit one in PolyVox then there is a good chance it is a bug in the library, as user errors should have been prevented by throwing an exceptions. Again, there are exceptions to this rule as some speed-critical functions (getVoxel(), etc) do not validate their parameters.
|
@ -41,7 +41,7 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'PolyVox'
|
project = u'PolyVox'
|
||||||
copyright = u'2010, David Williams, Matt Williams'
|
copyright = u'2013, David Williams, Matt Williams'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
@ -14,7 +14,7 @@ User Guide:
|
|||||||
ModifyingTerrain
|
ModifyingTerrain
|
||||||
LevelOfDetail
|
LevelOfDetail
|
||||||
Threading
|
Threading
|
||||||
|
ErrorHandling
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ Examples:
|
|||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
tutorial1
|
tutorial1
|
||||||
|
python-bindings
|
||||||
|
|
||||||
Other Information:
|
Other Information:
|
||||||
|
|
||||||
|
139
documentation/python-bindings.rst
Normal file
139
documentation/python-bindings.rst
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
***************
|
||||||
|
Python bindings
|
||||||
|
***************
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
PolyVox itself is a C++ library but in order to make it useful to as many people as possible, we also provide bindings to a number of other languages.
|
||||||
|
These bindings are all generated by `SWIG <http://swig.org>`_ and provide a bridge to a compiled PolyVox library (*DLL* or *.so*) via an interafce which is native to the language.
|
||||||
|
This allows you in a Python script to simpy call ``import PolyVoxCore`` and get access to the whole library's functionality.
|
||||||
|
|
||||||
|
The Python bindings are available for Python 3.
|
||||||
|
|
||||||
|
Comparison with C++
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
All the bindings available for PolyVox (so both the Python bindings and any future supported bindings such as for C♯) follow the PolyVox C++ API quite closely.
|
||||||
|
This means that many PolyVox code examples written in C++ are mostly applicable also to Python.
|
||||||
|
Classes and functions are named the same and take the same set of arguments.
|
||||||
|
The main place this falls down is with templated C++ classes.
|
||||||
|
Since C++ templates are essentially a code-generation system built into the C++ compiler there is no way for a user of the Python bindings to request, at run-time, a specific piece of code to be generated.
|
||||||
|
The way we work around this is by, as part of the bindings generation process, pre-compiling a number of different versions of each templated class.
|
||||||
|
For example, in C++ a 3D vector containing 32-bit integers would be declared as
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
PolyVox::Vector3D<int32_t> my_vec(0,1,4);
|
||||||
|
|
||||||
|
but in Python it would be accessed as
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
my_vec = PolyVoxCore.Vector3Dint32_t(0,1,4)
|
||||||
|
|
||||||
|
As a rule, any time in C++ where you see a template instantiation with ``<>``, just remove the angle brackets and it will yield the Python class name.
|
||||||
|
|
||||||
|
The choice of which C++ templates to instantiate is made by the developers of PolyVox in order to try to cover the main use-cases that library users would have.
|
||||||
|
If, however, you want to add your own versions, this can be done by editing the SWIG interface files and recompiling PolyVox.
|
||||||
|
|
||||||
|
Buildings the bindings
|
||||||
|
======================
|
||||||
|
|
||||||
|
The bindings are built as part of the standard PolyVox build process. For details on this please follow the instructions at :doc:`install`.
|
||||||
|
The important things to note there are the requirements for building the bindings: *Python development libraries* and *SWIG*.
|
||||||
|
During the CMake phase of building, it should tell you whether or not the bindings will be built.
|
||||||
|
|
||||||
|
Compiling the whole PolyVox library should then give you two files inside the ``build/library/bindings`` directory:
|
||||||
|
|
||||||
|
``PolyVoxCore.py``
|
||||||
|
This is the main entry point to the library.
|
||||||
|
|
||||||
|
``_PolyVoxCore.so`` (or ``.dll`` on Windows)
|
||||||
|
This contains the compiled code of the PolyVox library.
|
||||||
|
|
||||||
|
This file has a link dependency the main ``libPolyVoxCore.so`` library as well as the Python shared library.
|
||||||
|
|
||||||
|
|
||||||
|
Using the bindings
|
||||||
|
==================
|
||||||
|
|
||||||
|
As discussed above, the Python API is very similar to the C++ one but none-the-less we'll go through an example to see how it works.
|
||||||
|
All the code in this section is taken from ``PythonExample.py`` found in the source distribution of PolyVox in the ``examples/Python`` folder.
|
||||||
|
|
||||||
|
Seting up the volume
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The first this we do is import the ``PolyVoxCore`` module. We rename it as ``pv`` to make our life easier.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 29
|
||||||
|
|
||||||
|
We create a ``Region`` from two vectors defining the bounds of the area - a volume 64×64×64.
|
||||||
|
Remember that ``pv.Vector3Dint32_t`` refers to a 3D :polyvox:`PolyVox::Vector` templated on a 32-bit integer.
|
||||||
|
|
||||||
|
The second line creates a :polyvox:`SimpleVolume` of the same size as the :polyvox:`Region` where each voxel in the volume is defined an unsigned 8-bit integer.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 31-33
|
||||||
|
|
||||||
|
We're going to fill our volume with a sphere and so we start by finding out where the centre of the volume is and defining the radius of our desired shape.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 35-37
|
||||||
|
|
||||||
|
Then we actually loop over each of the dimensions of the volume such that inside the loop, ``x``, ``y`` and ``z`` refer to the current location.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 38-41
|
||||||
|
|
||||||
|
All we do inside the loop is set all the voxels inside the sphere to have a value of ``255`` and all those outside to have a value of ``0``.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 42-53
|
||||||
|
|
||||||
|
Getting the mesh data
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Extracting the surface mesh for the volume is a two-step process.
|
||||||
|
First we tell PolyVox to generate the appropriate mesh, then we have to convert the PolyVox mesh data to something that our rendering library can understand.
|
||||||
|
|
||||||
|
First we define the sort of mesh that we want. For this example we want a mesh with information on the position, material and normal of each vertex.
|
||||||
|
Once we have out mesh object ready to be filled, we pass it to our surface extractor of choice.
|
||||||
|
PolyVox comes with a number of different surface extractors but for our example here, we want a cubic mesh.
|
||||||
|
|
||||||
|
You should also note that the ungainly looking ``CubicSurfaceExtractorWithNormalsSimpleVolumeuint8`` refers to the C++ class ``CubicSurfaceExtractorWithNormals<SimpleVolume<uint8_t>>``.
|
||||||
|
The ``execute()`` call is when PolyVox actually goes off and generates the requested mesh based on the data contained in the volume.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 55-58
|
||||||
|
|
||||||
|
Up until this point, the Python code has been totally generic with respect to your choice of rendering engine.
|
||||||
|
For this example we will be using `PyOpenGL <http://pyopengl.sourceforge.net/>`_ as it provides a nice pythonic API for many OpenGL functions.
|
||||||
|
|
||||||
|
Regardless of which rendering engine you are using, you will need to be able to wrangle the PolyVox mesh output into something you can insert into your engine.
|
||||||
|
In our case, we want two lists:
|
||||||
|
|
||||||
|
1. All the vertices along with their normals
|
||||||
|
2. The vertex indices which describes how the vertices are put together to make triangles.
|
||||||
|
|
||||||
|
PyOpenGL undersands `NumPy <http://numpy.org>`_ arrays and so we are going to copy our vertex data into two of these.
|
||||||
|
:polyvox:`SurfaceMesh` provides two useful functions here, ``getIndices()`` and ``getVertices()``, the Python versions of which return Python tuples.
|
||||||
|
|
||||||
|
The indices we can pass directly to NumPy as long as we make sure we specify the correct type for the data inside.
|
||||||
|
For the vertices, we want to rearange the data so that OpenGL can read it more efficiently.
|
||||||
|
To this end we explicitly retrieve the vertex positions and normals for each vertex and place them
|
||||||
|
such that the vertex ``x``, ``y`` and ``z`` positions are placed contiguously in memory followed by the normal vector's ``x``, ``y`` and ``z`` values.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/Python/PythonExample.py
|
||||||
|
:language: python
|
||||||
|
:lines: 62-69
|
||||||
|
|
||||||
|
From this point on in the example, PolyVox is no longer used directly and all the code is standard PyOpenGL.
|
||||||
|
I won't go through every line here but the source code in ``PythonExample.py`` is commented and should be sufficient to understand how things work.
|
@ -21,7 +21,6 @@ freely, subject to the following restrictions:
|
|||||||
distribution.
|
distribution.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include "PolyVoxCore/Log.h"
|
|
||||||
#include "PolyVoxCore/MaterialDensityPair.h"
|
#include "PolyVoxCore/MaterialDensityPair.h"
|
||||||
#include "PolyVoxCore/LargeVolume.h"
|
#include "PolyVoxCore/LargeVolume.h"
|
||||||
#include "PolyVoxCore/LowPassFilter.h"
|
#include "PolyVoxCore/LowPassFilter.h"
|
||||||
@ -47,32 +46,8 @@ using namespace std;
|
|||||||
using namespace PolyVox;
|
using namespace PolyVox;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void exampleLog(string message, int severity)
|
|
||||||
{
|
|
||||||
//Identify how severe the mesage is
|
|
||||||
switch(severity)
|
|
||||||
{
|
|
||||||
case LS_DEBUG:
|
|
||||||
cout << "DEBUG: ";
|
|
||||||
break;
|
|
||||||
case LS_INFO:
|
|
||||||
cout << "INFO: ";
|
|
||||||
break;
|
|
||||||
case LS_WARN:
|
|
||||||
cout << "WARN: ";
|
|
||||||
break;
|
|
||||||
case LS_ERROR:
|
|
||||||
cout << "ERROR: ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Print the message
|
|
||||||
cout << message << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
logHandler = &exampleLog;
|
|
||||||
LargeVolume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)));
|
LargeVolume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)));
|
||||||
|
|
||||||
//Make our volume contain a sphere in the center.
|
//Make our volume contain a sphere in the center.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (c) 2013 Matt Williams
|
# Copyright (c) 2013 Matt Williams
|
||||||
@ -33,23 +33,21 @@ r = pv.Region(pv.Vector3Dint32_t(0,0,0), pv.Vector3Dint32_t(63,63,63))
|
|||||||
vol = pv.SimpleVolumeuint8(r)
|
vol = pv.SimpleVolumeuint8(r)
|
||||||
|
|
||||||
#Now fill the volume with our data (a sphere)
|
#Now fill the volume with our data (a sphere)
|
||||||
v3dVolCenter = pv.Vector3Dint32_t(vol.getWidth() / 2, vol.getHeight() / 2, vol.getDepth() / 2)
|
v3dVolCenter = pv.Vector3Dint32_t(vol.getWidth() // 2, vol.getHeight() // 2, vol.getDepth() // 2)
|
||||||
sphereRadius = 30
|
sphereRadius = 30
|
||||||
#This three-level for loop iterates over every voxel in the volume
|
#This three-level for loop iterates over every voxel in the volume
|
||||||
for z in range(vol.getDepth()):
|
for z in range(vol.getDepth()):
|
||||||
for y in range(vol.getHeight()):
|
for y in range(vol.getHeight()):
|
||||||
for x in range(vol.getWidth()):
|
for x in range(vol.getWidth()):
|
||||||
#Store our current position as a vector...
|
#Compute how far the current position is from the center of the volume
|
||||||
v3dCurrentPos = pv.Vector3Dint32_t(x,y,z)
|
fDistToCenter = (pv.Vector3Dint32_t(x,y,z) - v3dVolCenter).length()
|
||||||
#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 the current voxel is less than 'radius' units from the center then we make it solid.
|
||||||
if(fDistToCenter <= sphereRadius):
|
if(fDistToCenter <= sphereRadius):
|
||||||
#Our new voxel value
|
#Our new voxel value
|
||||||
uVoxelValue = 255
|
uVoxelValue = 255
|
||||||
|
else:
|
||||||
|
uVoxelValue = 0
|
||||||
|
|
||||||
#Write the voxel value into the volume
|
#Write the voxel value into the volume
|
||||||
vol.setVoxelAt(x, y, z, uVoxelValue);
|
vol.setVoxelAt(x, y, z, uVoxelValue);
|
||||||
@ -97,20 +95,20 @@ def run():
|
|||||||
screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF)
|
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
|
#The first thing we do is print some OpenGL details and check that we have a good enough version
|
||||||
print "OpenGL Implementation Details:"
|
print("OpenGL Implementation Details:")
|
||||||
if glGetString(GL_VENDOR):
|
if glGetString(GL_VENDOR):
|
||||||
print "\tGL_VENDOR:", glGetString(GL_VENDOR)
|
print("\tGL_VENDOR: {}".format(glGetString(GL_VENDOR).decode()))
|
||||||
if glGetString(GL_RENDERER):
|
if glGetString(GL_RENDERER):
|
||||||
print "\tGL_RENDERER:", glGetString(GL_RENDERER)
|
print("\tGL_RENDERER: {}".format(glGetString(GL_RENDERER).decode()))
|
||||||
if glGetString(GL_VERSION):
|
if glGetString(GL_VERSION):
|
||||||
print "\tGL_VERSION:", glGetString(GL_VERSION)
|
print("\tGL_VERSION: {}".format(glGetString(GL_VERSION).decode()))
|
||||||
if glGetString(GL_SHADING_LANGUAGE_VERSION):
|
if glGetString(GL_SHADING_LANGUAGE_VERSION):
|
||||||
print "\tGL_SHADING_LANGUAGE_VERSION:", glGetString(GL_SHADING_LANGUAGE_VERSION)
|
print("\tGL_SHADING_LANGUAGE_VERSION: {}".format(glGetString(GL_SHADING_LANGUAGE_VERSION).decode()))
|
||||||
|
|
||||||
major_version = int(glGetString(GL_VERSION).split()[0].split('.')[0])
|
major_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[0])
|
||||||
minor_version = int(glGetString(GL_VERSION).split()[0].split('.')[1])
|
minor_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[1])
|
||||||
if major_version < 3 or (major_version < 3 and minor_version < 0):
|
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])
|
print("OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).decode().split()[0]))
|
||||||
|
|
||||||
#Now onto the OpenGL initialisation
|
#Now onto the OpenGL initialisation
|
||||||
|
|
||||||
@ -123,7 +121,7 @@ def run():
|
|||||||
|
|
||||||
#We create out shaders which do little more than set a flat colour for each face
|
#We create out shaders which do little more than set a flat colour for each face
|
||||||
|
|
||||||
VERTEX_SHADER = shaders.compileShader("""
|
VERTEX_SHADER = shaders.compileShader(b"""
|
||||||
#version 130
|
#version 130
|
||||||
|
|
||||||
in vec4 position;
|
in vec4 position;
|
||||||
@ -145,7 +143,8 @@ def run():
|
|||||||
}
|
}
|
||||||
""", GL_VERTEX_SHADER)
|
""", GL_VERTEX_SHADER)
|
||||||
|
|
||||||
FRAGMENT_SHADER = shaders.compileShader("""
|
|
||||||
|
FRAGMENT_SHADER = shaders.compileShader(b"""
|
||||||
#version 130
|
#version 130
|
||||||
|
|
||||||
flat in float theColor;
|
flat in float theColor;
|
||||||
@ -160,8 +159,8 @@ def run():
|
|||||||
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
|
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
|
||||||
|
|
||||||
#And then grab our attribute locations from it
|
#And then grab our attribute locations from it
|
||||||
glBindAttribLocation(shader, 0, "position")
|
glBindAttribLocation(shader, 0, b"position")
|
||||||
glBindAttribLocation(shader, 1, "normal")
|
glBindAttribLocation(shader, 1, b"normal")
|
||||||
|
|
||||||
#Create the Vertex Array Object to hold our volume mesh
|
#Create the Vertex Array Object to hold our volume mesh
|
||||||
vertexArrayObject = GLuint(0)
|
vertexArrayObject = GLuint(0)
|
||||||
@ -184,9 +183,9 @@ def run():
|
|||||||
glDisableVertexAttribArray(0)
|
glDisableVertexAttribArray(0)
|
||||||
|
|
||||||
#Now grab out transformation martix locations
|
#Now grab out transformation martix locations
|
||||||
modelToWorldMatrixUnif = glGetUniformLocation(shader, "modelToWorldMatrix")
|
modelToWorldMatrixUnif = glGetUniformLocation(shader, b"modelToWorldMatrix")
|
||||||
worldToCameraMatrixUnif = glGetUniformLocation(shader, "worldToCameraMatrix")
|
worldToCameraMatrixUnif = glGetUniformLocation(shader, b"worldToCameraMatrix")
|
||||||
cameraToClipMatrixUnif = glGetUniformLocation(shader, "cameraToClipMatrix")
|
cameraToClipMatrixUnif = glGetUniformLocation(shader, b"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')
|
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')
|
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')
|
||||||
|
@ -32,7 +32,6 @@ SET(CORE_SRC_FILES
|
|||||||
source/ArraySizes.cpp
|
source/ArraySizes.cpp
|
||||||
source/AStarPathfinder.cpp
|
source/AStarPathfinder.cpp
|
||||||
source/MinizCompressor.cpp
|
source/MinizCompressor.cpp
|
||||||
source/Log.cpp
|
|
||||||
source/Region.cpp
|
source/Region.cpp
|
||||||
source/VertexTypes.cpp
|
source/VertexTypes.cpp
|
||||||
)
|
)
|
||||||
@ -66,7 +65,6 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/LargeVolume.h
|
include/PolyVoxCore/LargeVolume.h
|
||||||
include/PolyVoxCore/LargeVolume.inl
|
include/PolyVoxCore/LargeVolume.inl
|
||||||
include/PolyVoxCore/LargeVolumeSampler.inl
|
include/PolyVoxCore/LargeVolumeSampler.inl
|
||||||
include/PolyVoxCore/Log.h
|
|
||||||
include/PolyVoxCore/LowPassFilter.h
|
include/PolyVoxCore/LowPassFilter.h
|
||||||
include/PolyVoxCore/LowPassFilter.inl
|
include/PolyVoxCore/LowPassFilter.inl
|
||||||
include/PolyVoxCore/MarchingCubesSurfaceExtractor.h
|
include/PolyVoxCore/MarchingCubesSurfaceExtractor.h
|
||||||
@ -75,6 +73,8 @@ SET(CORE_INC_FILES
|
|||||||
include/PolyVoxCore/MaterialDensityPair.h
|
include/PolyVoxCore/MaterialDensityPair.h
|
||||||
include/PolyVoxCore/MinizCompressor.h
|
include/PolyVoxCore/MinizCompressor.h
|
||||||
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
||||||
|
include/PolyVoxCore/Picking.h
|
||||||
|
include/PolyVoxCore/Picking.inl
|
||||||
include/PolyVoxCore/RawVolume.h
|
include/PolyVoxCore/RawVolume.h
|
||||||
include/PolyVoxCore/RawVolume.inl
|
include/PolyVoxCore/RawVolume.inl
|
||||||
include/PolyVoxCore/RawVolumeSampler.inl
|
include/PolyVoxCore/RawVolumeSampler.inl
|
||||||
|
@ -298,7 +298,7 @@ namespace PolyVox
|
|||||||
hVal = SixConnectedCost(a, b);
|
hVal = SixConnectedCost(a, b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
POLYVOX_ASSERT(false, "Invalid case");
|
POLYVOX_THROW(std::invalid_argument, "Connectivity parameter has an unrecognised value.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sanity checks in debug mode. These can come out eventually, but I
|
//Sanity checks in debug mode. These can come out eventually, but I
|
||||||
|
@ -34,15 +34,24 @@ namespace PolyVox
|
|||||||
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
template<typename VolumeType, typename IsVoxelTransparentCallback>
|
||||||
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback)
|
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback)
|
||||||
{
|
{
|
||||||
|
//Make sure that the size of the volume is an exact multiple of the size of the array.
|
||||||
|
if(volInput->getWidth() % arrayResult->getDimension(0) != 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array width.");
|
||||||
|
}
|
||||||
|
if(volInput->getHeight() % arrayResult->getDimension(1) != 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array height.");
|
||||||
|
}
|
||||||
|
if(volInput->getDepth() % arrayResult->getDimension(2) != 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Volume width must be an exact multiple of array depth.");
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t uRandomUnitVectorIndex = 0;
|
uint16_t uRandomUnitVectorIndex = 0;
|
||||||
uint16_t uRandomVectorIndex = 0;
|
uint16_t uRandomVectorIndex = 0;
|
||||||
uint16_t uIndexIncreament;
|
uint16_t uIndexIncreament;
|
||||||
|
|
||||||
//Make sure that the size of the volume is an exact multiple of the size of the array.
|
|
||||||
POLYVOX_ASSERT(volInput->getWidth() % arrayResult->getDimension(0) == 0, "Volume width must be an exact multiple of array width.");
|
|
||||||
POLYVOX_ASSERT(volInput->getHeight() % arrayResult->getDimension(1) == 0, "Volume height must be an exact multiple of array height.");
|
|
||||||
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.
|
||||||
uRandomUnitVectorIndex += region.getLowerX() + region.getLowerY() + region.getLowerZ();
|
uRandomUnitVectorIndex += region.getLowerX() + region.getLowerY() + region.getLowerZ();
|
||||||
|
@ -73,7 +73,11 @@ 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)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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 +95,11 @@ 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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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 +147,10 @@ namespace PolyVox
|
|||||||
m_uNoOfElements = 1;
|
m_uNoOfElements = 1;
|
||||||
for (uint32_t i = 0; i<noOfDims; i++)
|
for (uint32_t i = 0; i<noOfDims; i++)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(pDimensions[i] != 0, "Invalid dimension");
|
if(pDimensions[i] == 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Invalid array dimension");
|
||||||
|
}
|
||||||
|
|
||||||
m_uNoOfElements *= pDimensions[i];
|
m_uNoOfElements *= pDimensions[i];
|
||||||
m_pDimensions[i] = pDimensions[i];
|
m_pDimensions[i] = pDimensions[i];
|
||||||
@ -186,7 +197,11 @@ 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)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uDimension < noOfDims, "Dimension out of range");
|
if(uDimension >= noOfDims)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array dimension out of range");
|
||||||
|
}
|
||||||
|
|
||||||
return m_pDimensions[uDimension];
|
return m_pDimensions[uDimension];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,14 +213,14 @@ namespace PolyVox
|
|||||||
,m_uNoOfElements(0)
|
,m_uNoOfElements(0)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
POLYVOX_ASSERT(false, "Not implemented.");
|
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
POLYVOX_ASSERT(false, "Not implemented.");
|
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -251,14 +266,22 @@ namespace PolyVox
|
|||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||||
|
}
|
||||||
|
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,14 +330,14 @@ namespace PolyVox
|
|||||||
,m_pDimensions(0)
|
,m_pDimensions(0)
|
||||||
{
|
{
|
||||||
//Not implemented
|
//Not implemented
|
||||||
POLYVOX_ASSERT(false, "Not implemented.");
|
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
POLYVOX_ASSERT(false, "Not implemented.");
|
POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ freely, subject to the following restrictions:
|
|||||||
#ifndef __PolyVox_BaseVolume_H__
|
#ifndef __PolyVox_BaseVolume_H__
|
||||||
#define __PolyVox_BaseVolume_H__
|
#define __PolyVox_BaseVolume_H__
|
||||||
|
|
||||||
#include "PolyVoxCore/Log.h"
|
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
BaseVolume<VoxelType>::BaseVolume(const BaseVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -59,14 +59,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<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
BaseVolume<VoxelType>& BaseVolume<VoxelType>::operator=(const BaseVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
POLYVOX_THROW(not_implemented, "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
|
||||||
POLYVOX_ASSERT(false, "Invalid case.");
|
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,24 +37,28 @@ 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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
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);
|
||||||
}
|
}
|
||||||
|
@ -220,9 +220,9 @@ 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.
|
||||||
// this can happen so let's put an assert to make sure. If you hit this assert then please report it to us!
|
// This shouldn't ever happen, so if it does it is probably a bug in PolyVox. Please report it to us!
|
||||||
POLYVOX_ASSERT(false, "All slots full but no matches.");
|
POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox");
|
||||||
return -1; //Should never happen.
|
return -1; //Should never happen.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +60,10 @@ 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
|
||||||
{
|
{
|
||||||
|
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
return m_tUncompressedData
|
return m_tUncompressedData
|
||||||
@ -83,10 +83,10 @@ 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)
|
||||||
{
|
{
|
||||||
|
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
m_tUncompressedData
|
m_tUncompressedData
|
||||||
@ -108,9 +108,6 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
@ -141,8 +138,16 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::compress(Compressor* pCompressor)
|
void Block<VoxelType>::compress(Compressor* pCompressor)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
if(m_bIsCompressed)
|
||||||
POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed.");
|
{
|
||||||
|
POLYVOX_THROW(invalid_operation, "Attempted to compress block which is already flagged as compressed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pCompressor)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||||
|
}
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
|
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
|
||||||
@ -212,8 +217,16 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Block<VoxelType>::uncompress(Compressor* pCompressor)
|
void Block<VoxelType>::uncompress(Compressor* pCompressor)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
|
if(!m_bIsCompressed)
|
||||||
POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed.");
|
{
|
||||||
|
POLYVOX_THROW(invalid_operation, "Attempted to uncompress block which is not flagged as compressed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pCompressor)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||||
|
}
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
|
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];
|
||||||
|
@ -29,11 +29,16 @@ freely, subject to the following restrictions:
|
|||||||
#include <cstdlib> // For std::exit
|
#include <cstdlib> // For std::exit
|
||||||
#include <iostream> // For std::cerr
|
#include <iostream> // For std::cerr
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string.h> // Exception constuctors take strings.
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
// In Visual Studio we can use this function to go into the debugger.
|
||||||
#define POLYVOX_HALT() __debugbreak()
|
#define POLYVOX_HALT() __debugbreak()
|
||||||
#else
|
#else
|
||||||
#define POLYVOX_HALT() std::exit(EXIT_FAILURE)
|
// On other platforms we just halt by forcing a crash.
|
||||||
|
// Hopefully this puts us in the debugger if one is running
|
||||||
|
#define POLYVOX_HALT() *((unsigned int*)0) = 0xDEAD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Macros cannot contain #ifdefs, but some of our macros need to disable warnings and such warning supression is
|
// Macros cannot contain #ifdefs, but some of our macros need to disable warnings and such warning supression is
|
||||||
@ -51,6 +56,44 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#define POLYVOX_UNUSED(x) do { (void)sizeof(x); } while(0)
|
#define POLYVOX_UNUSED(x) do { (void)sizeof(x); } while(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Logging
|
||||||
|
* --------
|
||||||
|
* PolyVox provides basic logging facilities which can be redirected by your application.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
class LogLevels
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum LogLevel
|
||||||
|
{
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
Fatal
|
||||||
|
};
|
||||||
|
};
|
||||||
|
typedef LogLevels::LogLevel LogLevel;
|
||||||
|
|
||||||
|
typedef void (*LogHandler)(const std::string& message, LogLevel logLevel);
|
||||||
|
|
||||||
|
LogHandler getLogHandler();
|
||||||
|
void setLogHandler(LogHandler newHandler);
|
||||||
|
|
||||||
|
// The actual logging function
|
||||||
|
void log(const std::string& message, LogLevel logLevel);
|
||||||
|
|
||||||
|
// Some handy wrappers
|
||||||
|
void logDebug (const std::string& message);
|
||||||
|
void logInfo (const std::string& message);
|
||||||
|
void logWarning(const std::string& message);
|
||||||
|
void logError (const std::string& message);
|
||||||
|
void logFatal (const std::string& message);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assertions
|
* Assertions
|
||||||
* ----------
|
* ----------
|
||||||
@ -71,12 +114,14 @@ freely, subject to the following restrictions:
|
|||||||
{ \
|
{ \
|
||||||
if (!(condition)) \
|
if (!(condition)) \
|
||||||
{ \
|
{ \
|
||||||
std::cerr << std::endl << std::endl; \
|
std::stringstream ss; \
|
||||||
std::cerr << " PolyVox Assertion Failed!" << std::endl; \
|
ss << std::endl << std::endl; \
|
||||||
std::cerr << " =========================" << std::endl; \
|
ss << " PolyVox Assertion Failed!" << std::endl; \
|
||||||
std::cerr << " Condition: " << #condition << std::endl; \
|
ss << " =========================" << std::endl; \
|
||||||
std::cerr << " Message: " << (message) << std::endl; \
|
ss << " Condition: " << #condition << std::endl; \
|
||||||
std::cerr << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
|
ss << " Message: " << (message) << std::endl; \
|
||||||
|
ss << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \
|
||||||
|
logFatal(ss.str()); \
|
||||||
POLYVOX_HALT(); \
|
POLYVOX_HALT(); \
|
||||||
} \
|
} \
|
||||||
} while(0) \
|
} while(0) \
|
||||||
@ -130,7 +175,9 @@ freely, subject to the following restrictions:
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
#ifdef POLYVOX_THROW_ENABLED
|
#ifdef POLYVOX_THROW_ENABLED
|
||||||
#define POLYVOX_THROW(type, message) throw type((message))
|
#define POLYVOX_THROW(type, message) \
|
||||||
|
log(message, LogLevels::Error); \
|
||||||
|
throw type((message))
|
||||||
#else
|
#else
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
@ -141,8 +188,37 @@ freely, subject to the following restrictions:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define POLYVOX_THROW(type, message) \
|
#define POLYVOX_THROW(type, message) \
|
||||||
|
log(message, LogLevels::Error); \
|
||||||
type except = (type)((message)); \
|
type except = (type)((message)); \
|
||||||
getThrowHandler()((except), __FILE__, __LINE__)
|
getThrowHandler()((except), __FILE__, __LINE__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
/// A general purpose exception to indicate that an operation cannot be peformed.
|
||||||
|
class invalid_operation : public std::logic_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit invalid_operation(const std::string& message)
|
||||||
|
: logic_error(message.c_str()) {}
|
||||||
|
|
||||||
|
explicit invalid_operation(const char *message)
|
||||||
|
: logic_error(message) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Thrown to indicate that a function is deliberatly not implmented. For example, perhaps you called a function
|
||||||
|
/// in a base class whereas you are supposed to use a derived class which implements the function, or perhaps the
|
||||||
|
/// function is not defined for a particular template parameter. It may be that the function is required to
|
||||||
|
/// compile sucessfully but it should not be called.
|
||||||
|
class not_implemented : public std::logic_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit not_implemented(const std::string& message)
|
||||||
|
: logic_error(message.c_str()) {}
|
||||||
|
|
||||||
|
explicit not_implemented(const char *message)
|
||||||
|
: logic_error(message) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif //__PolyVox_ErrorHandling_H__
|
#endif //__PolyVox_ErrorHandling_H__
|
||||||
|
@ -28,7 +28,11 @@ 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)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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 +41,11 @@ 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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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 +64,22 @@ namespace PolyVox
|
|||||||
template <typename ElementType>
|
template <typename ElementType>
|
||||||
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
|
ElementType& SubArray<1, ElementType>::operator[] (uint32_t uIndex)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array 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
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(uIndex < m_pDimensions[0], "Index out of range");
|
if(uIndex >= m_pDimensions[0])
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||||
|
}
|
||||||
|
|
||||||
return m_pElements[uIndex];
|
return m_pElements[uIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ namespace PolyVox
|
|||||||
const Type& v0,const Type& v1,
|
const Type& v0,const Type& v1,
|
||||||
const float x)
|
const float x)
|
||||||
{
|
{
|
||||||
|
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||||
POLYVOX_ASSERT((x >= 0.0f) && (x <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
POLYVOX_ASSERT((x >= 0.0f) && (x <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
//Interpolate along X
|
//Interpolate along X
|
||||||
@ -44,6 +45,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||||
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) &&
|
POLYVOX_ASSERT((x >= 0.0f) && (y >= 0.0f) &&
|
||||||
(x <= 1.0f) && (y <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
(x <= 1.0f) && (y <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
//This function is called frequently and is very short, so assert rather than exceptions.
|
||||||
POLYVOX_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), "Interpolation input out of 0.0 to 1.0 range.");
|
(x <= 1.0f) && (y <= 1.0f) && (z <= 1.0f), "Interpolation input out of 0.0 to 1.0 range.");
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ 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/Compressor.h"
|
||||||
#include "PolyVoxCore/Log.h"
|
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
|
LargeVolume<VoxelType>::LargeVolume(const LargeVolume<VoxelType>& /*rhs*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -112,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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -124,6 +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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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;
|
||||||
@ -228,7 +229,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
POLYVOX_ASSERT(false, "Invlaid case.");
|
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,6 +283,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)
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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;
|
||||||
@ -446,12 +448,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
//Validate parameters
|
||||||
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
|
|
||||||
if(uBlockSideLength == 0)
|
if(uBlockSideLength == 0)
|
||||||
{
|
{
|
||||||
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");
|
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");
|
||||||
|
@ -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.
|
||||||
POLYVOX_ASSERT(false, "This function cnnot be used on LargeVolume samplers.");
|
POLYVOX_THROW(not_implemented, "This function cannot be used on LargeVolume samplers.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
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_Log_H__
|
|
||||||
#define __PolyVox_Log_H__
|
|
||||||
|
|
||||||
#include "Impl/TypeDef.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
//Note: The functions in this file are not for the user to call - they are
|
|
||||||
//intended for internal use only. The only exception is that you may set the
|
|
||||||
//logHandler pointer to point at your own handling funtion for printing, etc.
|
|
||||||
|
|
||||||
namespace PolyVox
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Log levels for filtering logging events
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
enum LogSeverity
|
|
||||||
{
|
|
||||||
LS_DEBUG, ///< Only displayed if it is a debug build
|
|
||||||
LS_INFO,
|
|
||||||
LS_WARN,
|
|
||||||
LS_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
POLYVOX_API extern void (*logHandler)(std::string, int severity);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Debug severity messages are only used if we are a debug build
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#define POLYVOX_LOG_DEBUG(message) if(logHandler){logHandler(message, LS_DEBUG);}
|
|
||||||
#else
|
|
||||||
#define POLYVOX_LOG_DEBUG(message)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Other severity levels work in both debug and release
|
|
||||||
#define POLYVOX_LOG_INFO(message) if(logHandler){logHandler(message, LS_INFO);}
|
|
||||||
#define POLYVOX_LOG_WARN(message) if(logHandler){logHandler(message, LS_WARN);}
|
|
||||||
#define POLYVOX_LOG_ERROR(message) if(logHandler){logHandler(message, LS_ERROR);}
|
|
||||||
|
|
||||||
#endif
|
|
@ -39,14 +39,15 @@ namespace PolyVox
|
|||||||
,m_uKernelSize(uKernelSize)
|
,m_uKernelSize(uKernelSize)
|
||||||
{
|
{
|
||||||
//Kernel size must be at least three
|
//Kernel size must be at least three
|
||||||
POLYVOX_ASSERT(m_uKernelSize >= 3, "Kernel size must be at least three");
|
if(m_uKernelSize < 3)
|
||||||
m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3)); //For release builds
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three");
|
||||||
|
}
|
||||||
|
|
||||||
//Kernel size must be odd
|
//Kernel size must be odd
|
||||||
POLYVOX_ASSERT(m_uKernelSize % 2 == 1, "Kernel size must be odd");
|
if(m_uKernelSize % 2 == 0)
|
||||||
if(m_uKernelSize % 2 == 0) //For release builds
|
|
||||||
{
|
{
|
||||||
m_uKernelSize++;
|
POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
library/PolyVoxCore/include/PolyVoxCore/Picking.h
Normal file
49
library/PolyVoxCore/include/PolyVoxCore/Picking.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
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.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PolyVox_Picking_H__
|
||||||
|
#define __PolyVox_Picking_H__
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A structure containing the information about a picking operation
|
||||||
|
*/
|
||||||
|
struct PickResult
|
||||||
|
{
|
||||||
|
PickResult() : didHit(false) {}
|
||||||
|
bool didHit; ///< Did the picking operation hit anything
|
||||||
|
Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit
|
||||||
|
Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Pick the first solid voxel along a vector
|
||||||
|
template<typename VolumeType>
|
||||||
|
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Picking.inl"
|
||||||
|
|
||||||
|
#endif //__PolyVox_Picking_H__
|
84
library/PolyVoxCore/include/PolyVoxCore/Picking.inl
Normal file
84
library/PolyVoxCore/include/PolyVoxCore/Picking.inl
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
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.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Raycast.h"
|
||||||
|
|
||||||
|
namespace PolyVox
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This is just an implementation class for the pickVoxel function
|
||||||
|
*
|
||||||
|
* It makes note of the sort of empty voxel you're looking for in the constructor.
|
||||||
|
*
|
||||||
|
* Each time the operator() is called:
|
||||||
|
* * if it's hit a voxel it sets up the result and returns false
|
||||||
|
* * otherwise it preps the result for the next iteration and returns true
|
||||||
|
*/
|
||||||
|
template <typename VolumeType>
|
||||||
|
class RaycastPickingFunctor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample)
|
||||||
|
:m_emptyVoxelExample(emptyVoxelExample)
|
||||||
|
,m_result()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const typename VolumeType::Sampler& sampler)
|
||||||
|
{
|
||||||
|
if(sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something
|
||||||
|
{
|
||||||
|
m_result.didHit = true;
|
||||||
|
m_result.hitVoxel = sampler.getPosition();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_result.previousVoxel = sampler.getPosition();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const typename VolumeType::VoxelType& m_emptyVoxelExample;
|
||||||
|
PickResult m_result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param volData The volume to pass the ray though
|
||||||
|
* \param v3dStart The start position in the volume
|
||||||
|
* \param v3dDirectionAndLength The direction and length of the ray
|
||||||
|
* \param emptyVoxelExample The value used to represent empty voxels in your volume
|
||||||
|
*
|
||||||
|
* \return A PickResult containing the hit information
|
||||||
|
*/
|
||||||
|
template<typename VolumeType>
|
||||||
|
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample)
|
||||||
|
{
|
||||||
|
RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample);
|
||||||
|
|
||||||
|
raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor);
|
||||||
|
|
||||||
|
return functor.m_result;
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,6 @@ freely, subject to the following restrictions:
|
|||||||
#define __PolyVox_RawVolume_H__
|
#define __PolyVox_RawVolume_H__
|
||||||
|
|
||||||
#include "PolyVoxCore/BaseVolume.h"
|
#include "PolyVoxCore/BaseVolume.h"
|
||||||
#include "PolyVoxCore/Log.h"
|
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
|
@ -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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -82,6 +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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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();
|
||||||
@ -186,7 +187,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
POLYVOX_ASSERT(false, "Invalid case.");
|
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,10 +255,18 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
this->m_regValidRegion = regValidRegion;
|
this->m_regValidRegion = regValidRegion;
|
||||||
|
|
||||||
//Ensure dimensions of the specified Region are valid
|
if(this->getWidth() <= 0)
|
||||||
POLYVOX_ASSERT(this->getWidth() > 0, "Volume width must be greater than zero.");
|
{
|
||||||
POLYVOX_ASSERT(this->getHeight() > 0, "Volume width must be greater than zero.");
|
POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero.");
|
||||||
POLYVOX_ASSERT(this->getDepth() > 0, "Volume width must be greater than zero.");
|
}
|
||||||
|
if(this->getHeight() <= 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero.");
|
||||||
|
}
|
||||||
|
if(this->getDepth() <= 0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::invalid_argument, "Volume depth 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()];
|
||||||
|
@ -27,7 +27,6 @@ freely, subject to the following restrictions:
|
|||||||
#include "Impl/Utility.h"
|
#include "Impl/Utility.h"
|
||||||
|
|
||||||
#include "PolyVoxCore/BaseVolume.h"
|
#include "PolyVoxCore/BaseVolume.h"
|
||||||
#include "PolyVoxCore/Log.h"
|
|
||||||
#include "PolyVoxCore/Region.h"
|
#include "PolyVoxCore/Region.h"
|
||||||
#include "PolyVoxCore/Vector.h"
|
#include "PolyVoxCore/Vector.h"
|
||||||
|
|
||||||
|
@ -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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Copy constructor not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume copy constructor not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -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*/)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(false, "Assignment operator not implemented."); // See function comment above.
|
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -82,6 +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
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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;
|
||||||
@ -186,7 +187,7 @@ namespace PolyVox
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Should never happen
|
//Should never happen
|
||||||
POLYVOX_ASSERT(false, "Invalid case.");
|
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||||
return VoxelType();
|
return VoxelType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,6 +213,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)
|
||||||
{
|
{
|
||||||
|
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
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;
|
||||||
@ -247,11 +249,6 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
|
||||||
POLYVOX_ASSERT(uBlockSideLength >= 8, "Block side length should be at least 8");
|
|
||||||
POLYVOX_ASSERT(uBlockSideLength <= 256, "Block side length should not be more than 256");
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -52,10 +52,10 @@ 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
|
||||||
{
|
{
|
||||||
|
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||||
|
|
||||||
return m_tUncompressedData
|
return m_tUncompressedData
|
||||||
@ -75,10 +75,10 @@ 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)
|
||||||
{
|
{
|
||||||
|
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uXPos < m_uSideLength, "Position is outside of the block.");
|
||||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uYPos < m_uSideLength, "Position is outside of the block.");
|
||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Position is outside of the block.");
|
||||||
|
|
||||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data available");
|
||||||
|
|
||||||
m_tUncompressedData
|
m_tUncompressedData
|
||||||
@ -105,9 +105,6 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
|
void SimpleVolume<VoxelType>::Block::initialise(uint16_t uSideLength)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
@ -414,7 +414,11 @@ namespace PolyVox
|
|||||||
template <uint32_t Size, typename StorageType, typename OperationType>
|
template <uint32_t Size, typename StorageType, typename OperationType>
|
||||||
inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const
|
inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
|
if(index >= Size)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
|
||||||
|
}
|
||||||
|
|
||||||
return m_tElements[index];
|
return m_tElements[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +469,11 @@ namespace PolyVox
|
|||||||
template <uint32_t Size, typename StorageType, typename OperationType>
|
template <uint32_t Size, typename StorageType, typename OperationType>
|
||||||
inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue)
|
inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(index < Size, "Attempted to access invalid vector element.");
|
if(index >= Size)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
|
||||||
|
}
|
||||||
|
|
||||||
m_tElements[index] = tValue;
|
m_tElements[index] = tValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,10 +653,17 @@ namespace PolyVox
|
|||||||
inline void Vector<Size, StorageType, OperationType>::normalise(void)
|
inline void Vector<Size, StorageType, OperationType>::normalise(void)
|
||||||
{
|
{
|
||||||
float fLength = this->length();
|
float fLength = this->length();
|
||||||
|
if(fLength <= 0.0)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero");
|
||||||
|
}
|
||||||
|
|
||||||
for(uint32_t ct = 0; ct < Size; ++ct)
|
for(uint32_t ct = 0; ct < Size; ++ct)
|
||||||
{
|
{
|
||||||
// Standard float rules apply for divide-by-zero
|
// Standard float rules apply for divide-by-zero
|
||||||
m_tElements[ct] /= fLength;
|
m_tElements[ct] /= fLength;
|
||||||
|
|
||||||
|
//This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen.
|
||||||
POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?");
|
POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,31 +23,117 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||||
|
|
||||||
#ifndef POLYVOX_THROW_ENABLED
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
{
|
{
|
||||||
|
void defaultLogHandler(const std::string& message, LogLevel logLevel)
|
||||||
|
{
|
||||||
|
switch(logLevel)
|
||||||
|
{
|
||||||
|
case LogLevels::Debug:
|
||||||
|
{
|
||||||
|
// Debug messages are not output by this default log handler.
|
||||||
|
// Provide a custom handler if you want to process them.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LogLevels::Info:
|
||||||
|
{
|
||||||
|
std::cout << "Info: " << message.c_str() << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LogLevels::Warning:
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: " << message.c_str() << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LogLevels::Error:
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << message.c_str() << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LogLevels::Fatal:
|
||||||
|
{
|
||||||
|
std::cerr << "Fatal: " << message.c_str() << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogHandler& getLogHandlerInstance()
|
||||||
|
{
|
||||||
|
static LogHandler s_fLogHandler = &defaultLogHandler;
|
||||||
|
return s_fLogHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogHandler getLogHandler()
|
||||||
|
{
|
||||||
|
return getLogHandlerInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLogHandler(LogHandler fNewHandler)
|
||||||
|
{
|
||||||
|
getLogHandlerInstance() = fNewHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log(const std::string& message, LogLevel logLevel)
|
||||||
|
{
|
||||||
|
LogHandler logHandler = getLogHandler();
|
||||||
|
if(logHandler)
|
||||||
|
{
|
||||||
|
logHandler(message, logLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some handy wrappers
|
||||||
|
void logDebug(const std::string& message)
|
||||||
|
{
|
||||||
|
log(message, LogLevels::Debug );
|
||||||
|
}
|
||||||
|
|
||||||
|
void logInfo(const std::string& message)
|
||||||
|
{
|
||||||
|
log(message, LogLevels::Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logWarning(const std::string& message)
|
||||||
|
{
|
||||||
|
log(message, LogLevels::Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logError(const std::string& message)
|
||||||
|
{
|
||||||
|
log(message, LogLevels::Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logFatal(const std::string& message)
|
||||||
|
{
|
||||||
|
log(message, LogLevels::Fatal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef POLYVOX_THROW_ENABLED
|
||||||
void defaultThrowHandler(std::exception& e, const char* file, int line)
|
void defaultThrowHandler(std::exception& e, const char* file, int line)
|
||||||
{
|
{
|
||||||
std::cerr << std::endl << std::endl; \
|
std::stringstream ss; \
|
||||||
std::cerr << " PolyVox exception thrown!" << std::endl; \
|
ss << std::endl << std::endl; \
|
||||||
std::cerr << " =========================" << std::endl; \
|
ss << " PolyVox exception thrown!" << std::endl; \
|
||||||
std::cerr << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
|
ss << " =========================" << std::endl; \
|
||||||
std::cerr << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
|
ss << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \
|
||||||
std::cerr << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
|
ss << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \
|
||||||
|
ss << " and this message is being printed by the default throw handler." << std::endl << std::endl; \
|
||||||
|
|
||||||
std::cerr << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
|
ss << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \
|
||||||
std::cerr << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
|
ss << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \
|
||||||
std::cerr << " due to something like an invalid argument to a function then you should be" << std::endl; \
|
ss << " due to something like an invalid argument to a function then you should be" << std::endl; \
|
||||||
std::cerr << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
|
ss << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \
|
||||||
std::cerr << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
|
ss << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \
|
||||||
std::cerr << " you should replace this default handler with something which is more" << std::endl; \
|
ss << " you should replace this default handler with something which is more" << std::endl; \
|
||||||
std::cerr << " meaningful to your users." << std::endl << std::endl; \
|
ss << " meaningful to your users." << std::endl << std::endl; \
|
||||||
|
|
||||||
std::cerr << " Exception details" << std::endl; \
|
ss << " Exception details" << std::endl; \
|
||||||
std::cerr << " -----------------" << std::endl; \
|
ss << " -----------------" << std::endl; \
|
||||||
std::cerr << " Line: " << line << std::endl; \
|
ss << " Line: " << line << std::endl; \
|
||||||
std::cerr << " File: " << file << std::endl; \
|
ss << " File: " << file << std::endl; \
|
||||||
std::cerr << " Message: " << e.what() << std::endl << std::endl; \
|
ss << " Message: " << e.what() << std::endl << std::endl; \
|
||||||
|
logFatal(ss.str()); \
|
||||||
|
|
||||||
POLYVOX_HALT(); \
|
POLYVOX_HALT(); \
|
||||||
}
|
}
|
||||||
@ -67,5 +153,5 @@ freely, subject to the following restrictions:
|
|||||||
{
|
{
|
||||||
getThrowHandlerInstance() = fNewHandler;
|
getThrowHandlerInstance() = fNewHandler;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
@ -30,10 +30,6 @@ namespace PolyVox
|
|||||||
//If this is not the case then the output is undefined.
|
//If this is not the case then the output is undefined.
|
||||||
uint8_t logBase2(uint32_t uInput)
|
uint8_t logBase2(uint32_t uInput)
|
||||||
{
|
{
|
||||||
//Debug mode validation
|
|
||||||
POLYVOX_ASSERT(uInput != 0, "Cannot compute the log of zero.");
|
|
||||||
POLYVOX_ASSERT(isPowerOf2(uInput), "Input must be a power of two in order to compute the log.");
|
|
||||||
|
|
||||||
//Release mode validation
|
//Release mode validation
|
||||||
if(uInput == 0)
|
if(uInput == 0)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,10 @@ namespace PolyVox
|
|||||||
*/
|
*/
|
||||||
void Region::accumulate(const Region& reg)
|
void Region::accumulate(const Region& reg)
|
||||||
{
|
{
|
||||||
POLYVOX_ASSERT(reg.isValid(), "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
|
if(!reg.isValid())
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(invalid_operation, "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()));
|
||||||
|
@ -23,7 +23,7 @@ option(ENABLE_BINDINGS "Build Python bindings" ON)
|
|||||||
if(ENABLE_BINDINGS)
|
if(ENABLE_BINDINGS)
|
||||||
find_package(SWIG)
|
find_package(SWIG)
|
||||||
mark_as_advanced(SWIG_DIR SWIG_VERSION)
|
mark_as_advanced(SWIG_DIR SWIG_VERSION)
|
||||||
find_package(PythonLibs)
|
find_package(PythonLibs 3)
|
||||||
if(CMAKE_VERSION VERSION_LESS "2.8.6")
|
if(CMAKE_VERSION VERSION_LESS "2.8.6")
|
||||||
set_package_info(SWIG "Bindings generator" http://www.swig.org)
|
set_package_info(SWIG "Bindings generator" http://www.swig.org)
|
||||||
set_package_info(PythonLibs "Programming language" http://www.python.org)
|
set_package_info(PythonLibs "Programming language" http://www.python.org)
|
||||||
@ -43,6 +43,7 @@ if(ENABLE_BINDINGS)
|
|||||||
set_source_files_properties(PolyVoxCore.i PROPERTIES CPLUSPLUS ON)
|
set_source_files_properties(PolyVoxCore.i PROPERTIES CPLUSPLUS ON)
|
||||||
|
|
||||||
#set_source_files_properties(PolyVoxCore.i PROPERTIES SWIG_FLAGS "-builtin")
|
#set_source_files_properties(PolyVoxCore.i PROPERTIES SWIG_FLAGS "-builtin")
|
||||||
|
set(SWIG_MODULE_PolyVoxCorePython_EXTRA_FLAGS "-py3")
|
||||||
swig_add_module(PolyVoxCorePython python PolyVoxCore.i)
|
swig_add_module(PolyVoxCorePython python PolyVoxCore.i)
|
||||||
swig_link_libraries(PolyVoxCorePython ${PYTHON_LIBRARIES} PolyVoxCore)
|
swig_link_libraries(PolyVoxCorePython ${PYTHON_LIBRARIES} PolyVoxCore)
|
||||||
set_target_properties(${SWIG_MODULE_PolyVoxCorePython_REAL_NAME} PROPERTIES OUTPUT_NAME _PolyVoxCore)
|
set_target_properties(${SWIG_MODULE_PolyVoxCorePython_REAL_NAME} PROPERTIES OUTPUT_NAME _PolyVoxCore)
|
||||||
|
8
library/bindings/Picking.i
Normal file
8
library/bindings/Picking.i
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
%module Picking
|
||||||
|
%{
|
||||||
|
#include "Picking.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include "Picking.h"
|
||||||
|
|
||||||
|
EXTRACTORS(pickVoxel)
|
@ -90,3 +90,4 @@ EXTRACTOR(shortname, LargeVolume)
|
|||||||
%include "CubicSurfaceExtractor.i"
|
%include "CubicSurfaceExtractor.i"
|
||||||
%include "CubicSurfaceExtractorWithNormals.i"
|
%include "CubicSurfaceExtractorWithNormals.i"
|
||||||
%include "Raycast.i"
|
%include "Raycast.i"
|
||||||
|
%include "Picking.i"
|
||||||
|
@ -50,8 +50,16 @@ REMOVE_DEFINITIONS(-DQT_GUI_LIB) #Make sure the tests don't link to the QtGui
|
|||||||
|
|
||||||
# Python tests
|
# Python tests
|
||||||
IF(BUILD_BINDINGS)
|
IF(BUILD_BINDINGS)
|
||||||
ADD_TEST(PythonSurfaceExtractorTest python ${CMAKE_CURRENT_SOURCE_DIR}/TestSurfaceExtractor.py)
|
FIND_PACKAGE(PythonInterp 3)
|
||||||
ADD_TEST(PythonRaycastTest python ${CMAKE_CURRENT_SOURCE_DIR}/TestRaycast.py)
|
IF(CMAKE_VERSION VERSION_LESS "2.8.6")
|
||||||
|
set_package_info(PythonInterp "Python Interpereter" http://www.python.org "Running the Python tests")
|
||||||
|
ELSE()
|
||||||
|
set_package_properties(PythonInterp PROPERTIES URL http://www.python.org DESCRIPTION "Python Interpereter" TYPE OPTIONAL PURPOSE "Running the Python tests")
|
||||||
|
ENDIF()
|
||||||
|
IF(PYTHONINTERP_FOUND)
|
||||||
|
ADD_TEST(PythonSurfaceExtractorTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/TestSurfaceExtractor.py)
|
||||||
|
ADD_TEST(PythonRaycastTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/TestRaycast.py)
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# AmbientOcclusionGenerator tests
|
# AmbientOcclusionGenerator tests
|
||||||
@ -81,6 +89,10 @@ ADD_TEST(MaterialTestCompile ${LATEST_TEST} testCompile)
|
|||||||
CREATE_TEST(TestRaycast.h TestRaycast.cpp TestRaycast)
|
CREATE_TEST(TestRaycast.h TestRaycast.cpp TestRaycast)
|
||||||
ADD_TEST(RaycastExecuteTest ${LATEST_TEST} testExecute)
|
ADD_TEST(RaycastExecuteTest ${LATEST_TEST} testExecute)
|
||||||
|
|
||||||
|
# Picking tests
|
||||||
|
CREATE_TEST(TestPicking.h TestPicking.cpp TestPicking)
|
||||||
|
ADD_TEST(PickingExecuteTest ${LATEST_TEST} testExecute)
|
||||||
|
|
||||||
# Region tests
|
# Region tests
|
||||||
CREATE_TEST(TestRegion.h TestRegion.cpp TestRegion)
|
CREATE_TEST(TestRegion.h TestRegion.cpp TestRegion)
|
||||||
ADD_TEST(RegionEqualityTest ${LATEST_TEST} testEquality)
|
ADD_TEST(RegionEqualityTest ${LATEST_TEST} testEquality)
|
||||||
|
68
tests/TestPicking.cpp
Normal file
68
tests/TestPicking.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
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.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include "TestPicking.h"
|
||||||
|
|
||||||
|
#include "PolyVoxCore/Picking.h"
|
||||||
|
#include "PolyVoxCore/SimpleVolume.h"
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
using namespace PolyVox;
|
||||||
|
|
||||||
|
void TestPicking::testExecute()
|
||||||
|
{
|
||||||
|
const int32_t uVolumeSideLength = 32;
|
||||||
|
|
||||||
|
SimpleVolume<int8_t> volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(uVolumeSideLength-1, uVolumeSideLength-1, uVolumeSideLength-1)));
|
||||||
|
for (int32_t z = 0; z < uVolumeSideLength; z++)
|
||||||
|
{
|
||||||
|
for (int32_t y = 0; y < uVolumeSideLength; y++)
|
||||||
|
{
|
||||||
|
for (int32_t x = 0; x < uVolumeSideLength; x++)
|
||||||
|
{
|
||||||
|
if((x > uVolumeSideLength/2)) //x > 16 is filled
|
||||||
|
{
|
||||||
|
volData.setVoxelAt(x, y, z, 100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
volData.setVoxelAt(x, y, z, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int8_t emptyVoxelExample = 0; //A voxel value of zero will represent empty space.
|
||||||
|
PickResult resultHit = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength, 0, 0), emptyVoxelExample);
|
||||||
|
|
||||||
|
QCOMPARE(resultHit.didHit, true);
|
||||||
|
QCOMPARE(resultHit.hitVoxel, Vector3DInt32((uVolumeSideLength / 2) + 1, uVolumeSideLength / 2, uVolumeSideLength / 2));
|
||||||
|
QCOMPARE(resultHit.previousVoxel, Vector3DInt32((uVolumeSideLength / 2), uVolumeSideLength / 2, uVolumeSideLength / 2));
|
||||||
|
|
||||||
|
PickResult resultMiss = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength / 2, uVolumeSideLength, uVolumeSideLength), emptyVoxelExample);
|
||||||
|
|
||||||
|
QCOMPARE(resultMiss.didHit, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(TestPicking)
|
@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
Copyright (c) 2005-2009 David Williams
|
Copyright (c) 2013 Matt Williams
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
@ -21,9 +21,17 @@ freely, subject to the following restrictions:
|
|||||||
distribution.
|
distribution.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include "PolyVoxCore/Log.h"
|
#ifndef __PolyVox_TestRaycast_H__
|
||||||
|
#define __PolyVox_TestRaycast_H__
|
||||||
|
|
||||||
namespace PolyVox
|
#include <QObject>
|
||||||
|
|
||||||
|
class TestPicking: public QObject
|
||||||
{
|
{
|
||||||
void (*logHandler)(std::string, int severity) = 0;
|
Q_OBJECT
|
||||||
}
|
|
||||||
|
private slots:
|
||||||
|
void testExecute();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user