Explorar o código

Added some (very) basic sound positioning and attenuation stuff to replace removed OpenAL functionality

Ivan Safrin %!s(int64=9) %!d(string=hai) anos
pai
achega
258a53f92b

+ 22 - 0
bindings/javascript/Polycode/AudioMixer.js

@@ -1,6 +1,8 @@
 function AudioMixer() {
 	Object.defineProperties(this, {
 		'globalVolume': { enumerable: true, configurable: true, get: AudioMixer.prototype.__get_globalVolume, set: AudioMixer.prototype.__set_globalVolume},
+		'listenerPosition': { enumerable: true, configurable: true, get: AudioMixer.prototype.__get_listenerPosition, set: AudioMixer.prototype.__set_listenerPosition},
+		'listenerOrientation': { enumerable: true, configurable: true, get: AudioMixer.prototype.__get_listenerOrientation, set: AudioMixer.prototype.__set_listenerOrientation},
 		'mixerMutex': { enumerable: true, configurable: true, get: AudioMixer.prototype.__get_mixerMutex, set: AudioMixer.prototype.__set_mixerMutex}
 	})
 }
@@ -12,6 +14,26 @@ AudioMixer.prototype.__set_globalVolume = function(val) {
 	Polycode.AudioMixer__set_globalVolume(this.__ptr, val)
 }
 
