diff --git a/examples/avatarLocalLight.js b/examples/avatarLocalLight.js index 5768388b45..040289af1f 100644 --- a/examples/avatarLocalLight.js +++ b/examples/avatarLocalLight.js @@ -10,174 +10,127 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var localLightDirections = [ {x: 1.0, y:1.0, z: 0.0}, {x: 0.0, y:1.0, z: 1.0} ]; -var localLightColors = [ {x: 0.0, y:1.0, z: 0.0}, {x: 1.0, y:0.0, z: 0.0} ]; +var localLightDirections = [ {x: 1.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 1.0} ]; +var localLightColors = [ {x: 1.0, y:1.0, z: 1.0}, {x: 1.0, y:1.0, z: 1.0} ]; var currentSelection = 0; -var currentNumLights = 1; +var currentNumLights = 2; var maxNumLights = 2; var currentNumAvatars = 0; var changeDelta = 0.1; +var lightsDirty = true; function keyPressEvent(event) { var choice = parseInt(event.text); if (event.text == "1") { - currentSelection = 0; - print("light election = " + currentSelection); + currentSelection = 0; + print("light election = " + currentSelection); } else if (event.text == "2" ) { - currentSelection = 1; - print("light selection = " + currentSelection); + currentSelection = 1; + print("light selection = " + currentSelection); } else if (event.text == "3" ) { - currentSelection = 2; - print("light selection = " + currentSelection); + currentSelection = 2; + print("light selection = " + currentSelection); } else if (event.text == "4" ) { - currentSelection = 3; - print("light selection = " + currentSelection); + currentSelection = 3; + print("light selection = " + currentSelection); } else if (event.text == "5" ) { - localLightColors[currentSelection].x += changeDelta; - if ( localLightColors[currentSelection].x > 1.0) { - localLightColors[currentSelection].x = 0.0; - } - - setAllLightColors(); - print("CHANGE RED light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); + localLightColors[currentSelection].x += changeDelta; + if ( localLightColors[currentSelection].x > 1.0) { + localLightColors[currentSelection].x = 0.0; + } + + lightsDirty = true; + print("CHANGE RED light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); } else if (event.text == "6" ) { - localLightColors[currentSelection].y += changeDelta; - if ( localLightColors[currentSelection].y > 1.0) { - localLightColors[currentSelection].y = 0.0; - } - - setAllLightColors(); - print("CHANGE GREEN light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); + localLightColors[currentSelection].y += changeDelta; + if ( localLightColors[currentSelection].y > 1.0) { + localLightColors[currentSelection].y = 0.0; + } + + lightsDirty = true; + print("CHANGE GREEN light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); } else if (event.text == "7" ) { - localLightColors[currentSelection].z += changeDelta; - if ( localLightColors[currentSelection].z > 1.0) { - localLightColors[currentSelection].z = 0.0; - } - - setAllLightColors(); - print("CHANGE BLUE light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); + localLightColors[currentSelection].z += changeDelta; + if ( localLightColors[currentSelection].z > 1.0) { + localLightColors[currentSelection].z = 0.0; + } + + lightsDirty = true; + print("CHANGE BLUE light " + currentSelection + " color (" + localLightColors[currentSelection].x + ", " + localLightColors[currentSelection].y + ", " + localLightColors[currentSelection].z + " )" ); } else if (event.text == "8" ) { - localLightDirections[currentSelection].x += changeDelta; - if (localLightDirections[currentSelection].x > 1.0) { - localLightDirections[currentSelection].x = -1.0; - } - - setAllLightDirections(); - print("PLUS X light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); + localLightDirections[currentSelection].x += changeDelta; + if (localLightDirections[currentSelection].x > 1.0) { + localLightDirections[currentSelection].x = -1.0; + } + + lightsDirty = true; + print("PLUS X light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); } else if (event.text == "9" ) { - localLightDirections[currentSelection].x -= changeDelta; - if (localLightDirections[currentSelection].x < -1.0) { - localLightDirections[currentSelection].x = 1.0; - } - - setAllLightDirections(); - print("MINUS X light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); + localLightDirections[currentSelection].x -= changeDelta; + if (localLightDirections[currentSelection].x < -1.0) { + localLightDirections[currentSelection].x = 1.0; + } + + lightsDirty = true; + print("MINUS X light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); } else if (event.text == "0" ) { - localLightDirections[currentSelection].y += changeDelta; - if (localLightDirections[currentSelection].y > 1.0) { - localLightDirections[currentSelection].y = -1.0; - } - - setAllLightDirections(); - print("PLUS Y light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); + localLightDirections[currentSelection].y += changeDelta; + if (localLightDirections[currentSelection].y > 1.0) { + localLightDirections[currentSelection].y = -1.0; + } + + lightsDirty = true; + print("PLUS Y light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); } else if (event.text == "-" ) { - localLightDirections[currentSelection].y -= changeDelta; - if (localLightDirections[currentSelection].y < -1.0) { - localLightDirections[currentSelection].y = 1.0; - } - - setAllLightDirections(); - print("MINUS Y light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); + localLightDirections[currentSelection].y -= changeDelta; + if (localLightDirections[currentSelection].y < -1.0) { + localLightDirections[currentSelection].y = 1.0; + } + + lightsDirty = true; + print("MINUS Y light " + currentSelection + " direction (" + localLightDirections[currentSelection].x + ", " + localLightDirections[currentSelection].y + ", " + localLightDirections[currentSelection].z + " )" ); } else if (event.text == "," ) { - if (currentNumLights + 1 <= maxNumLights) { - ++currentNumLights; - - for (var i = 0; i < currentNumAvatars; i++) { - AvatarManager.addAvatarLocalLight(i); - - for (var j = 0; j < currentNumLights; j++) { - AvatarManager.setAvatarLightColor(localLightColors[j], j, i); - AvatarManager.setAvatarLightDirection(localLightDirections[j], j, i); - } - } - } - - print("ADD LIGHT, number of lights " + currentNumLights); + if (currentNumLights + 1 <= maxNumLights) { + ++currentNumLights; + lightsDirty = true; + } + + print("ADD LIGHT, number of lights " + currentNumLights); } else if (event.text == "." ) { - if (currentNumLights - 1 >= 0 ) { - --currentNumLights; - - for (var i = 0; i < currentNumAvatars; i++) { - AvatarManager.removeAvatarLocalLight(i); - - for (var j = 0; j < currentNumLights; j++) { - AvatarManager.setAvatarLightColor(localLightColors[j], j, i); - AvatarManager.setAvatarLightDirection(localLightDirections[j], j, i); - } - } - - } - - print("REMOVE LIGHT, number of lights " + currentNumLights); + if (currentNumLights - 1 >= 0 ) { + --currentNumLights; + lightsDirty = true; + } + + print("REMOVE LIGHT, number of lights " + currentNumLights); } } function updateLocalLights() { - // new avatars, so add lights - var numAvatars = AvatarManager.getNumAvatars(); - if (numAvatars != currentNumAvatars) { - - for (var i = 0; i < numAvatars; i++) { - var numLights = AvatarManager.getNumLightsInAvatar(i); - - // check if new avatar has lights - if (numLights <= 0) { - AvatarManager.addAvatarLocalLight(i); - - // set color and direction for new avatar - for (var j = 0; j < maxNumLights; j++) { - AvatarManager.setAvatarLightColor(localLightColors[j], j, i); - AvatarManager.setAvatarLightDirection(localLightDirections[j], j, i); - } - } - } - - currentNumAvatars = numAvatars; - } -} - -function setAllLightColors() -{ - for (var i = 0; i < currentNumAvatars; i++) { - for (var j = 0; j < maxNumLights; j++) { - AvatarManager.setAvatarLightColor(localLightColors[j], j, i); - } - } -} - -function setAllLightDirections() -{ - for (var i = 0; i < currentNumAvatars; i++) { - for (var j = 0; j < maxNumLights; j++) { - AvatarManager.setAvatarLightDirection(localLightDirections[j], j, i); - } - } + if (lightsDirty) { + var localLights = []; + for (var i = 0; i < currentNumLights; i++) { + localLights.push({ direction: localLightDirections[i], color: localLightColors[i] }); + } + AvatarManager.setLocalLights(localLights); + lightsDirty = false; + } } // main diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 468a892686..27f6510477 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -11,16 +11,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; // the diffuse texture uniform sampler2D diffuseMap; -// local lights -const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on -uniform int numLocalLights; -uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; -uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; - // the interpolated position varying vec4 position; @@ -28,23 +24,18 @@ varying vec4 position; varying vec4 normal; void main(void) { - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 normalizedNormal = normalize(normal); - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - - // the local light that is always present - vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); - for (int i = 0; i < numLocalLights; i++) { - float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0)); - float localLight = step(0.0, localDiffuse); - float localLightVal = localDiffuse * localLight; - - totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0)); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); } + // compute the base color based on OpenGL lighting model + float diffuse = dot(normalizedNormal, gl_LightSource[0].position); + float facingLight = step(0.0, diffuse); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/resources/shaders/model_cascaded_shadow_map.frag b/interface/resources/shaders/model_cascaded_shadow_map.frag index 720c43b656..35026cb3b2 100644 --- a/interface/resources/shaders/model_cascaded_shadow_map.frag +++ b/interface/resources/shaders/model_cascaded_shadow_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -34,9 +37,15 @@ void main(void) { int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0))); vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), dot(gl_EyePlaneR[shadowIndex], position)); + + // add up the local lights + vec4 normalizedNormal = normalize(normal); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); + } // compute the base color based on OpenGL lighting model - vec4 normalizedNormal = normalize(normal); float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -44,7 +53,7 @@ void main(void) { shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/resources/shaders/model_cascaded_shadow_normal_map.frag b/interface/resources/shaders/model_cascaded_shadow_normal_map.frag index 5758333392..0e474c173a 100644 --- a/interface/resources/shaders/model_cascaded_shadow_normal_map.frag +++ b/interface/resources/shaders/model_cascaded_shadow_normal_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -46,10 +49,16 @@ void main(void) { vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], interpolatedPosition), dot(gl_EyePlaneT[shadowIndex], interpolatedPosition), dot(gl_EyePlaneR[shadowIndex], interpolatedPosition)); - - // compute the base color based on OpenGL lighting model + + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -57,7 +66,7 @@ void main(void) { shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - diff --git a/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag b/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag index 2b949710f3..33c025925e 100644 --- a/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag +++ b/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -50,9 +53,15 @@ void main(void) { dot(gl_EyePlaneT[shadowIndex], interpolatedPosition), dot(gl_EyePlaneR[shadowIndex], interpolatedPosition)); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -60,7 +69,7 @@ void main(void) { shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - diff --git a/interface/resources/shaders/model_cascaded_shadow_specular_map.frag b/interface/resources/shaders/model_cascaded_shadow_specular_map.frag index ba8ba6b85b..9190654431 100644 --- a/interface/resources/shaders/model_cascaded_shadow_specular_map.frag +++ b/interface/resources/shaders/model_cascaded_shadow_specular_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -38,8 +41,14 @@ void main(void) { vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), dot(gl_EyePlaneR[shadowIndex], position)); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 normalizedNormal = normalize(normal); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -47,7 +56,7 @@ void main(void) { shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index ca0201f6ab..acd049dc47 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -32,19 +35,20 @@ void main(void) { vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse); - float localDiffuse = dot(viewNormal, gl_LightSource[1].position); - float localLight = step(0.0, localDiffuse); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + gl_FrontLightProduct[1].diffuse * (localDiffuse * localLight)); - - - - + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); + // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index 357677d82a..fa997bff7f 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -35,13 +38,19 @@ void main(void) { vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - diff --git a/interface/resources/shaders/model_shadow_map.frag b/interface/resources/shaders/model_shadow_map.frag index aa1df03b95..c2bf95fd27 100644 --- a/interface/resources/shaders/model_shadow_map.frag +++ b/interface/resources/shaders/model_shadow_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -27,8 +30,14 @@ varying vec4 position; varying vec4 normal; void main(void) { - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 normalizedNormal = normalize(normal); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -36,7 +45,7 @@ void main(void) { shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/resources/shaders/model_shadow_normal_map.frag b/interface/resources/shaders/model_shadow_normal_map.frag index 3461c1b5f3..058c3783be 100644 --- a/interface/resources/shaders/model_shadow_normal_map.frag +++ b/interface/resources/shaders/model_shadow_normal_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -38,9 +41,15 @@ void main(void) { vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -48,7 +57,7 @@ void main(void) { shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - diff --git a/interface/resources/shaders/model_shadow_normal_specular_map.frag b/interface/resources/shaders/model_shadow_normal_specular_map.frag index 273d197fca..5b8d7c87a4 100644 --- a/interface/resources/shaders/model_shadow_normal_specular_map.frag +++ b/interface/resources/shaders/model_shadow_normal_specular_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -41,9 +44,15 @@ void main(void) { vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(viewNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -51,7 +60,7 @@ void main(void) { shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - diff --git a/interface/resources/shaders/model_shadow_specular_map.frag b/interface/resources/shaders/model_shadow_specular_map.frag index 77cff1e04e..9f413f63a4 100644 --- a/interface/resources/shaders/model_shadow_specular_map.frag +++ b/interface/resources/shaders/model_shadow_specular_map.frag @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; + // the diffuse texture uniform sampler2D diffuseMap; @@ -30,8 +33,14 @@ varying vec4 position; varying vec4 normal; void main(void) { - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 normalizedNormal = normalize(normal); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); + } + + // compute the base color based on OpenGL lighting model float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + @@ -39,7 +48,7 @@ void main(void) { shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 329da65e9e..54790a36fb 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -10,11 +10,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -const int MAX_LOCAL_LIGHTS = 2; -uniform int numLocalLights; -uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; -uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; +// the maximum number of local lights to apply +const int MAX_LOCAL_LIGHTS = 2; // the diffuse texture uniform sampler2D diffuseMap; @@ -29,23 +27,18 @@ varying vec4 position; varying vec4 normal; void main(void) { - // compute the base color based on OpenGL lighting model + // add up the local lights vec4 normalizedNormal = normalize(normal); - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - - // the local light that is always present - vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); - for (int i = 0; i < numLocalLights; i++) { - float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0)); - float localLight = step(0.0, localDiffuse); - float localLightVal = localDiffuse * localLight; - - totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0)); + vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); + for (int i = 1; i <= MAX_LOCAL_LIGHTS; i++) { + localLight += gl_FrontLightProduct[i].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[i].position)); } + // compute the base color based on OpenGL lighting model + float diffuse = dot(normalizedNormal, gl_LightSource[0].position); + float facingLight = step(0.0, diffuse); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aad9c4de58..1d0bf8d6a3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3628,6 +3628,9 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine->getModelsScriptingInterface()->setPacketSender(&_modelEditSender); scriptEngine->getModelsScriptingInterface()->setModelTree(_models.getTree()); + // model has some custom types + Model::registerMetaTypes(scriptEngine->getEngine()); + // hook our avatar object into this script engine scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index b5590dec09..ef0fae1c13 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -60,7 +60,6 @@ Avatar::Avatar() : _mouseRayDirection(0.0f, 0.0f, 0.0f), _moving(false), _collisionGroups(0), - _numLocalLights(0), _initialized(false), _shouldRenderBillboard(true) { @@ -245,19 +244,9 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { // local lights directions and colors - getSkeletonModel().setNumLocalLights(_numLocalLights); - getHead()->getFaceModel().setNumLocalLights(_numLocalLights); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - glm::vec3 normalized = glm::normalize(_localLightDirections[i]); - - // body - getSkeletonModel().setLocalLightColor(_localLightColors[i], i); - getSkeletonModel().setLocalLightDirection(normalized, i); - - // head - getHead()->getFaceModel().setLocalLightColor(_localLightColors[i], i); - getHead()->getFaceModel().setLocalLightDirection(_localLightDirections[i], i); - } + const QVector& localLights = Application::getInstance()->getAvatarManager().getLocalLights(); + _skeletonModel.setLocalLights(localLights); + getHead()->getFaceModel().setLocalLights(localLights); // render body if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { @@ -926,36 +915,3 @@ void Avatar::setShowDisplayName(bool showDisplayName) { } -void Avatar::setLocalLightDirection(const glm::vec3& direction, int lightIndex) { - _localLightDirections[lightIndex] = direction; -} - -void Avatar::setLocalLightColor(const glm::vec3& color, int lightIndex) { - _localLightColors[lightIndex] = color; -} - -void Avatar::addLocalLight() { - if (_numLocalLights + 1 <= MAX_LOCAL_LIGHTS) { - ++_numLocalLights; - } -} - -void Avatar::removeLocalLight() { - if (_numLocalLights - 1 >= 0) { - --_numLocalLights; - } -} - -int Avatar::getNumLocalLights() { - return _numLocalLights; -} - -glm::vec3 Avatar::getLocalLightDirection(int lightIndex) { - return _localLightDirections[lightIndex]; -} - -glm::vec3 Avatar::getLocalLightColor(int lightIndex) { - return _localLightColors[lightIndex]; -} - - diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index d2f3ee6ab4..02bc2f227a 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -159,14 +159,7 @@ public: public slots: void updateCollisionGroups(); - void setLocalLightDirection(const glm::vec3& direction, int lightIndex); - void setLocalLightColor(const glm::vec3& color, int lightIndex); - void addLocalLight(); - void removeLocalLight(); - int getNumLocalLights(); - glm::vec3 getLocalLightDirection(int lightIndex); - glm::vec3 getLocalLightColor(int lightIndex); - + signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); @@ -189,11 +182,6 @@ protected: bool _moving; ///< set when position is changing quint32 _collisionGroups; - - // always-present local lighting for the avatar - glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; - glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; - int _numLocalLights; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c172df5de6..0db12276ad 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -159,58 +159,21 @@ void AvatarManager::clearOtherAvatars() { _myAvatar->clearLookAtTargetAvatar(); } -Avatar* AvatarManager::getAvatarFromIndex(int avatarIndex) { - Avatar* avatar = NULL; - int numAvatars = _avatarHash.count(); - if (avatarIndex < numAvatars) { - QUuid key = (_avatarHash.keys())[avatarIndex]; - - const AvatarSharedPointer& avatarPointer = _avatarHash.value(key); - avatar = static_cast(avatarPointer.data()); +void AvatarManager::setLocalLights(const QVector& localLights) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector&, localLights)); + return; } - - return avatar; + _localLights = localLights; } -void AvatarManager::addAvatarLocalLight(int avatarIndex) { - Avatar* avatar = getAvatarFromIndex(avatarIndex); - if (avatar) { - avatar->addLocalLight(); +QVector AvatarManager::getLocalLights() const { + if (QThread::currentThread() != thread()) { + QVector result; + QMetaObject::invokeMethod(const_cast(this), "getLocalLights", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QVector, result)); + return result; } + return _localLights; } -void AvatarManager::removeAvatarLocalLight(int avatarIndex) { - Avatar* avatar = getAvatarFromIndex(avatarIndex); - if (avatar) { - avatar->removeLocalLight(); - } -} - -void AvatarManager::setAvatarLightDirection(const glm::vec3& direction, int lightIndex, int avatarIndex) { - Avatar* avatar = getAvatarFromIndex(avatarIndex); - if (avatar) { - avatar->setLocalLightDirection(direction, lightIndex); - } -} - -void AvatarManager::setAvatarLightColor(const glm::vec3& color, int lightIndex, int avatarIndex) { - Avatar* avatar = getAvatarFromIndex(avatarIndex); - if (avatar) { - avatar->setLocalLightColor(color, lightIndex); - } -} - -int AvatarManager::getNumLightsInAvatar(int avatarIndex) { - int numLights = 0; - - Avatar* avatar = getAvatarFromIndex(avatarIndex); - if (avatar) { - numLights = avatar->getNumLocalLights(); - } - - return numLights; -} - -int AvatarManager::getNumAvatars() { - return _avatarHash.count(); -} diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index e6f058c0ab..ccb7459217 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -37,13 +37,8 @@ public: void clearOtherAvatars(); -public slots: - void setAvatarLightColor(const glm::vec3& color, int lightIndex, int avatarIndex); - void setAvatarLightDirection(const glm::vec3& direction, int lightIndex, int avatarIndex); - void removeAvatarLocalLight(int avatarIndex); - void addAvatarLocalLight(int avatarIndex); - int getNumLightsInAvatar(int avatarIndex); - int getNumAvatars(); + Q_INVOKABLE void setLocalLights(const QVector& localLights); + Q_INVOKABLE QVector getLocalLights() const; private: AvatarManager(const AvatarManager& other); @@ -53,13 +48,13 @@ private: AvatarSharedPointer newSharedAvatar(); - Avatar* getAvatarFromIndex(int avatarIndex); - // virtual override AvatarHash::iterator erase(const AvatarHash::iterator& iterator); QVector _avatarFades; QSharedPointer _myAvatar; + + QVector _localLights; }; #endif // hifi_AvatarManager_h diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index d65cb014c9..c5c83aa01d 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -31,6 +33,23 @@ static int modelPointerTypeId = qRegisterMetaType >(); static int weakNetworkGeometryPointerTypeId = qRegisterMetaType >(); static int vec3VectorTypeId = qRegisterMetaType >(); +static QScriptValue localLightToScriptValue(QScriptEngine* engine, const Model::LocalLight& light) { + QScriptValue object = engine->newObject(); + object.setProperty("direction", vec3toScriptValue(engine, light.direction)); + object.setProperty("color", vec3toScriptValue(engine, light.color)); + return object; +} + +static void localLightFromScriptValue(const QScriptValue& value, Model::LocalLight& light) { + vec3FromScriptValue(value.property("direction"), light.direction); + vec3FromScriptValue(value.property("color"), light.color); +} + +void Model::registerMetaTypes(QScriptEngine* engine) { + qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); + qScriptRegisterSequenceMetaType >(engine); +} + Model::Model(QObject* parent) : QObject(parent), _scale(1.0f, 1.0f, 1.0f), @@ -609,6 +628,20 @@ bool Model::render(float alpha, RenderMode mode, bool receiveShadows) { glEnable(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { glCullFace(GL_FRONT); + + } else if (mode == DEFAULT_RENDER_MODE) { + // set up the local lights + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + glm::vec4 color; + GLenum lightName = GL_LIGHT0 + i + 1; + if (i < _localLights.size()) { + const LocalLight& light = _localLights.at(i); + color = glm::vec4(light.color, 1.0f); + glm::vec4 position = glm::vec4(_rotation * light.direction, 0.0f); + glLightfv(lightName, GL_POSITION, (GLfloat*)&position); + } + glLightfv(lightName, GL_DIFFUSE, (GLfloat*)&color); + } } } @@ -1493,11 +1526,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re if (cascadedShadows) { program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances()); } - - // local light uniforms - skinProgram->setUniformValue("numLocalLights", _numLocalLights); - skinProgram->setUniformArray("localLightDirections", _localLightDirections, MAX_LOCAL_LIGHTS); - skinProgram->setUniformArray("localLightColors", _localLightColors, MAX_LOCAL_LIGHTS); } else { glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]); program->bind(); @@ -1632,20 +1660,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re } } -void Model::setLocalLightDirection(const glm::vec3& direction, int lightIndex) { - assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS); - _localLightDirections[lightIndex] = direction; -} - -void Model::setLocalLightColor(const glm::vec3& color, int lightIndex) { - assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS); - _localLightColors[lightIndex] = color; -} - -void Model::setNumLocalLights(int numLocalLights) { - _numLocalLights = numLocalLights; -} - void AnimationHandle::setURL(const QUrl& url) { if (_url != url) { _animation = Application::getInstance()->getAnimationCache()->getAnimation(_url = url); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 078685345b..fe09710d0a 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -26,6 +26,8 @@ #include "ProgramObject.h" #include "TextureCache.h" +class QScriptEngine; + class AnimationHandle; class Shape; @@ -40,6 +42,9 @@ class Model : public QObject, public PhysicsEntity { public: + /// Registers the script types associated with models. + static void registerMetaTypes(QScriptEngine* engine); + Model(QObject* parent = NULL); virtual ~Model(); @@ -145,9 +150,14 @@ public: /// Sets blended vertices computed in a separate thread. void setBlendedVertices(const QVector& vertices, const QVector& normals); - void setLocalLightDirection(const glm::vec3& direction, int lightIndex); - void setLocalLightColor(const glm::vec3& color, int lightIndex); - void setNumLocalLights(int numLocalLights); + class LocalLight { + public: + glm::vec3 color; + glm::vec3 direction; + }; + + void setLocalLights(const QVector& localLights) { _localLights = localLights; } + const QVector& getLocalLights() const { return _localLights; } void setShowTrueJointTransforms(bool show) { _showTrueJointTransforms = show; } @@ -165,10 +175,8 @@ protected: bool _snappedToCenter; /// are we currently snapped to center bool _showTrueJointTransforms; - glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; - glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; - int _numLocalLights; - + QVector _localLights; + QVector _jointStates; class MeshState { @@ -326,6 +334,8 @@ private: Q_DECLARE_METATYPE(QPointer) Q_DECLARE_METATYPE(QWeakPointer) Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(Model::LocalLight) +Q_DECLARE_METATYPE(QVector) /// Represents a handle to a model animation. class AnimationHandle : public QObject { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 412de6e7b0..f82bc7ba17 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -828,19 +828,19 @@ void Stats::display( } // draw local light stats - int numLocalLights = myAvatar->getNumLocalLights(); + QVector localLights = Application::getInstance()->getAvatarManager().getLocalLights(); verticalOffset = 400; horizontalOffset = 20; char buffer[128]; - for (int i = 0; i < numLocalLights; i++) { - glm::vec3 lightDirection = myAvatar->getLocalLightDirection(i); + for (int i = 0; i < localLights.size(); i++) { + glm::vec3 lightDirection = localLights.at(i).direction; snprintf(buffer, sizeof(buffer), "Light %d direction (%.2f, %.2f, %.2f)", i, lightDirection.x, lightDirection.y, lightDirection.z); drawText(horizontalOffset, verticalOffset, scale, rotation, font, buffer, color); verticalOffset += STATS_PELS_PER_LINE; - glm::vec3 lightColor = myAvatar->getLocalLightColor(i); + glm::vec3 lightColor = localLights.at(i).color; snprintf(buffer, sizeof(buffer), "Light %d color (%.2f, %.2f, %.2f)", i, lightColor.x, lightColor.y, lightColor.z); drawText(horizontalOffset, verticalOffset, scale, rotation, font, buffer, color);