added specular lighting calculation function 40/12440/1
Pedro Arthur [Tue, 3 Sep 2013 13:05:58 +0000 (10:05 -0300)]
Change-Id: Ibf1e9cd4242a4ae60137a017bd041cd5cb9379a0

scilab/modules/renderer/src/java/org/scilab/modules/renderer/JoGLView/util/LightingUtils.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/LightHelper.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Motor3D.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/jogl/lightning/JoGLLightManager.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/shapes/appearance/Material.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/tranformations/Vector3f.java

index d5bab8b..1e1f431 100644 (file)
@@ -39,7 +39,7 @@ public class LightingUtils {
         color = m.getSpecularColor();
         mtl.setSpecularColor(new Color(color[0].floatValue(), color[1].floatValue(), color[2].floatValue()));
         mtl.setColorMaterialEnable(m.getColorMaterialMode().booleanValue());
-        mtl.setShinines(m.getShininess().floatValue());
+        mtl.setShininess(m.getShininess().floatValue());
 
         return mtl;
     }
@@ -60,10 +60,10 @@ public class LightingUtils {
     public static void setupLights(LightManager manager, org.scilab.modules.graphic_objects.axes.Axes axes) {
 
         if (manager == null) return;
-        
+
         boolean hasLight = false;
         int index = 0;
-        
+
         for (String child : axes.getChildren()) {
             GraphicObject object = GraphicController.getController().getObjectFromId(child);
             if (object instanceof org.scilab.modules.graphic_objects.lighting.Light) {
index c045e96..5141cd9 100644 (file)
@@ -8,13 +8,14 @@
  * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  */
+
 package org.scilab.forge.scirenderer.implementation.g2d.motor;
 
 import java.awt.Color;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
 
+
 import org.scilab.forge.scirenderer.tranformations.Vector3f;
 import org.scilab.forge.scirenderer.implementation.g2d.lighting.G2DLight;
 import org.scilab.forge.scirenderer.shapes.appearance.Material;
@@ -43,8 +44,8 @@ public class LightHelper {
         }
 
         Vector3f[] ret = new Vector3f[floats.length / stride];
-        for (int i = 0; i < floats.length; i+= stride) {
-            ret[i] = new Vector3f(floats[i], floats[i+1], floats[i+2]);
+        for (int i = 0; i < floats.length; i += stride) {
+            ret[i] = new Vector3f(floats[i], floats[i + 1], floats[i + 2]);
         }
         return ret;
     }
@@ -79,7 +80,7 @@ public class LightHelper {
 
         Vector3f[] ret = new Vector3f[idx.length];
         for (int i = 0; i < idx.length; ++i) {
-            ret[i] = new Vector3f(floats[stride*idx[i]], floats[stride*idx[i]+1], floats[stride*idx[i]+2]);
+            ret[i] = new Vector3f(floats[stride * idx[i]], floats[stride * idx[i] + 1], floats[stride * idx[i] + 2]);
         }
         return ret;
     }
@@ -119,10 +120,10 @@ public class LightHelper {
         for (int i = 0; i < colors.length; ++i) {
 
             if (directional) {
-                ndotl = normals[i].getNormalized().scalar(light);
-            }else {
+                ndotl = normals[i].scalar(light);
+            } else {
                 Vector3f ray = light.minus(vertices[i]).getNormalized();
-                ndotl = normals[i].getNormalized().scalar(ray);
+                ndotl = normals[i].scalar(ray);
             }
             ndotl = clamp(ndotl);
             Color c = getColorProduct(colors[i], diffuse);
@@ -134,7 +135,7 @@ public class LightHelper {
         }
         return output;
     }
-    
+
     /**
      * Apply diffuse light to the output colors
      * @param light the light position or direction.
@@ -151,10 +152,10 @@ public class LightHelper {
         for (int i = 0; i < output.length; ++i) {
 
             if (directional) {
-                ndotl = normals[i].getNormalized().scalar(light);
-            }else {
+                ndotl = normals[i].scalar(light);
+            } else {
                 Vector3f ray = light.minus(vertices[i]).getNormalized();
-                ndotl = normals[i].getNormalized().scalar(ray);
+                ndotl = normals[i].scalar(ray);
             }
             ndotl = clamp(ndotl);
             if (additive) {
@@ -166,10 +167,24 @@ public class LightHelper {
         return output;
     }
 
-    public static Color[] applySpecular(Vector3f camera, Vector3f light, boolean directional, Vector3f[] vertices, Vector3f[] normals, Color specular, Color[] output, boolean additive) {
+    public static Color[] applySpecular(Vector3f camera, Vector3f light, float shininess, boolean directional, Vector3f[] vertices, Vector3f[] normals, Color specular, Color[] output, boolean additive) {
         for (int i = 0; i < output.length; ++i) {
+            Vector3f R;
+            Vector3f view = camera.minus(vertices[i]).getNormalized();
+            if (directional) {
+                R = reflect(light.negate(), normals[i]);
+            } else {
+                Vector3f ray = light.minus(vertices[i]).getNormalized();
+                R = reflect(ray.negate(), normals[i]);
+            }
+            R = R.getNormalized();
+            float s = R.scalar(view);
+            s = s < 0.0f ? 0.0f : s;
+            s = (float)Math.pow((double)s, (double)shininess);
             if (additive) {
+                output[i] = getColorSum(getColorProduct(specular, s), output[i]);
             } else {
+                output[i] = getColorProduct(specular, s);
             }
         }
         return output;
@@ -191,13 +206,17 @@ public class LightHelper {
         Color diffuse = getColorProduct(mat.getDiffuseColor(), light.getDiffuseColor());
         Color specular = getColorProduct(mat.getSpecularColor(), light.getSpecularColor());
 
+        for (int i = 0; i < normals.length; ++i) {
+            normals[i] = normals[i].getNormalized();
+        }
+
         Color[] finalColor = applyAmbient(ambient, output, additive);
 
         float[] v;
         if (light.isPoint()) {
             v = light.getPosition().getDataAsFloatArray();
         } else {
-            v = light.getDirection().getDataAsFloatArray();  
+            v = light.getDirection().getDataAsFloatArray();
         }
 
         Vector3f vec = new Vector3f(v[0], v[1], v[2]);
@@ -208,8 +227,7 @@ public class LightHelper {
             finalColor = applyDiffuse(vec, !light.isPoint(), vertices, normals, diffuse, finalColor, true);
         }
 
-        //TODO: how to retrieve Camera position?
-        //finalColor = performSpecular(null, null, false, vertices, normals, specular, finalColor, true);
+        //finalColor = applySpecular(new Vector3f(), vec, mat.getShininess(), !light.isPoint(), vertices, normals, specular, finalColor, true);
 
         return finalColor;
     }
@@ -248,4 +266,8 @@ public class LightHelper {
         f = f > 1.0f ? 1.0f : f;
         return f;
     }
+
+    static Vector3f reflect(Vector3f I, Vector3f N) {
+        return I.minus(N.times(2 * I.scalar(N)));
+    }
 }
index 012e26b..07e9fe3 100644 (file)
@@ -425,8 +425,8 @@ public class Motor3D {
         if (texture != null) {
             filter = texture.getMagnificationFilter();
         }
-        
-       colorsArray = applyLighting(vertices, normals, indices, colorsArray, lightManager);
+
+        colorsArray = applyLighting(vertices, normals, indices, colorsArray, lightManager);
 
         switch (drawingMode) {
             case TRIANGLE_FAN :
@@ -551,7 +551,7 @@ public class Motor3D {
     private Color[] applyLighting(FloatBuffer vertices, FloatBuffer normals, IntBuffer index, Color[] colors, G2DLightManager lightManager) {
 
         if (!lightManager.isLightningEnable() || vertices == null || normals == null
-            || index == null || colors == null) {
+                || index == null || colors == null) {
             return colors;
         }
 
@@ -560,7 +560,6 @@ public class Motor3D {
             return colors;
         }
 
-
         Vector3f[] vertexArray = LightHelper.getIndexedVector3f(vertices, index, G2DElementsBuffer.ELEMENT_SIZE);
         Vector3f[] normalArray = LightHelper.getIndexedVector3f(normals, index, G2DElementsBuffer.ELEMENT_SIZE);
 
index 94a0e39..451f664 100644 (file)
@@ -89,7 +89,7 @@ public class JoGLLightManager implements LightManager {
             }
             drawingTools.getGl().glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, material.getAmbientColor().getComponents(null), 0);
             drawingTools.getGl().glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, material.getSpecularColor().getComponents(null), 0);
-            drawingTools.getGl().glMaterialf(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, material.getShinines());
+            drawingTools.getGl().glMaterialf(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, material.getShininess());
             float[] f = {0.0f, 0.0f, 0.0f, 0.0f};
             drawingTools.getGl().glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_EMISSION, f, 0);
         }
index a39bf07..9f9846c 100644 (file)
@@ -25,8 +25,8 @@ public class Material {
     private Color diffuse;
     /** specular color */
     private Color specular;
-    /** shinines level */
-    private float shinines;
+    /** shininess level */
+    private float shininess;
     
     /**
      * @param the new ambient color;.
@@ -52,8 +52,8 @@ public class Material {
     /**
      * @param the new shinines.
      */
-    public void setShinines(float s) {
-        shinines = s;
+    public void setShininess(float s) {
+        shininess = s;
     }
 
     /**
@@ -78,10 +78,10 @@ public class Material {
     }
 
     /**
-     * @return the shinines.;
+     * @return the shininess.
      */
-    public float getShinines() {
-        return shinines;
+    public float getShininess() {
+        return shininess;
     }
 
     /**
index 624f521..41719a3 100644 (file)
@@ -54,6 +54,10 @@ public class Vector3f {
         return new Vector3f(x - v.x, y - v.y, z - v.z);
     }
 
+    public Vector3f negate() {
+        return new Vector3f(-x, -y, -z);
+    }
+
     public Vector3f times(float d) {
         return new Vector3f(x * d, y * d, z * d);
     }