+AudioMixer.prototype.__get_listenerPosition = function() {
+	var retVal = new Vector3()
+	retVal.__ptr = 	Polycode.AudioMixer__get_listenerPosition(this.__ptr)
+	return retVal
+}
+
+AudioMixer.prototype.__set_listenerPosition = function(val) {
+	Polycode.AudioMixer__set_listenerPosition(this.__ptr, val.__ptr)
+}
+
+AudioMixer.prototype.__get_listenerOrientation = function() {
+	var retVal = new Quaternion()
+	retVal.__ptr = 	Polycode.AudioMixer__get_listenerOrientation(this.__ptr)
+	return retVal
+}
+
+AudioMixer.prototype.__set_listenerOrientation = function(val) {
+	Polycode.AudioMixer__set_listenerOrientation(this.__ptr, val.__ptr)
+}
+
 AudioMixer.prototype.__get_mixerMutex = function() {
 	var retVal = new CoreMutex()
 	retVal.__ptr = 	Polycode.AudioMixer__get_mixerMutex(this.__ptr)

+ 231 - 0
bindings/javascript/Polycode/MeshGeometry.js

@@ -0,0 +1,231 @@
+function MeshGeometry() {
+	Object.defineProperties(this, {
+		'meshType': { enumerable: true, configurable: true, get: MeshGeometry.prototype.__get_meshType, set: MeshGeometry.prototype.__set_meshType},
+		'dataChanged': { enumerable: true, configurable: true, get: MeshGeometry.prototype.__get_dataChanged, set: MeshGeometry.prototype.__set_dataChanged},
+		'indexedMesh': { enumerable: true, configurable: true, get: MeshGeometry.prototype.__get_indexedMesh, set: MeshGeometry.prototype.__set_indexedMesh}
+	})
+}
+MeshGeometry.prototype.__get_meshType = function() {
+	return Polycode.MeshGeometry__get_meshType(this.__ptr)
+}
+
+MeshGeometry.prototype.__set_meshType = function(val) {
+	Polycode.MeshGeometry__set_meshType(this.__ptr, val)
+}
+
+MeshGeometry.prototype.__get_dataChanged = function() {
+	return Polycode.MeshGeometry__get_dataChanged(this.__ptr)
+}
+
+MeshGeometry.prototype.__set_dataChanged = function(val) {
+	Polycode.MeshGeometry__set_dataChanged(this.__ptr, val)
+}
+
+MeshGeometry.prototype.__get_indexedMesh = function() {
+	return Polycode.MeshGeometry__get_indexedMesh(this.__ptr)
+}
+
+MeshGeometry.prototype.__set_indexedMesh = function(val) {
+	Polycode.MeshGeometry__set_indexedMesh(this.__ptr, val)
+}
+
+Duktape.fin(MeshGeometry.prototype, function (x) {
+	if (x === MeshGeometry.prototype) {
+		return;
+	}
+	Polycode.MeshGeometry__delete(x.__ptr)
+})
+
+MeshGeometry.prototype.clearMesh = function() {
+	Polycode.MeshGeometry_clearMesh(this.__ptr)
+}
+
+MeshGeometry.prototype.getVertexCount = function() {
+	return Polycode.MeshGeometry_getVertexCount(this.__ptr)
+}
+
+MeshGeometry.prototype.createPlane = function(w,h,tilingValue) {
+	Polycode.MeshGeometry_createPlane(this.__ptr, w,h,tilingValue)
+}
+
+MeshGeometry.prototype.createVPlane = function(w,h,tilingValue) {
+	Polycode.MeshGeometry_createVPlane(this.__ptr, w,h,tilingValue)
+}
+
+MeshGeometry.prototype.createCircle = function(w,h,numSegments,tilingValue) {
+	Polycode.MeshGeometry_createCircle(this.__ptr, w,h,numSegments,tilingValue)
+}
+
+MeshGeometry.prototype.createLineCircle = function(w,h,numSegments,tilingValue) {
+	Polycode.MeshGeometry_createLineCircle(this.__ptr, w,h,numSegments,tilingValue)
+}
+
+MeshGeometry.prototype.createTorus = function(radius,tubeRadius,segmentsW,segmentsH,tilingValue) {
+	Polycode.MeshGeometry_createTorus(this.__ptr, radius,tubeRadius,segmentsW,segmentsH,tilingValue)
+}
+
+MeshGeometry.prototype.createBox = function(w,d,h,tilingValue) {
+	Polycode.MeshGeometry_createBox(this.__ptr, w,d,h,tilingValue)
+}
+
+MeshGeometry.prototype.createSphere = function(radius,numRings,numSegments,tilingValue) {
+	Polycode.MeshGeometry_createSphere(this.__ptr, radius,numRings,numSegments,tilingValue)
+}
+
+MeshGeometry.prototype.createIcosphere = function(radius,subdivisions) {
+	Polycode.MeshGeometry_createIcosphere(this.__ptr, radius,subdivisions)
+}
+
+MeshGeometry.prototype.createOctosphere = function(radius,subdivisions) {
+	Polycode.MeshGeometry_createOctosphere(this.__ptr, radius,subdivisions)
+}
+
+MeshGeometry.prototype.createCylinder = function(height,radius,numSegments,capped,tilingValue) {
+	Polycode.MeshGeometry_createCylinder(this.__ptr, height,radius,numSegments,capped,tilingValue)
+}
+
+MeshGeometry.prototype.createCone = function(height,radius,numSegments,tilingValue) {
+	Polycode.MeshGeometry_createCone(this.__ptr, height,radius,numSegments,tilingValue)
+}
+
+MeshGeometry.prototype.recenterMesh = function() {
+	var retVal = new Vector3()
+	retVal.__ptr = Polycode.MeshGeometry_recenterMesh(this.__ptr)
+	return retVal
+}
+
+MeshGeometry.prototype.setVertexAtOffset = function(offset,x,y,z) {
+	Polycode.MeshGeometry_setVertexAtOffset(this.__ptr, offset,x,y,z)
+}
+
+MeshGeometry.prototype.addVertexWithUVAndNormal = function(x,y,z,u,v,nx,ny,nz) {
+	Polycode.MeshGeometry_addVertexWithUVAndNormal(this.__ptr, x,y,z,u,v,nx,ny,nz)
+}
+
+MeshGeometry.prototype.addTexCoord = function(u,v) {
+	Polycode.MeshGeometry_addTexCoord(this.__ptr, u,v)
+}
+
+MeshGeometry.prototype.addTexCoord2 = function(u,v) {
+	Polycode.MeshGeometry_addTexCoord2(this.__ptr, u,v)
+}
+
+MeshGeometry.prototype.addTangent = function(x,y,z) {
+	Polycode.MeshGeometry_addTangent(this.__ptr, x,y,z)
+}
+
+MeshGeometry.prototype.addVertexWithUV = function(x,y,z,u,v) {
+	Polycode.MeshGeometry_addVertexWithUV(this.__ptr, x,y,z,u,v)
+}
+
+MeshGeometry.prototype.addVertex = function(x,y,z) {
+	Polycode.MeshGeometry_addVertex(this.__ptr, x,y,z)
+}
+
+MeshGeometry.prototype.addNormal = function(nx,ny,nz) {
+	Polycode.MeshGeometry_addNormal(this.__ptr, nx,ny,nz)
+}
+
+MeshGeometry.prototype.addBoneAssignments = function(b1Weight,b1Index,b2Weight,b2Index,b3Weight,b3Index,b4Weight,b4Index) {
+	Polycode.MeshGeometry_addBoneAssignments(this.__ptr, b1Weight,b1Index,b2Weight,b2Index,b3Weight,b3Index,b4Weight,b4Index)
+}
+
+MeshGeometry.prototype.addColor = function(r,g,b,a) {
+	Polycode.MeshGeometry_addColor(this.__ptr, r,g,b,a)
+}
+
+MeshGeometry.prototype.getVertexPosition = function(vertexOffset) {
+	var retVal = new Vector3()
+	retVal.__ptr = Polycode.MeshGeometry_getVertexPosition(this.__ptr, vertexOffset)
+	return retVal
+}
+
+MeshGeometry.prototype.getVertexPositionAtIndex = function(index) {
+	var retVal = new Vector3()
+	retVal.__ptr = Polycode.MeshGeometry_getVertexPositionAtIndex(this.__ptr, index)
+	return retVal
+}
+
+MeshGeometry.prototype.getVertexTexCoord = function(vertexOffset) {
+	var retVal = new Vector2()
+	retVal.__ptr = Polycode.MeshGeometry_getVertexTexCoord(this.__ptr, vertexOffset)
+	return retVal
+}
+
+MeshGeometry.prototype.getVertexTexCoordAtIndex = function(index) {
+	var retVal = new Vector2()
+	retVal.__ptr = Polycode.MeshGeometry_getVertexTexCoordAtIndex(this.__ptr, index)
+	return retVal
+}
+
+MeshGeometry.prototype.Copy = function() {
+	var retVal = new MeshGeometry()
+	retVal.__ptr = Polycode.MeshGeometry_Copy(this.__ptr)
+	return retVal
+}
+
+MeshGeometry.prototype.getRadius = function() {
+	return Polycode.MeshGeometry_getRadius(this.__ptr)
+}
+
+MeshGeometry.prototype.calculateNormals = function() {
+	Polycode.MeshGeometry_calculateNormals(this.__ptr)
+}
+
+MeshGeometry.prototype.calculateTangents = function() {
+	Polycode.MeshGeometry_calculateTangents(this.__ptr)
+}
+
+MeshGeometry.prototype.getMeshType = function() {
+	return Polycode.MeshGeometry_getMeshType(this.__ptr)
+}
+
+MeshGeometry.prototype.setMeshType = function(newType) {
+	Polycode.MeshGeometry_setMeshType(this.__ptr, newType)
+}
+
+MeshGeometry.prototype.getIndexGroupSize = function() {
+	return Polycode.MeshGeometry_getIndexGroupSize(this.__ptr)
+}
+
+MeshGeometry.prototype.calculateBBox = function() {
+	var retVal = new Vector3()
+	retVal.__ptr = Polycode.MeshGeometry_calculateBBox(this.__ptr)
+	return retVal
+}
+
+MeshGeometry.prototype.addIndexedFace = function(i1,i2) {
+	Polycode.MeshGeometry_addIndexedFace(this.__ptr, i1,i2)
+}
+
+MeshGeometry.prototype.addIndex = function(index) {
+	Polycode.MeshGeometry_addIndex(this.__ptr, index)
+}
+
+MeshGeometry.prototype.removeVertexRange = function(beginRemoveVertex,vertexRemovalCount) {
+	Polycode.MeshGeometry_removeVertexRange(this.__ptr, beginRemoveVertex,vertexRemovalCount)
+}
+
+MeshGeometry.prototype.removeFace = function(faceIndex) {
+	Polycode.MeshGeometry_removeFace(this.__ptr, faceIndex)
+}
+
+MeshGeometry.prototype.removeUnusedVertices = function() {
+	return Polycode.MeshGeometry_removeUnusedVertices(this.__ptr)
+}
+
+MeshGeometry.prototype.getIndexCount = function() {
+	return Polycode.MeshGeometry_getIndexCount(this.__ptr)
+}
+
+MeshGeometry.prototype.subdivideToRadius = function(radius,subdivisions) {
+	Polycode.MeshGeometry_subdivideToRadius(this.__ptr, radius,subdivisions)
+}
+
+MeshGeometry.prototype.saveAsOBJ = function(fileName) {
+	Polycode.MeshGeometry_saveAsOBJ(this.__ptr, fileName)
+}
+
+MeshGeometry.prototype.normalizeBoneWeights = function() {
+	Polycode.MeshGeometry_normalizeBoneWeights(this.__ptr)
+}

+ 2 - 2
bindings/javascript/Polycode/Sound.js

@@ -7,8 +7,8 @@ Duktape.fin(Sound.prototype, function (x) {
 	Polycode.Sound__delete(x.__ptr)
 })
 
-Sound.prototype.getSampleAsNumber = function(offset,channel) {
-	return Polycode.Sound_getSampleAsNumber(this.__ptr, offset,channel)
+Sound.prototype.getSampleAsNumber = function(offset,channel,listener,orientation) {
+	return Polycode.Sound_getSampleAsNumber(this.__ptr, offset,channel,listener,orientation)
 }
 
 Sound.prototype.loadFile = function(fileName) {

+ 2 - 2
bindings/javascript/Polycode/SoundManager.js

@@ -11,8 +11,8 @@ SoundManager.prototype.setListenerPosition = function(position) {
 	Polycode.SoundManager_setListenerPosition(this.__ptr, position)
 }
 
-SoundManager.prototype.setListenerOrientation = function(orientation,upVector) {
-	Polycode.SoundManager_setListenerOrientation(this.__ptr, orientation,upVector)
+SoundManager.prototype.setListenerOrientation = function(orientation) {
+	Polycode.SoundManager_setListenerOrientation(this.__ptr, orientation)
 }
 
 SoundManager.prototype.recordSound = function(rate,sampleSize) {

BIN=BIN
bindings/javascript/js_Polycode.pak


+ 18 - 0
bindings/lua/Polycode/AudioMixer.lua

@@ -4,6 +4,18 @@ class "AudioMixer"
 function AudioMixer:__getvar(name)
 	if name == "globalVolume" then
 		return Polycode.AudioMixer_get_globalVolume(self.__ptr)
+	elseif name == "listenerPosition" then
+		local retVal = Polycode.AudioMixer_get_listenerPosition(self.__ptr)
+		if retVal == nil then return nil end
+		local __c = _G["Vector3"]("__skip_ptr__")
+		__c.__ptr = retVal
+		return __c
+	elseif name == "listenerOrientation" then
+		local retVal = Polycode.AudioMixer_get_listenerOrientation(self.__ptr)
+		if retVal == nil then return nil end
+		local __c = _G["Quaternion"]("__skip_ptr__")
+		__c.__ptr = retVal
+		return __c
 	elseif name == "mixerMutex" then
 		local retVal = Polycode.AudioMixer_get_mixerMutex(self.__ptr)
 		if retVal == nil then return nil end
@@ -17,6 +29,12 @@ function AudioMixer:__setvar(name,value)
 	if name == "globalVolume" then
 		Polycode.AudioMixer_set_globalVolume(self.__ptr, value)
 		return true
+	elseif name == "listenerPosition" then
+		Polycode.AudioMixer_set_listenerPosition(self.__ptr, value.__ptr)
+		return true
+	elseif name == "listenerOrientation" then
+		Polycode.AudioMixer_set_listenerOrientation(self.__ptr, value.__ptr)
+		return true
 	elseif name == "mixerMutex" then
 		Polycode.AudioMixer_set_mixerMutex(self.__ptr, value.__ptr)
 		return true

+ 272 - 0
bindings/lua/Polycode/MeshGeometry.lua

@@ -0,0 +1,272 @@
+class "MeshGeometry"
+
+MeshGeometry.TRISTRIP_MESH = 0
+MeshGeometry.TRI_MESH = 1
+MeshGeometry.TRIFAN_MESH = 2
+MeshGeometry.LINE_MESH = 4
+MeshGeometry.POINT_MESH = 5
+MeshGeometry.LINE_STRIP_MESH = 6
+MeshGeometry.LINE_LOOP_MESH = 7
+
+function MeshGeometry:__getvar(name)
+	if name == "meshType" then
+		return Polycode.MeshGeometry_get_meshType(self.__ptr)
+	elseif name == "dataChanged" then
+		return Polycode.MeshGeometry_get_dataChanged(self.__ptr)
+	elseif name == "indexedMesh" then
+		return Polycode.MeshGeometry_get_indexedMesh(self.__ptr)
+	end
+end
+
+function MeshGeometry:__setvar(name,value)
+	if name == "meshType" then
+		Polycode.MeshGeometry_set_meshType(self.__ptr, value)
+		return true
+	elseif name == "dataChanged" then
+		Polycode.MeshGeometry_set_dataChanged(self.__ptr, value)
+		return true
+	elseif name == "indexedMesh" then
+		Polycode.MeshGeometry_set_indexedMesh(self.__ptr, value)
+		return true
+	end
+	return false
+end
+function MeshGeometry:MeshGeometry(...)
+	local arg = {...}
+	for k,v in pairs(arg) do
+		if type(v) == "table" then
+			if v.__ptr ~= nil then
+				arg[k] = v.__ptr
+			end
+		end
+	end
+	if self.__ptr == nil and arg[1] ~= "__skip_ptr__" then
+		self.__ptr = Polycode.MeshGeometry(unpack(arg))
+	end
+end
+
+function MeshGeometry:clearMesh()
+	local retVal =  Polycode.MeshGeometry_clearMesh(self.__ptr)
+end
+
+function MeshGeometry:getVertexCount()
+	local retVal =  Polycode.MeshGeometry_getVertexCount(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:createPlane(w, h, tilingValue)
+	local retVal = Polycode.MeshGeometry_createPlane(self.__ptr, w, h, tilingValue)
+end
+
+function MeshGeometry:createVPlane(w, h, tilingValue)
+	local retVal = Polycode.MeshGeometry_createVPlane(self.__ptr, w, h, tilingValue)
+end
+
+function MeshGeometry:createCircle(w, h, numSegments, tilingValue)
+	local retVal = Polycode.MeshGeometry_createCircle(self.__ptr, w, h, numSegments, tilingValue)
+end
+
+function MeshGeometry:createLineCircle(w, h, numSegments, tilingValue)
+	local retVal = Polycode.MeshGeometry_createLineCircle(self.__ptr, w, h, numSegments, tilingValue)
+end
+
+function MeshGeometry:createTorus(radius, tubeRadius, segmentsW, segmentsH, tilingValue)
+	local retVal = Polycode.MeshGeometry_createTorus(self.__ptr, radius, tubeRadius, segmentsW, segmentsH, tilingValue)
+end
+
+function MeshGeometry:createBox(w, d, h, tilingValue)
+	local retVal = Polycode.MeshGeometry_createBox(self.__ptr, w, d, h, tilingValue)
+end
+
+function MeshGeometry:createSphere(radius, numRings, numSegments, tilingValue)
+	local retVal = Polycode.MeshGeometry_createSphere(self.__ptr, radius, numRings, numSegments, tilingValue)
+end
+
+function MeshGeometry:createIcosphere(radius, subdivisions)
+	local retVal = Polycode.MeshGeometry_createIcosphere(self.__ptr, radius, subdivisions)
+end
+
+function MeshGeometry:createOctosphere(radius, subdivisions)
+	local retVal = Polycode.MeshGeometry_createOctosphere(self.__ptr, radius, subdivisions)
+end
+
+function MeshGeometry:createCylinder(height, radius, numSegments, capped, tilingValue)
+	local retVal = Polycode.MeshGeometry_createCylinder(self.__ptr, height, radius, numSegments, capped, tilingValue)
+end
+
+function MeshGeometry:createCone(height, radius, numSegments, tilingValue)
+	local retVal = Polycode.MeshGeometry_createCone(self.__ptr, height, radius, numSegments, tilingValue)
+end
+
+function MeshGeometry:recenterMesh()
+	local retVal =  Polycode.MeshGeometry_recenterMesh(self.__ptr)
+	if retVal == nil then return nil end
+	local __c = _G["Vector3"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:setVertexAtOffset(offset, x, y, z)
+	local retVal = Polycode.MeshGeometry_setVertexAtOffset(self.__ptr, offset, x, y, z)
+end
+
+function MeshGeometry:addVertexWithUVAndNormal(x, y, z, u, v, nx, ny, nz)
+	local retVal = Polycode.MeshGeometry_addVertexWithUVAndNormal(self.__ptr, x, y, z, u, v, nx, ny, nz)
+end
+
+function MeshGeometry:addTexCoord(u, v)
+	local retVal = Polycode.MeshGeometry_addTexCoord(self.__ptr, u, v)
+end
+
+function MeshGeometry:addTexCoord2(u, v)
+	local retVal = Polycode.MeshGeometry_addTexCoord2(self.__ptr, u, v)
+end
+
+function MeshGeometry:addTangent(x, y, z)
+	local retVal = Polycode.MeshGeometry_addTangent(self.__ptr, x, y, z)
+end
+
+function MeshGeometry:addVertexWithUV(x, y, z, u, v)
+	local retVal = Polycode.MeshGeometry_addVertexWithUV(self.__ptr, x, y, z, u, v)
+end
+
+function MeshGeometry:addVertex(x, y, z)
+	local retVal = Polycode.MeshGeometry_addVertex(self.__ptr, x, y, z)
+end
+
+function MeshGeometry:addNormal(nx, ny, nz)
+	local retVal = Polycode.MeshGeometry_addNormal(self.__ptr, nx, ny, nz)
+end
+
+function MeshGeometry:addBoneAssignments(b1Weight, b1Index, b2Weight, b2Index, b3Weight, b3Index, b4Weight, b4Index)
+	local retVal = Polycode.MeshGeometry_addBoneAssignments(self.__ptr, b1Weight, b1Index, b2Weight, b2Index, b3Weight, b3Index, b4Weight, b4Index)
+end
+
+function MeshGeometry:addColor(r, g, b, a)
+	local retVal = Polycode.MeshGeometry_addColor(self.__ptr, r, g, b, a)
+end
+
+function MeshGeometry:getVertexPosition(vertexOffset)
+	local retVal = Polycode.MeshGeometry_getVertexPosition(self.__ptr, vertexOffset)
+	if retVal == nil then return nil end
+	local __c = _G["Vector3"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:getVertexPositionAtIndex(index)
+	local retVal = Polycode.MeshGeometry_getVertexPositionAtIndex(self.__ptr, index)
+	if retVal == nil then return nil end
+	local __c = _G["Vector3"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:getVertexTexCoord(vertexOffset)
+	local retVal = Polycode.MeshGeometry_getVertexTexCoord(self.__ptr, vertexOffset)
+	if retVal == nil then return nil end
+	local __c = _G["Vector2"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:getVertexTexCoordAtIndex(index)
+	local retVal = Polycode.MeshGeometry_getVertexTexCoordAtIndex(self.__ptr, index)
+	if retVal == nil then return nil end
+	local __c = _G["Vector2"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:Copy()
+	local retVal =  Polycode.MeshGeometry_Copy(self.__ptr)
+	if retVal == nil then return nil end
+	local __c = _G["MeshGeometry"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:getRadius()
+	local retVal =  Polycode.MeshGeometry_getRadius(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:calculateNormals()
+	local retVal =  Polycode.MeshGeometry_calculateNormals(self.__ptr)
+end
+
+function MeshGeometry:calculateTangents()
+	local retVal =  Polycode.MeshGeometry_calculateTangents(self.__ptr)
+end
+
+function MeshGeometry:getMeshType()
+	local retVal =  Polycode.MeshGeometry_getMeshType(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:setMeshType(newType)
+	local retVal = Polycode.MeshGeometry_setMeshType(self.__ptr, newType)
+end
+
+function MeshGeometry:getIndexGroupSize()
+	local retVal =  Polycode.MeshGeometry_getIndexGroupSize(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:calculateBBox()
+	local retVal =  Polycode.MeshGeometry_calculateBBox(self.__ptr)
+	if retVal == nil then return nil end
+	local __c = _G["Vector3"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:addIndexedFace(i1, i2)
+	local retVal = Polycode.MeshGeometry_addIndexedFace(self.__ptr, i1, i2)
+end
+
+function MeshGeometry:addIndex(index)
+	local retVal = Polycode.MeshGeometry_addIndex(self.__ptr, index)
+end
+
+function MeshGeometry:removeVertexRange(beginRemoveVertex, vertexRemovalCount)
+	local retVal = Polycode.MeshGeometry_removeVertexRange(self.__ptr, beginRemoveVertex, vertexRemovalCount)
+end
+
+function MeshGeometry:removeFace(faceIndex)
+	local retVal = Polycode.MeshGeometry_removeFace(self.__ptr, faceIndex)
+end
+
+function MeshGeometry:removeUnusedVertices()
+	local retVal =  Polycode.MeshGeometry_removeUnusedVertices(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:getIndexCount()
+	local retVal =  Polycode.MeshGeometry_getIndexCount(self.__ptr)
+	return retVal
+end
+
+function MeshGeometry:subdivideToRadius(radius, subdivisions)
+	local retVal = Polycode.MeshGeometry_subdivideToRadius(self.__ptr, radius, subdivisions)
+end
+
+function MeshGeometry:calculateFaceTangent(v1, v2, v3, texCoord1, texCoord2, texCoord3)
+	local retVal = Polycode.MeshGeometry_calculateFaceTangent(self.__ptr, v1.__ptr, v2.__ptr, v3.__ptr, texCoord1.__ptr, texCoord2.__ptr, texCoord3.__ptr)
+	if retVal == nil then return nil end
+	local __c = _G["Vector3"]("__skip_ptr__")
+	__c.__ptr = retVal
+	return __c
+end
+
+function MeshGeometry:saveAsOBJ(fileName)
+	local retVal = Polycode.MeshGeometry_saveAsOBJ(self.__ptr, fileName)
+end
+
+function MeshGeometry:normalizeBoneWeights()
+	local retVal =  Polycode.MeshGeometry_normalizeBoneWeights(self.__ptr)
+end
+
+function MeshGeometry:__delete()
+	if self then Polycode.delete_MeshGeometry(self.__ptr) end
+end

+ 2 - 2
bindings/lua/Polycode/Sound.lua

@@ -15,8 +15,8 @@ function Sound:Sound(...)
 	end
 end
 
-function Sound:getSampleAsNumber(offset, channel)
-	local retVal = Polycode.Sound_getSampleAsNumber(self.__ptr, offset, channel)
+function Sound:getSampleAsNumber(offset, channel, listener, orientation)
+	local retVal = Polycode.Sound_getSampleAsNumber(self.__ptr, offset, channel, listener.__ptr, orientation.__ptr)
 	return retVal
 end
 

+ 2 - 2
bindings/lua/Polycode/SoundManager.lua

@@ -19,8 +19,8 @@ function SoundManager:setListenerPosition(position)
 	local retVal = Polycode.SoundManager_setListenerPosition(self.__ptr, position.__ptr)
 end
 
-function SoundManager:setListenerOrientation(orientation, upVector)
-	local retVal = Polycode.SoundManager_setListenerOrientation(self.__ptr, orientation.__ptr, upVector.__ptr)
+function SoundManager:setListenerOrientation(orientation)
+	local retVal = Polycode.SoundManager_setListenerOrientation(self.__ptr, orientation.__ptr)
 end
 
 function SoundManager:recordSound(rate, sampleSize)

BIN=BIN
bindings/lua/lua_Polycode.pak


+ 4 - 0
build/osx/TemplateApp/TemplateApp.xcodeproj/project.pbxproj

@@ -10,6 +10,7 @@
 		6D6FD3E11BF122A2005AA8E9 /* PolycodeView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */; };
 		6D904FD31CC2AEB400D0E80A /* rotate.lua in Resources */ = {isa = PBXBuildFile; fileRef = 6D904FD21CC2AEB400D0E80A /* rotate.lua */; };
 		6D90506B1CCC057C00D0E80A /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D90506A1CCC057C00D0E80A /* liblua.a */; };
+		6DB4EE6D1CFB4F3B00D39AA7 /* test.wav in Resources */ = {isa = PBXBuildFile; fileRef = 6DB4EE6C1CFB4F3B00D39AA7 /* test.wav */; };
 		6DCDD7251C724726007E90E1 /* main_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DCDD7241C724726007E90E1 /* main_icon.png */; };
 		6DD2D0B61BEEDC150026D85C /* libportaudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DD2D0B51BEEDC150026D85C /* libportaudio.a */; };
 		8A4ABF0A1CDBC69E007433DE /* lua_Polycode.pak in Resources */ = {isa = PBXBuildFile; fileRef = 8A4ABF091CDBC69E007433DE /* lua_Polycode.pak */; };
@@ -41,6 +42,7 @@
 		6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PolycodeView.mm; path = ../../../../src/view/osx/PolycodeView.mm; sourceTree = "<group>"; };
 		6D904FD21CC2AEB400D0E80A /* rotate.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rotate.lua; sourceTree = "<group>"; };
 		6D90506A1CCC057C00D0E80A /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = ../../../../lib/osx/liblua.a; sourceTree = "<group>"; };
+		6DB4EE6C1CFB4F3B00D39AA7 /* test.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = test.wav; path = ../../../../assets/examples/test.wav; sourceTree = "<group>"; };
 		6DCDD7241C724726007E90E1 /* main_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = main_icon.png; path = ../../../../assets/icons/main_icon.png; sourceTree = "<group>"; };
 		6DD2D0B51BEEDC150026D85C /* libportaudio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libportaudio.a; path = ../../../../lib/osx/libportaudio.a; sourceTree = "<group>"; };
 		8A4ABF091CDBC69E007433DE /* lua_Polycode.pak */ = {isa = PBXFileReference; lastKnownFileType = file; name = lua_Polycode.pak; path = ../../../../bindings/lua/lua_Polycode.pak; sourceTree = "<group>"; };
@@ -127,6 +129,7 @@
 				8A9D122B1CDD29EB00ACD484 /* js_Polycode.pak */,
 				6DCDD7241C724726007E90E1 /* main_icon.png */,
 				8A8653351B72931C009F94DD /* AppDelegate.h */,
+				6DB4EE6C1CFB4F3B00D39AA7 /* test.wav */,
 				8A8653361B72931C009F94DD /* AppDelegate.m */,
 				6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */,
 				8A7E202E1CD7D11A00EFC3CB /* rotate.js */,
@@ -220,6 +223,7 @@
 			files = (
 				8A86533B1B72931C009F94DD /* Images.xcassets in Resources */,
 				8A4ABF0A1CDBC69E007433DE /* lua_Polycode.pak in Resources */,
+				6DB4EE6D1CFB4F3B00D39AA7 /* test.wav in Resources */,
 				8A8653961B752DBE009F94DD /* main_icon.png in Resources */,
 				8ADFECFA1C8E0852007B57A2 /* default.pak in Resources */,
 				8A9D122C1CDD29EB00ACD484 /* js_Polycode.pak in Resources */,

+ 2 - 0
build/osx/TemplateApp/TemplateApp/PolycodeTemplateApp.h

@@ -22,5 +22,7 @@ private:
     std::vector<ScenePrimitive*> tests;
     SceneLabel *fpsLabel;
     Number counter;
+    Entity *sourceEntity;
+    Number positionValue;
     int numFrames;
 };

+ 17 - 34
build/osx/TemplateApp/TemplateApp/PolycodeTemplateApp.mm

@@ -18,36 +18,23 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     core->addFileSource("archive", "hdr.pak");
     globalPool->loadResourcesFromFolder("hdr", true);
     
-    Polycode:Script *rotateScript = (Script*) globalPool->loadResource("rotate.js");
     
-	// Write your code here!
-    
-    Scene *scene = new Scene(Scene::SCENE_2D);
+    Scene *scene = new Scene(Scene::SCENE_3D);
     scene->useClearColor = true;
-    scene->clearColor.setColor(0.2, 0.2, 0.2, 1.0);
+    sourceEntity = new Entity();
     
-   // scene->setOverrideMaterial((Material*)globalPool->getResource(Resource::RESOURCE_MATERIAL, "Unlit"));
+    SceneSound *testSound = new SceneSound("test.wav", 20, 50);
+    testSound->getSound()->Play(true);
+    sourceEntity->addChild(testSound);
     
-    for(int i=0; i  < 10; i++) {
-        test = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 0.5, 0.5);
-        test->setMaterialByName("Unlit");
-        test->attachScript(rotateScript);
-        /*
-         ScriptInstance *scriptInstance = test->attachScript(rotateScript);
-         scriptInstance->setPropNumber("speed", 1.0);
-         */
-        test->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "main_icon.png");
-        test->setPosition(RANDOM_NUMBER * 0.5, RANDOM_NUMBER * 0.4);
-        test->setBlendingMode(Renderer::BLEND_MODE_NONE);
-        test->setScale(0.3, 0.3);
-        scene->addChild(test);
-        tests.push_back(test);
-    }
-    Camera *camera = scene->getDefaultCamera();
-
-    fpsLabel = new SceneLabel("FPS:", 32, "mono", Label::ANTIALIAS_FULL, 0.1);
-    scene->addChild(fpsLabel);
-    fpsLabel->setPositionY(-0.4);
+    ScenePrimitive *soundShape = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 1,1,1);
+    sourceEntity->addChild(soundShape);
+    scene->addEntity(sourceEntity);
+    
+    SceneSoundListener *soundListener = new SceneSoundListener();
+    scene->addEntity(soundListener);
+    
+    positionValue = 0;
     
     Services()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
 }
@@ -63,14 +50,10 @@ PolycodeTemplateApp::~PolycodeTemplateApp() {
 bool PolycodeTemplateApp::Update() {
     Number elapsed = core->getElapsed();
     
-    
-    ++numFrames;
-    counter += elapsed;
-    if(counter >= 1.0) {
-        counter = 0.0;
-        fpsLabel->setText("FPS:"+String::IntToString(numFrames)+" FRAME MS:"+String::IntToString(Services()->getRenderer()->getRenderThread()->getFrameInfo().timeTaken));
-        numFrames = 0;
-    }
+    positionValue += elapsed;
+    sourceEntity->setPosition((sin(positionValue) * 20), 0, cos(positionValue) * 50);
+    sourceEntity->Roll(core->getElapsed() * 120);
+    sourceEntity->Pitch(core->getElapsed()* 120);
     
     return core->updateAndRender();
 }

+ 42 - 13
include/polycode/bindings/javascript/PolycodeJSWrappers.h

@@ -813,7 +813,7 @@ namespace Polycode {
 
 	duk_ret_t Polycode_Camera_setViewport(duk_context *context) {
 		Camera *inst = (Camera*)duk_to_pointer(context, 0);
-		Polycode::Rectangle viewport = *(Polycode::Rectangle*)duk_to_pointer(context, 1);
+		Rectangle viewport = *(Rectangle*)duk_to_pointer(context, 1);
 		inst->setViewport(viewport);
 		return 0;
 	}
@@ -847,7 +847,7 @@ namespace Polycode {
 	duk_ret_t Polycode_Camera_projectRayFrom2DCoordinate(duk_context *context) {
 		Camera *inst = (Camera*)duk_to_pointer(context, 0);
 		Vector2 coordinate = *(Vector2*)duk_to_pointer(context, 1);
-		Polycode::Rectangle viewport = *(Polycode::Rectangle*)duk_to_pointer(context, 2);
+		Rectangle viewport = *(Rectangle*)duk_to_pointer(context, 2);
 		Vector3 *retInst = new Vector3();
 		*retInst = inst->projectRayFrom2DCoordinate(coordinate,viewport);
 		duk_push_pointer(context, (void*)retInst);
@@ -2576,7 +2576,7 @@ namespace Polycode {
 
 	duk_ret_t Polycode_CoreServices_Render(duk_context *context) {
 		CoreServices *inst = (CoreServices*)duk_to_pointer(context, 0);
-		Polycode::Rectangle viewport = *(Polycode::Rectangle*)duk_to_pointer(context, 1);
+		Rectangle viewport = *(Rectangle*)duk_to_pointer(context, 1);
 		inst->Render(viewport);
 		return 0;
 	}
@@ -3130,7 +3130,7 @@ namespace Polycode {
 	duk_ret_t Polycode_Entity_transformAndRender(duk_context *context) {
 		Entity *inst = (Entity*)duk_to_pointer(context, 0);
 		GPUDrawBuffer* drawBuffer = (GPUDrawBuffer*)duk_to_pointer(context, 1);
-		Polycode::Rectangle* parentScissorBox = (Polycode::Rectangle*)duk_to_pointer(context, 2);
+		Rectangle* parentScissorBox = (Rectangle*)duk_to_pointer(context, 2);
 		inst->transformAndRender(drawBuffer,parentScissorBox);
 		return 0;
 	}
@@ -3138,7 +3138,7 @@ namespace Polycode {
 	duk_ret_t Polycode_Entity_renderChildren(duk_context *context) {
 		Entity *inst = (Entity*)duk_to_pointer(context, 0);
 		GPUDrawBuffer* buffer = (GPUDrawBuffer*)duk_to_pointer(context, 1);
-		Polycode::Rectangle* parentScissorBox = (Polycode::Rectangle*)duk_to_pointer(context, 2);
+		Rectangle* parentScissorBox = (Rectangle*)duk_to_pointer(context, 2);
 		inst->renderChildren(buffer,parentScissorBox);
 		return 0;
 	}
@@ -3876,7 +3876,7 @@ namespace Polycode {
 		Entity *inst = (Entity*)duk_to_pointer(context, 0);
 		Matrix4 projectionMatrix = *(Matrix4*)duk_to_pointer(context, 1);
 		Matrix4 cameraMatrix = *(Matrix4*)duk_to_pointer(context, 2);
-		Polycode::Rectangle viewport = *(Polycode::Rectangle*)duk_to_pointer(context, 3);
+		Rectangle viewport = *(Rectangle*)duk_to_pointer(context, 3);
 		Vector2 *retInst = new Vector2();
 		*retInst = inst->getScreenPosition(projectionMatrix,cameraMatrix,viewport);
 		duk_push_pointer(context, (void*)retInst);
@@ -4888,7 +4888,7 @@ namespace Polycode {
 
 	duk_ret_t Polycode_Image_getImagePart(duk_context *context) {
 		Image *inst = (Image*)duk_to_pointer(context, 0);
-		Polycode::Rectangle subRect = *(Polycode::Rectangle*)duk_to_pointer(context, 1);
+		Rectangle subRect = *(Rectangle*)duk_to_pointer(context, 1);
 		PolyBase *ptrRetVal = (PolyBase*)inst->getImagePart(subRect);
 		duk_push_pointer(context, (void*)ptrRetVal);
 		return 1;
@@ -7847,7 +7847,7 @@ namespace Polycode {
 
 	duk_ret_t Polycode_Rectangle_Clipped(duk_context *context) {
 		Rectangle *inst = (Rectangle*)duk_to_pointer(context, 0);
-		Polycode::Rectangle rect = *(Polycode::Rectangle*)duk_to_pointer(context, 1);
+		Rectangle rect = *(Rectangle*)duk_to_pointer(context, 1);
 		Polycode::Rectangle *retInst = new Polycode::Rectangle();
 		*retInst = inst->Clipped(rect);
 		duk_push_pointer(context, (void*)retInst);
@@ -9993,7 +9993,7 @@ namespace Polycode {
 
 	duk_ret_t Polycode_SceneManager_Render(duk_context *context) {
 		SceneManager *inst = (SceneManager*)duk_to_pointer(context, 0);
-		Polycode::Rectangle viewport = *(Polycode::Rectangle*)duk_to_pointer(context, 1);
+		Rectangle viewport = *(Rectangle*)duk_to_pointer(context, 1);
 		inst->Render(viewport);
 		return 0;
 	}
@@ -12447,7 +12447,9 @@ namespace Polycode {
 		Sound *inst = (Sound*)duk_to_pointer(context, 0);
 		int offset = duk_to_int(context, 1);
 		int channel = duk_to_int(context, 2);
-		duk_push_number(context, inst->getSampleAsNumber(offset,channel));
+		Vector3 listener = *(Vector3*)duk_to_pointer(context, 3);
+		Quaternion orientation = *(Quaternion*)duk_to_pointer(context, 4);
+		duk_push_number(context, inst->getSampleAsNumber(offset,channel,listener,orientation));
 		return 1;
 	}
 
@@ -12692,6 +12694,34 @@ namespace Polycode {
 		return 0;
 	}
 
+	duk_ret_t Polycode_AudioMixer__get_listenerPosition(duk_context *context) {
+		AudioMixer *inst = (AudioMixer*)duk_to_pointer(context, 0);
+		Vector3 *retInst = new Vector3();
+		*retInst = inst->listenerPosition;
+		duk_push_pointer(context, (void*)retInst);
+		return 1;
+	}
+
+	duk_ret_t Polycode_AudioMixer__set_listenerPosition(duk_context *context) {
+		AudioMixer *inst = (AudioMixer*)duk_to_pointer(context, 0);
+		inst->listenerPosition = *(Vector3*)duk_to_pointer(context, 1);
+		return 0;
+	}
+
+	duk_ret_t Polycode_AudioMixer__get_listenerOrientation(duk_context *context) {
+		AudioMixer *inst = (AudioMixer*)duk_to_pointer(context, 0);
+		Quaternion *retInst = new Quaternion();
+		*retInst = inst->listenerOrientation;
+		duk_push_pointer(context, (void*)retInst);
+		return 1;
+	}
+
+	duk_ret_t Polycode_AudioMixer__set_listenerOrientation(duk_context *context) {
+		AudioMixer *inst = (AudioMixer*)duk_to_pointer(context, 0);
+		inst->listenerOrientation = *(Quaternion*)duk_to_pointer(context, 1);
+		return 0;
+	}
+
 	duk_ret_t Polycode_AudioMixer__get_mixerMutex(duk_context *context) {
 		AudioMixer *inst = (AudioMixer*)duk_to_pointer(context, 0);
 		PolyBase *ptrRetVal = (PolyBase*)inst->mixerMutex;
@@ -12734,9 +12764,8 @@ namespace Polycode {
 
 	duk_ret_t Polycode_SoundManager_setListenerOrientation(duk_context *context) {
 		SoundManager *inst = (SoundManager*)duk_to_pointer(context, 0);
-		Vector3 orientation = *(Vector3*)duk_to_pointer(context, 1);
-		Vector3 upVector = *(Vector3*)duk_to_pointer(context, 2);
-		inst->setListenerOrientation(orientation,upVector);
+		Quaternion orientation = *(Quaternion*)duk_to_pointer(context, 1);
+		inst->setListenerOrientation(orientation);
 		return 0;
 	}
 

+ 41 - 5
include/polycode/bindings/lua/PolycodeLuaWrappers.h

@@ -17618,7 +17618,11 @@ static int Polycode_BoneTrack_set_weight(lua_State *L) {
 		int offset = lua_tointeger(L, 2);
 		luaL_checktype(L, 3, LUA_TNUMBER);
 		int channel = lua_tointeger(L, 3);
-		lua_pushnumber(L, inst->getSampleAsNumber(offset, channel));
+		luaL_checktype(L, 4, LUA_TUSERDATA);
+		Vector3 listener = *(Vector3*) *((PolyBase**)lua_touserdata(L, 4));
+		luaL_checktype(L, 5, LUA_TUSERDATA);
+		Quaternion orientation = *(Quaternion*) *((PolyBase**)lua_touserdata(L, 5));
+		lua_pushnumber(L, inst->getSampleAsNumber(offset, channel, listener, orientation));
 		return 1;
 	}
 	static int Polycode_Sound_loadFile(lua_State *L) {
@@ -17912,6 +17916,22 @@ static int Polycode_AudioMixer_get_globalVolume(lua_State *L) {
 	return 1;
 }
 
+static int Polycode_AudioMixer_get_listenerPosition(lua_State *L) {
+	luaL_checktype(L, 1, LUA_TUSERDATA);
+	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
+	PolyBase **userdataPtr = (PolyBase**)lua_newuserdata(L, sizeof(PolyBase*));
+	*userdataPtr = (PolyBase*)&inst->listenerPosition;
+	return 1;
+}
+
+static int Polycode_AudioMixer_get_listenerOrientation(lua_State *L) {
+	luaL_checktype(L, 1, LUA_TUSERDATA);
+	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
+	PolyBase **userdataPtr = (PolyBase**)lua_newuserdata(L, sizeof(PolyBase*));
+	*userdataPtr = (PolyBase*)&inst->listenerOrientation;
+	return 1;
+}
+
 static int Polycode_AudioMixer_get_mixerMutex(lua_State *L) {
 	luaL_checktype(L, 1, LUA_TUSERDATA);
 	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
@@ -17932,6 +17952,24 @@ static int Polycode_AudioMixer_set_globalVolume(lua_State *L) {
 	return 0;
 }
 
+static int Polycode_AudioMixer_set_listenerPosition(lua_State *L) {
+	luaL_checktype(L, 1, LUA_TUSERDATA);
+	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
+	luaL_checktype(L, 2, LUA_TUSERDATA);
+	Vector3 *argInst = (Vector3*) *((PolyBase**)lua_touserdata(L, 2));
+	inst->listenerPosition = *argInst;
+	return 0;
+}
+
+static int Polycode_AudioMixer_set_listenerOrientation(lua_State *L) {
+	luaL_checktype(L, 1, LUA_TUSERDATA);
+	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
+	luaL_checktype(L, 2, LUA_TUSERDATA);
+	Quaternion *argInst = (Quaternion*) *((PolyBase**)lua_touserdata(L, 2));
+	inst->listenerOrientation = *argInst;
+	return 0;
+}
+
 static int Polycode_AudioMixer_set_mixerMutex(lua_State *L) {
 	luaL_checktype(L, 1, LUA_TUSERDATA);
 	AudioMixer *inst = (AudioMixer*) *((PolyBase**)lua_touserdata(L, 1));
@@ -17987,10 +18025,8 @@ static int Polycode_AudioMixer_set_mixerMutex(lua_State *L) {
 		luaL_checktype(L, 1, LUA_TUSERDATA);
 		SoundManager *inst = (SoundManager*) *((PolyBase**)lua_touserdata(L, 1));
 		luaL_checktype(L, 2, LUA_TUSERDATA);
-		Vector3 orientation = *(Vector3*) *((PolyBase**)lua_touserdata(L, 2));
-		luaL_checktype(L, 3, LUA_TUSERDATA);
-		Vector3 upVector = *(Vector3*) *((PolyBase**)lua_touserdata(L, 3));
-		inst->setListenerOrientation(orientation, upVector);
+		Quaternion orientation = *(Quaternion*) *((PolyBase**)lua_touserdata(L, 2));
+		inst->setListenerOrientation(orientation);
 		return 0;
 	}
 	static int Polycode_SoundManager_recordSound(lua_State *L) {

+ 13 - 5
include/polycode/core/PolySound.h

@@ -34,6 +34,8 @@ namespace Polycode {
     enum SoundFormat {SoundFormatUnsupported, SoundFormat8, SoundFormat16, SoundFormat32};
     
 	class String;
+    class Vector3;
+    class Quaternion;
     
     class  AudioStreamingSource {
         public:
@@ -64,7 +66,7 @@ namespace Polycode {
 		Sound(int size, const char *data, int channels, unsigned int freq, SoundFormat format);
         Sound(AudioStreamingSource *streamingSource);
         
-        Number getSampleAsNumber(unsigned int offset, unsigned int channel);
+        Number getSampleAsNumber(unsigned int offset, unsigned int channel, const Vector3 &position, const Quaternion &orientation);
         
 		virtual ~Sound();
 		
@@ -107,9 +109,9 @@ namespace Polycode {
         
 		void setIsPositional(bool isPositional);
 		
-		void setSoundPosition(Vector3 position);
-		void setSoundVelocity(Vector3 velocity);
-		void setSoundDirection(Vector3 direction);
+		void setSoundPosition(const Vector3 &position);
+		void setSoundVelocity(const Vector3 &velocity);
+		void setSoundDirection(const Vector3 &direction);
 		
 		/**
 		* Sets the current sample offset of this sound.
@@ -158,7 +160,13 @@ namespace Polycode {
         void updateStream(unsigned int streamCount);
 
 	protected:
-	
+        
+        Number modulateSampleForListener(Number sample, unsigned int channel, const Vector3 &position, const Quaternion &orientation);
+        
+        Vector3 position;
+        Vector3 velocity;
+        Vector3 direction;
+        
 		Number referenceDistance;
 		Number maxDistance;
         

+ 5 - 3
include/polycode/core/PolySoundManager.h

@@ -23,6 +23,7 @@
 #pragma once
 #include "polycode/core/PolyGlobals.h"
 #include "polycode/core/PolyVector3.h"
+#include "polycode/core/PolyQuaternion.h"
 #include "polycode/core/PolySound.h"
 
 #define POLY_FRAMES_PER_BUFFER 2048
@@ -42,7 +43,8 @@ namespace Polycode {
             void mixIntoBuffer(int16_t *buffer, unsigned int numSamples);
             std::vector<Sound*> sounds;
             Number globalVolume;
-
+            Vector3 listenerPosition;
+            Quaternion listenerOrientation;
 			CoreMutex *mixerMutex;
     };
 	
@@ -66,8 +68,8 @@ namespace Polycode {
 		SoundManager();
 		~SoundManager();
 		 
-		void setListenerPosition(Vector3 position);
-		void setListenerOrientation(Vector3 orientation, Vector3 upVector);	
+		void setListenerPosition(const Vector3 &position);
+		void setListenerOrientation(const Quaternion &orientation);
         
         bool recordSound(unsigned int rate, unsigned int sampleSize);
         Sound *stopRecording(bool generateFloatBuffer = false);

+ 6 - 2
src/bindings/javascript/PolycodeJS.cpp

@@ -1796,7 +1796,7 @@ int jsopen_Polycode(duk_context *ctx) {
 			{"BoneTrack_Reset", Polycode_BoneTrack_Reset, 1},
 			{"BoneTrack_setSpeed", Polycode_BoneTrack_setSpeed, 2},
 			{"Sound__delete", Polycode_Sound__delete, 1},
-			{"Sound_getSampleAsNumber", Polycode_Sound_getSampleAsNumber, 3},
+			{"Sound_getSampleAsNumber", Polycode_Sound_getSampleAsNumber, 5},
 			{"Sound_loadFile", Polycode_Sound_loadFile, 2},
 			{"Sound_Play", Polycode_Sound_Play, 3},
 			{"Sound_Stop", Polycode_Sound_Stop, 1},
@@ -1833,13 +1833,17 @@ int jsopen_Polycode(duk_context *ctx) {
 			{"AudioStreamingSource_getFrequency", Polycode_AudioStreamingSource_getFrequency, 1},
 			{"AudioMixer__get_globalVolume", Polycode_AudioMixer__get_globalVolume, 1},
 			{"AudioMixer__set_globalVolume", Polycode_AudioMixer__set_globalVolume, 2},
+			{"AudioMixer__get_listenerPosition", Polycode_AudioMixer__get_listenerPosition, 1},
+			{"AudioMixer__set_listenerPosition", Polycode_AudioMixer__set_listenerPosition, 2},
+			{"AudioMixer__get_listenerOrientation", Polycode_AudioMixer__get_listenerOrientation, 1},
+			{"AudioMixer__set_listenerOrientation", Polycode_AudioMixer__set_listenerOrientation, 2},
 			{"AudioMixer__get_mixerMutex", Polycode_AudioMixer__get_mixerMutex, 1},
 			{"AudioMixer__set_mixerMutex", Polycode_AudioMixer__set_mixerMutex, 2},
 			{"AudioMixer__delete", Polycode_AudioMixer__delete, 1},
 			{"AudioMixer_mixIntoBuffer", Polycode_AudioMixer_mixIntoBuffer, 3},
 			{"SoundManager__delete", Polycode_SoundManager__delete, 1},
 			{"SoundManager_setListenerPosition", Polycode_SoundManager_setListenerPosition, 2},
-			{"SoundManager_setListenerOrientation", Polycode_SoundManager_setListenerOrientation, 3},
+			{"SoundManager_setListenerOrientation", Polycode_SoundManager_setListenerOrientation, 2},
 			{"SoundManager_recordSound", Polycode_SoundManager_recordSound, 3},
 			{"SoundManager_stopRecording", Polycode_SoundManager_stopRecording, 2},
 			{"SoundManager_setAudioInterface", Polycode_SoundManager_setAudioInterface, 2},

+ 4 - 0
src/bindings/lua/PolycodeLua.cpp

@@ -1942,8 +1942,12 @@ int luaopen_Polycode(lua_State *L) {
 		{"AudioStreamingSource_getFrequency", Polycode_AudioStreamingSource_getFrequency},
 		{"delete_AudioStreamingSource", Polycode_delete_AudioStreamingSource},
 		{"AudioMixer_get_globalVolume", Polycode_AudioMixer_get_globalVolume},
+		{"AudioMixer_get_listenerPosition", Polycode_AudioMixer_get_listenerPosition},
+		{"AudioMixer_get_listenerOrientation", Polycode_AudioMixer_get_listenerOrientation},
 		{"AudioMixer_get_mixerMutex", Polycode_AudioMixer_get_mixerMutex},
 		{"AudioMixer_set_globalVolume", Polycode_AudioMixer_set_globalVolume},
+		{"AudioMixer_set_listenerPosition", Polycode_AudioMixer_set_listenerPosition},
+		{"AudioMixer_set_listenerOrientation", Polycode_AudioMixer_set_listenerOrientation},
 		{"AudioMixer_set_mixerMutex", Polycode_AudioMixer_set_mixerMutex},
 		{"AudioMixer", Polycode_AudioMixer},
 		{"AudioMixer_mixIntoBuffer", Polycode_AudioMixer_mixIntoBuffer},

+ 3 - 4
src/core/PolySceneSound.cpp

@@ -37,10 +37,9 @@ SceneSoundListener::~SceneSoundListener() {
 void SceneSoundListener::Update() {
 	Matrix4 finalMatrix = getConcatenatedMatrix();
 	CoreServices::getInstance()->getSoundManager()->setListenerPosition(finalMatrix.getPosition());
-
-	Vector3 upVector = Vector3(finalMatrix.ml[4], finalMatrix.ml[5], finalMatrix.ml[6]);
-	Vector3 direction = Vector3( -finalMatrix.ml[8], -finalMatrix.ml[9], -finalMatrix.ml[10]);
-	CoreServices::getInstance()->getSoundManager()->setListenerOrientation(direction, upVector);
+    Quaternion orientation;
+    orientation.setFromMatrix(finalMatrix);
+	CoreServices::getInstance()->getSoundManager()->setListenerOrientation(orientation);
 }
 
 void SceneSound::setLoopOnLoad(bool val) {

+ 42 - 41
src/core/PolySound.cpp

@@ -218,31 +218,16 @@ void Sound::setPitch(Number newPitch) {
 	this->pitch = newPitch;
 }
 
-void Sound::setSoundPosition(Vector3 position) {
-    /*
-	if(isPositional)
-		alSource3f(soundSource,AL_POSITION, position.x, position.y, position.z);
-	checkALError("Set sound position");
-     */
-        //NOAL_TODO
+void Sound::setSoundPosition(const Vector3 &position) {
+    this->position = position;
 }
 
-void Sound::setSoundVelocity(Vector3 velocity) {
-    /*
-	if(isPositional)
-		alSource3f(soundSource,AL_VELOCITY, velocity.x, velocity.y, velocity.z);
-	checkALError("Set sound velocity");
-     */
-        //NOAL_TODO
+void Sound::setSoundVelocity(const Vector3 &velocity) {
+    this->velocity = velocity;
 }
 
-void Sound::setSoundDirection(Vector3 direction) {
-    /*
-	if(isPositional)
-		alSource3f(soundSource,AL_DIRECTION, direction.x, direction.y, direction.z);
-	checkALError("Set sound direction");
-     */
-        //NOAL_TODO
+void Sound::setSoundDirection(const Vector3 &direction) {
+    this->direction = direction;
 }
 
 
@@ -318,16 +303,10 @@ void Sound::setPositionalProperties(Number referenceDistance, Number maxDistance
 
 void Sound::setReferenceDistance(Number referenceDistance) {
 	this->referenceDistance = referenceDistance;
-	//alSourcef(soundSource, AL_REFERENCE_DISTANCE, referenceDistance);
-	//checkALError("Set reference distance");
-            //NOAL_TODO
 }
 
 void Sound::setMaxDistance(Number maxDistance) {
 	this->maxDistance = maxDistance;
-	//alSourcef(soundSource,AL_MAX_DISTANCE, maxDistance);
-//	checkALError("Set max distance");
-            //NOAL_TODO
 }
 		
 Number Sound::getReferenceDistance() {
@@ -339,19 +318,7 @@ Number Sound::getMaxDistance() {
 }
 
 void Sound::setIsPositional(bool isPositional) {
-    /*
 	this->isPositional = isPositional;
-	if(isPositional) {
-		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_FALSE);
-	} else {
-		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_TRUE);	
-		alSource3f(soundSource,AL_POSITION, 0,0,0);
-		alSource3f(soundSource,AL_VELOCITY, 0,0,0);
-		alSource3f(soundSource,AL_DIRECTION, 0,0,0);				
-	}
-	checkALError("Set is-positional");
-     */
-            //NOAL_TODO
 }
 
 void Sound::Stop() {
@@ -359,12 +326,46 @@ void Sound::Stop() {
 }
 
 
-Number Sound::getSampleAsNumber(unsigned int offset, unsigned int channel) {
+Number Sound::getSampleAsNumber(unsigned int offset, unsigned int channel, const Vector3 &position, const Quaternion &orientation) {
     Number adjustedOffset = ((Number)offset) * pitch * frequencyAdjust;
-    Number ret = (((Number)(soundBuffer[((((unsigned int )adjustedOffset)%numSamples)*numChannels)+(channel % numChannels)])/((Number)INT16_MAX))) * volume;
+    Number ret;
+    if(isPositional) {
+        ret = (((Number)(soundBuffer[((((unsigned int )adjustedOffset)%numSamples)*numChannels)])/((Number)INT16_MAX))) * volume;
+        ret = modulateSampleForListener(ret, channel, position, orientation);
+    } else {
+        ret = (((Number)(soundBuffer[((((unsigned int )adjustedOffset)%numSamples)*numChannels)+(channel % numChannels)])/((Number)INT16_MAX))) * volume;
+    }
     return ret;
 }
 
+Number Sound::modulateSampleForListener(Number sample, unsigned int channel, const Vector3 &position, const Quaternion &orientation) {
+    
+    // setup different channel configurations here
+    // if(STEREO) {
+    Vector3 earDirection;
+    if(channel) {
+        earDirection = Vector3(-1.0, 0.0, 0.0);
+    } else {
+        earDirection = Vector3(1.0, 0.0, 0.0);
+    }
+    earDirection = orientation.applyTo(earDirection);
+    
+    Vector3 dir = position - this->position;
+    dir.Normalize();
+    Number muliplier = earDirection.dot(dir);
+    if(muliplier < 0.0) {
+        muliplier = 0.0;
+    }
+    
+    Number ret = sample * (0.1 + (muliplier * 0.9)); // bleed 0.1 into the other ear
+    Number distance = position.distance(this->position);
+    Number attenuate = 0.5 * pow(referenceDistance/distance, 2.0);
+    
+    attenuate = min(attenuate, 1.0);
+    attenuate = max(attenuate, 0.0);
+    ret *= attenuate;
+    return ret;
+}
 
 bool Sound::loadBytes(const char *data, int size, int channels, unsigned int freq, SoundFormat format) {
     

+ 9 - 17
src/core/PolySoundManager.cpp

@@ -44,24 +44,16 @@ void SoundManager::setGlobalVolume(Number globalVolume) {
     mixer->globalVolume = globalVolume;
 }
 
-void SoundManager::setListenerPosition(Vector3 position) {
-    // NOAL_TODO
-//	alListener3f(AL_POSITION, position.x, position.y, position.z);
+void SoundManager::setListenerPosition(const Vector3 &position) {
+    if(mixer) {
+        mixer->listenerPosition = position;
+    }
 }
 
-void SoundManager::setListenerOrientation(Vector3 orientation, Vector3 upVector) {
-    /*
-	ALfloat ori[6];
-	ori[0] = orientation.x;
-	ori[1] = orientation.y;
-	ori[2] = orientation.z;
-	
-	ori[3] = upVector.x;
-	ori[4] = upVector.y;
-	ori[5] = upVector.z;	
-	alListenerfv(AL_ORIENTATION,ori);
-     */
-    // NOAL_TODO
+void SoundManager::setListenerOrientation(const Quaternion &orientation) {
+    if(mixer) {
+        mixer->listenerOrientation = orientation;
+    }
 }
 
 bool SoundManager::recordSound(unsigned int rate, unsigned int sampleSize) {
@@ -192,7 +184,7 @@ void AudioMixer::mixIntoBuffer(int16_t *buffer, unsigned int numSamples) {
 
                 for(int c=0; c < POLY_NUM_CHANNELS; c++) {
                     Number sampleA = mixResults[c];
-                    Number sampleB = sounds[i]->getSampleAsNumber(sounds[i]->getOffset(), c);
+                    Number sampleB = sounds[i]->getSampleAsNumber(sounds[i]->getOffset(), c, listenerPosition, listenerOrientation);
                     
                     if(mixNum == 0) {
                         mixResults[c] = sampleB;