From e90215b0fc4b55859501a8716e82e576ec664f04 Mon Sep 17 00:00:00 2001 From: Matt Williams Date: Wed, 16 Jan 2013 15:29:17 +0000 Subject: [PATCH 1/6] These names only make sense for Python In future, it might make sense to use these names as the intermediate names for C# and Java too but for now, keep them separate. --- library/bindings/Vector.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/bindings/Vector.i b/library/bindings/Vector.i index 37d0b3ab..188333e7 100644 --- a/library/bindings/Vector.i +++ b/library/bindings/Vector.i @@ -13,6 +13,7 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ) #endif %extend PolyVox::Vector { +#ifdef SWIGPYTHON PolyVox::Vector __add__(const PolyVox::Vector& rhs) { return *$self + rhs; } @@ -31,6 +32,7 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ) PolyVox::Vector __mul__(const StorageType& rhs) { return *$self * rhs; } +#endif STR() }; From bab3c32ec5a38c0c4d8ec9055d082f5891490093 Mon Sep 17 00:00:00 2001 From: Matt Williams Date: Wed, 16 Jan 2013 15:30:22 +0000 Subject: [PATCH 2/6] Wrap the Vector operators for C# This should allow all the normal vector operations as well as silence the warnings from SWIG. --- library/bindings/Vector.i | 69 +++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/library/bindings/Vector.i b/library/bindings/Vector.i index 188333e7..ac6eed46 100644 --- a/library/bindings/Vector.i +++ b/library/bindings/Vector.i @@ -12,6 +12,13 @@ PROPERTY(PolyVox::Vector, y, getY, setY) PROPERTY(PolyVox::Vector, z, getZ, setZ) #endif +%rename(Plus) operator +; +%rename(Minus) operator -; +%rename(Multiply) operator *; +%rename(Divide) operator /; +%rename(Equal) operator ==; +%rename(NotEqual) operator !=; + %extend PolyVox::Vector { #ifdef SWIGPYTHON PolyVox::Vector __add__(const PolyVox::Vector& rhs) { @@ -44,12 +51,62 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ) //%csattributes PolyVox::Vector::operator< "[System.Obsolete(\"deprecated\")]" %define VECTOR3(StorageType,OperationType,ReducedStorageType) -%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType); -%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType); -%ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const; -%ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType); -%ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType); -%template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>; + #if SWIGCSHARP + %extend PolyVox::Vector<3,StorageType,OperationType> { + PolyVox::Vector<3,StorageType,OperationType> operator+(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self + rhs;} + PolyVox::Vector<3,StorageType,OperationType> operator-(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self - rhs;} + PolyVox::Vector<3,StorageType,OperationType> operator*(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self * rhs;} + PolyVox::Vector<3,StorageType,OperationType> operator/(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self / rhs;} + PolyVox::Vector<3,StorageType,OperationType> operator*(const StorageType& rhs) {return *$self * rhs;} + PolyVox::Vector<3,StorageType,OperationType> operator/(const StorageType& rhs) {return *$self / rhs;} + }; + %typemap(cscode) PolyVox::Vector<3,StorageType,OperationType> %{ + public static Vector3D##StorageType operator+(Vector3D##StorageType lhs, Vector3D##StorageType rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Plus(rhs); + return newVec; + } + public static Vector3D##StorageType operator-(Vector3D##StorageType lhs, Vector3D##StorageType rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Minus(rhs); + return newVec; + } + public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, Vector3D##StorageType rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Multiply(rhs); + return newVec; + } + public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, Vector3D##StorageType rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Divide(rhs); + return newVec; + } + public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Multiply(rhs); + return newVec; + } + public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) { + Vector3D##StorageType newVec = new Vector3D##StorageType(); + newVec = lhs.Divide(rhs); + return newVec; + } + public bool Equals(Vector3D##StorageType rhs) { + if ((object)rhs == null) + { + return false; + } + return Equal(rhs); + } + %} + %ignore PolyVox::Vector<3,StorageType,OperationType>::operator<; //This is deprecated + #endif + %ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType); + %ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType); + %ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const; + %ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType); + %ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType); + %template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>; %enddef VECTOR3(float,float,float) From 6e93048c9f5321d7f73eedd8e0909ef938cd556d Mon Sep 17 00:00:00 2001 From: Matt Williams Date: Wed, 16 Jan 2013 15:31:52 +0000 Subject: [PATCH 3/6] Add a test for C# This test is not actually run yet but it serves as an example of how to use the C# bindings. --- tests/TestSurfaceExtractor.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/TestSurfaceExtractor.cs diff --git a/tests/TestSurfaceExtractor.cs b/tests/TestSurfaceExtractor.cs new file mode 100644 index 00000000..58e6cc60 --- /dev/null +++ b/tests/TestSurfaceExtractor.cs @@ -0,0 +1,32 @@ +using System.Diagnostics; + +public class test +{ + public static void Main() + { + Region r = new Region(new Vector3Dint32_t(0,0,0), new Vector3Dint32_t(31,31,31)); + SimpleVolumeuint8 vol = new SimpleVolumeuint8(r); + //Set one single voxel to have a reasonably high density + vol.setVoxelAt(new Vector3Dint32_t(5, 5, 5), 200); + SurfaceMeshPositionMaterialNormal mesh = new SurfaceMeshPositionMaterialNormal(); + MarchingCubesSurfaceExtractorSimpleVolumeuint8 extractor = new MarchingCubesSurfaceExtractorSimpleVolumeuint8(vol, r, mesh); + extractor.execute(); + + Debug.Assert(mesh.getNoOfVertices() == 6); + + Vector3Dint32_t v1 = new Vector3Dint32_t(1,2,3); + Vector3Dint32_t v2 = new Vector3Dint32_t(6,8,12); + Vector3Dint32_t v3 = v1 + v2; + + Vector3Dint32_t v11 = new Vector3Dint32_t(1,2,3); + + Debug.Assert(v3.getX() == 7); + Debug.Assert((v3*5).getX() == 35); + Debug.Assert(v1.Equals(v11)); + Debug.Assert(v1 != v11); + Debug.Assert(!v1.Equals(v2)); + Debug.Assert(!v1.Equals(null)); + + System.Console.WriteLine("Success"); + } +} From d50e9dfebc135098d0048585ec29da441b4c59b8 Mon Sep 17 00:00:00 2001 From: Matt Williams Date: Sat, 19 Jan 2013 14:19:26 +0000 Subject: [PATCH 4/6] Start enabling the CubicSurfaceExtractors --- library/bindings/CubicSurfaceExtractor.i | 3 ++- library/bindings/CubicSurfaceExtractorWithNormals.i | 7 +------ library/bindings/PolyVoxCore.i | 3 ++- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/library/bindings/CubicSurfaceExtractor.i b/library/bindings/CubicSurfaceExtractor.i index 8c17997e..11e76cdb 100644 --- a/library/bindings/CubicSurfaceExtractor.i +++ b/library/bindings/CubicSurfaceExtractor.i @@ -5,4 +5,5 @@ %include "CubicSurfaceExtractor.h" -EXTRACTORS(CubicSurfaceExtractor) +%template(CubicSurfaceExtractorSimpleVolumeuint8) PolyVox::CubicSurfaceExtractor, PolyVox::DefaultIsQuadNeeded >; +//EXTRACTORS(CubicSurfaceExtractor) diff --git a/library/bindings/CubicSurfaceExtractorWithNormals.i b/library/bindings/CubicSurfaceExtractorWithNormals.i index 93d778cb..5bd6e0ab 100644 --- a/library/bindings/CubicSurfaceExtractorWithNormals.i +++ b/library/bindings/CubicSurfaceExtractorWithNormals.i @@ -1,13 +1,8 @@ %module CubicSurfaceExtractorWithNormals %{ -#include "SimpleVolume.h" -//#include "CubicSurfaceExtractor.h" #include "CubicSurfaceExtractorWithNormals.h" %} -%include "SimpleVolume.h" -//%include "CubicSurfaceExtractor.h" %include "CubicSurfaceExtractorWithNormals.h" -%template(CubicSurfaceExtractorWithNormalsMaterial8) PolyVox::CubicSurfaceExtractorWithNormals; -%template(CubicSurfaceExtractorWithNormalsDensity8) PolyVox::CubicSurfaceExtractorWithNormals; \ No newline at end of file +%template(CubicSurfaceExtractorWithNormalsSimpleVolumeuint8) PolyVox::CubicSurfaceExtractorWithNormals, PolyVox::DefaultIsQuadNeeded >; diff --git a/library/bindings/PolyVoxCore.i b/library/bindings/PolyVoxCore.i index f32ee0e3..8c0d30c4 100644 --- a/library/bindings/PolyVoxCore.i +++ b/library/bindings/PolyVoxCore.i @@ -84,5 +84,6 @@ EXTRACTOR(shortname, LargeVolume) %include "VertexTypes.i" %include "SurfaceMesh.i" %include "MarchingCubesSurfaceExtractor.i" -//%include "CubicSurfaceExtractor.i" +%include "CubicSurfaceExtractor.i" +%include "CubicSurfaceExtractorWithNormals.i" %include "Raycast.i" From 8ad0cae89a37200b8789c3e7dc393d27e9b89e64 Mon Sep 17 00:00:00 2001 From: Matt Williams Date: Sat, 19 Jan 2013 14:24:10 +0000 Subject: [PATCH 5/6] Add an example which uses the Python bindings This is more or less a copy of the BasicExample but using ever so slightly more modern OpenGL (>=3.0). I've tried to comment this as much as possible. In addition to this simple example I will go on to develop a more complex application as discussed in issue #21 --- CMakeLists.txt | 1 + examples/Python/CMakeLists.txt | 26 ++++ examples/Python/PythonExample.py | 257 +++++++++++++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 examples/Python/CMakeLists.txt create mode 100755 examples/Python/PythonExample.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 8af58ba6..61384b2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ IF(ENABLE_EXAMPLES AND QT_QTOPENGL_FOUND) ADD_SUBDIRECTORY(examples/Paging) ADD_SUBDIRECTORY(examples/OpenGL) ADD_SUBDIRECTORY(examples/SmoothLOD) + ADD_SUBDIRECTORY(examples/Python) SET(BUILD_EXAMPLES ON) ELSE() SET(BUILD_EXAMPLES OFF) diff --git a/examples/Python/CMakeLists.txt b/examples/Python/CMakeLists.txt new file mode 100644 index 00000000..1d101d6e --- /dev/null +++ b/examples/Python/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2010-2013 Matt Williams +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# +# 3. This notice may not be removed or altered from any source +# distribution. + +PROJECT(PythonExample) + +SOURCE_GROUP("Sources" FILES PythonExample.py) + +configure_file(PythonExample.py PythonExample.py COPYONLY) diff --git a/examples/Python/PythonExample.py b/examples/Python/PythonExample.py new file mode 100755 index 00000000..2a688971 --- /dev/null +++ b/examples/Python/PythonExample.py @@ -0,0 +1,257 @@ +#! /usr/bin/env python + +################################################################################ +# Copyright (c) 2013 Matt Williams +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# +# 3. This notice may not be removed or altered from any source +# distribution. +################################################################################ + +import sys +sys.path.append("../../library/bindings/") #This is just to point to the generated bindings + +import PolyVoxCore as pv + +#Create a 64x64x64 volume of integers +r = pv.Region(pv.Vector3Dint32_t(0,0,0), pv.Vector3Dint32_t(63,63,63)) +vol = pv.SimpleVolumeuint8(r) + +#Now fill the volume with our data (a sphere) +v3dVolCenter = pv.Vector3Dint32_t(vol.getWidth() / 2, vol.getHeight() / 2, vol.getDepth() / 2) +sphereRadius = 30 +#This three-level for loop iterates over every voxel in the volume +for z in range(vol.getDepth()): + for y in range(vol.getHeight()): + for x in range(vol.getWidth()): + #Store our current position as a vector... + v3dCurrentPos = pv.Vector3Dint32_t(x,y,z) + #And compute how far the current position is from the center of the volume + fDistToCenter = (v3dCurrentPos - v3dVolCenter).length() + + uVoxelValue = 0 + + #If the current voxel is less than 'radius' units from the center then we make it solid. + if(fDistToCenter <= sphereRadius): + #Our new voxel value + uVoxelValue = 255 + + #Write the voxel value into the volume + vol.setVoxelAt(x, y, z, uVoxelValue); + +#Create a mesh, pass it to the extractor and generate the mesh +mesh = pv.SurfaceMeshPositionMaterialNormal() +extractor = pv.CubicSurfaceExtractorWithNormalsSimpleVolumeuint8(vol, r, mesh) +extractor.execute() + +#That's all of the PolyVox generation done, now to convert the output to something OpenGL can read efficiently + +import numpy as np + +indices = np.array(mesh.getIndices(), dtype='uint32') #Throw in the vertex indices into an array +#The vertices and normals are placed in an interpolated array like [vvvnnn,vvvnnn,vvvnnn] +vertices = np.array([[vertex.getPosition().getX(), vertex.getPosition().getY(), vertex.getPosition().getZ(), + vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ()] + for vertex in mesh.getVertices()], + dtype='f') + +#Now that we have our data, everything else here is just OpenGL + +import OpenGL + +from OpenGL.GL import shaders +from OpenGL.arrays import vbo +from OpenGL.GL import glClear, glEnable, glDepthFunc, GLuint, glEnableVertexAttribArray, glVertexAttribPointer, glDisableVertexAttribArray, \ + glDrawElements, glGetUniformLocation, glUniformMatrix4fv, glDepthMask, glDepthRange, glGetString, glBindAttribLocation, \ + GL_COLOR_BUFFER_BIT, GL_TRIANGLES, GL_DEPTH_TEST, GL_LEQUAL, GL_FLOAT, \ + GL_DEPTH_BUFFER_BIT, GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, GL_STATIC_DRAW, \ + GL_FALSE, GL_TRUE, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_CULL_FACE, \ + GL_VENDOR, GL_RENDERER, GL_VERSION, GL_SHADING_LANGUAGE_VERSION +from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray + +import pygame + +from math import sin, cos, tan, radians + +SCREEN_SIZE = (800, 800) + +def run(): + #Start OpenGL and ask it for an OpenGL context + pygame.init() + clock = pygame.time.Clock() + screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF) + + #The first thing we do is print some OpenGL details and check that we have a good enough version + print "OpenGL Implementation Details:" + if glGetString(GL_VENDOR): + print "\tGL_VENDOR:", glGetString(GL_VENDOR) + if glGetString(GL_RENDERER): + print "\tGL_RENDERER:", glGetString(GL_RENDERER) + if glGetString(GL_VERSION): + print "\tGL_VERSION:", glGetString(GL_VERSION) + if glGetString(GL_SHADING_LANGUAGE_VERSION): + print "\tGL_SHADING_LANGUAGE_VERSION:", glGetString(GL_SHADING_LANGUAGE_VERSION) + + major_version = int(glGetString(GL_VERSION).split()[0].split('.')[0]) + minor_version = int(glGetString(GL_VERSION).split()[0].split('.')[1]) + if major_version < 3 or (major_version < 3 and minor_version < 0): + print "OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).split()[0]) + + #Now onto the OpenGL initialisation + + #Set up depth culling + glEnable(GL_CULL_FACE) + glEnable(GL_DEPTH_TEST) + glDepthMask(GL_TRUE) + glDepthFunc(GL_LEQUAL) + glDepthRange(0.0, 1.0) + + #We create out shaders which do little more than set a flat colour for each face + + VERTEX_SHADER = shaders.compileShader(""" + #version 130 + + in vec4 position; + in vec4 normal; + + uniform mat4 cameraToClipMatrix; + uniform mat4 worldToCameraMatrix; + uniform mat4 modelToWorldMatrix; + + flat out float theColor; + + void main() + { + vec4 temp = modelToWorldMatrix * position; + temp = worldToCameraMatrix * temp; + gl_Position = cameraToClipMatrix * temp; + + theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1); + } + """, GL_VERTEX_SHADER) + + FRAGMENT_SHADER = shaders.compileShader(""" + #version 130 + + flat in float theColor; + + out vec4 outputColor; + void main() + { + outputColor = vec4(1.0, 0.5, theColor, 1.0); + } + """, GL_FRAGMENT_SHADER) + + shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) + + #And then grab our attribute locations from it + glBindAttribLocation(shader, 0, "position") + glBindAttribLocation(shader, 1, "normal") + + #Create the Vertex Array Object to hold our volume mesh + vertexArrayObject = GLuint(0) + glGenVertexArrays(1, vertexArrayObject) + glBindVertexArray(vertexArrayObject) + + #Create the index buffer object + indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER, usage=GL_STATIC_DRAW) + #Create the VBO + vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW) + + #Bind our VBOs and set up our data layout specifications + with indexPositions, vertexPositions: + glEnableVertexAttribArray(0) + glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(0*vertices.dtype.itemsize)) + glEnableVertexAttribArray(1) + glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(3*vertices.dtype.itemsize)) + + glBindVertexArray(0) + glDisableVertexAttribArray(0) + + #Now grab out transformation martix locations + modelToWorldMatrixUnif = glGetUniformLocation(shader, "modelToWorldMatrix") + worldToCameraMatrixUnif = glGetUniformLocation(shader, "worldToCameraMatrix") + cameraToClipMatrixUnif = glGetUniformLocation(shader, "cameraToClipMatrix") + + modelToWorldMatrix = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f') + worldToCameraMatrix = np.array([[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,-50.0],[0.0,0.0,0.0,1.0]], dtype='f') + cameraToClipMatrix = np.array([[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0]], dtype='f') + + #These next few lines just set up our camera frustum + fovDeg = 45.0 + frustumScale = 1.0 / tan(radians(fovDeg) / 2.0) + + zNear = 1.0 + zFar = 1000.0 + + cameraToClipMatrix[0][0] = frustumScale + cameraToClipMatrix[1][1] = frustumScale + cameraToClipMatrix[2][2] = (zFar + zNear) / (zNear - zFar) + cameraToClipMatrix[2][3] = -1.0 + cameraToClipMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar) + + #worldToCameraMatrix and cameraToClipMatrix don't change ever so just set them once here + with shader: + glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_TRUE, cameraToClipMatrix) + glUniformMatrix4fv(worldToCameraMatrixUnif, 1, GL_TRUE, worldToCameraMatrix) + + #These are used to track the rotation of the volume + LastFrameMousePos = (0,0) + CurrentMousePos = (0,0) + xRotation = 0 + yRotation = 0 + + while True: + clock.tick() + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return + if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: + return + if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: + CurrentMousePos = event.pos + LastFrameMousePos = CurrentMousePos + if event.type == pygame.MOUSEMOTION and 1 in event.buttons: + CurrentMousePos = event.pos + diff = (CurrentMousePos[0] - LastFrameMousePos[0], CurrentMousePos[1] - LastFrameMousePos[1]) + xRotation += event.rel[0] + yRotation += event.rel[1] + LastFrameMousePos = CurrentMousePos + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + #Perform the rotation of the mesh + moveToOrigin = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f') + rotateAroundX = np.array([[1.0,0.0,0.0,0.0],[0.0,cos(radians(yRotation)),-sin(radians(yRotation)),0.0],[0.0,sin(radians(yRotation)),cos(radians(yRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f') + rotateAroundY = np.array([[cos(radians(xRotation)),0.0,sin(radians(xRotation)),0.0],[0.0,1.0,0.0,0.0],[-sin(radians(xRotation)),0.0,cos(radians(xRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f') + + modelToWorldMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin)) + + with shader: + glUniformMatrix4fv(modelToWorldMatrixUnif, 1, GL_TRUE, modelToWorldMatrix) + glBindVertexArray(vertexArrayObject) + + glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None) + + glBindVertexArray(0) + + # Show the screen + pygame.display.flip() + +run() From 8d2061bdb5296bb2dd47c096bf0f286d9ceeae95 Mon Sep 17 00:00:00 2001 From: Daviw Williams Date: Mon, 4 Feb 2013 16:38:50 +0100 Subject: [PATCH 6/6] Fixed crash with MaxVerticesPerPosition being set too low. --- .../include/PolyVoxCore/CubicSurfaceExtractor.inl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl index 5cf72fc6..72294e2c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl @@ -26,13 +26,12 @@ namespace PolyVox // We try to avoid duplicate vertices by checking whether a vertex has already been added at a given position. // However, it is possible that vertices have the same position but different materials. In this case, the // vertices are not true duplicates and both must be added to the mesh. As far as I can tell, it is possible to have - // at most six vertices with the same position but different materials. This worst-case scenario happens when we - // have a 2x2x2 group of voxels (all with different materials) and then we delete two voxels from opposing corners. - // The vertex position at the center of this group is then going to be used by six quads all with different materials. - // One futher note - we can actually have eight quads sharing a vertex position (imagine two 1x1x10 rows of voxels - // sharing a common edge) but in this case all eight quads will not have different materials. + // at most eight vertices with the same position but different materials. For example, this worst-case scenario + // happens when we have a 2x2x2 group of voxels, all with different materials and some/all partially transparent. + // The vertex position at the center of this group is then going to be used by all eight voxels all with different + // materials. template - const uint32_t CubicSurfaceExtractor::MaxVerticesPerPosition = 6; + const uint32_t CubicSurfaceExtractor::MaxVerticesPerPosition = 8; template CubicSurfaceExtractor::CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)