Adding light script to scenegraph.
Patching up the collada parser to handle data from different converters.

Change-Id: Ibac4d3cd8e7af65b67ad3ad5023e26af075a20bb
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
index 127d85e..b7f05ab 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
@@ -48,6 +48,7 @@
     HashMap<String, ArrayList<ShaderParam> > mEffectsParams;

     HashMap<String, Texture2D> mImages;

     HashMap<String, Texture2D> mSamplerImageMap;

+    HashMap<String, String> mMeshIdNameMap;

     Scene mScene;

 

     String mRootDir;

@@ -67,6 +68,7 @@
         mCameras = new HashMap<String, Camera>();

         mEffectsParams = new HashMap<String, ArrayList<ShaderParam> >();

         mImages = new HashMap<String, Texture2D>();

+        mMeshIdNameMap = new HashMap<String, String>();

     }

 

     public void init(InputStream is, String rootDir) {

@@ -142,6 +144,16 @@
             }

         }

 

+        // Look through the geometry list and build up a correlation between id's and names

+        nl = docEle.getElementsByTagName("geometry");

+        if (nl != null) {

+            for(int i = 0; i < nl.getLength(); i++) {

+                Element m = (Element)nl.item(i);

+                convertGeometries(m);

+            }

+        }

+

+

         nl = docEle.getElementsByTagName("visual_scene");

         if (nl != null) {

             for(int i = 0; i < nl.getLength(); i++) {

@@ -152,7 +164,11 @@
     }

 

     private void getRenderable(Element shape, Transform t) {

-        String geoURL = shape.getAttribute("url");

+        String geoURL = shape.getAttribute("url").substring(1);

+        String geoName = mMeshIdNameMap.get(geoURL);

+        if (geoName != null) {

+            geoURL = geoName;

+        }

         //RenderableGroup group = new RenderableGroup();

         //group.setName(geoURL.substring(1));

         //mScene.appendRenderable(group);

@@ -164,9 +180,9 @@
                 String materialName = materialRef.getAttribute("target");

 

                 Renderable d = new Renderable();

-                d.setMesh(geoURL.substring(1), meshIndexName);

+                d.setMesh(geoURL, meshIndexName);

                 d.setMaterialName(materialName);

-                d.setName(geoURL.substring(1));

+                d.setName(geoURL);

 

                 //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);

 

@@ -261,33 +277,36 @@
         }

     }

 

+    // This will find the actual texture node, which is sometimes hidden behind a sampler

+    // and sometimes referenced directly

     Texture2D getTexture(String samplerName) {

+        String texName = samplerName;

+

+        // Check to see if the image file is hidden by a sampler surface link combo

         Element sampler = mDom.getElementById(samplerName);

-        if (sampler == null) {

-            return null;

-        }

-

-        NodeList nl = sampler.getElementsByTagName("source");

-        if (nl != null && nl.getLength() == 1) {

-            Element ref = (Element)nl.item(0);

-            String surfaceName = getString(ref);

-            if (surfaceName == null) {

-                return null;

-            }

-

-            Element surface = mDom.getElementById(surfaceName);

-            if (surface == null) {

-                return null;

-            }

-            nl = surface.getElementsByTagName("init_from");

+        if (sampler != null) {

+            NodeList nl = sampler.getElementsByTagName("source");

             if (nl != null && nl.getLength() == 1) {

-                ref = (Element)nl.item(0);

-                String texName = getString(ref);

-                //Log.v(TAG, "Extracted texture name " + texName);

-                return mImages.get(texName);

+                Element ref = (Element)nl.item(0);

+                String surfaceName = getString(ref);

+                if (surfaceName == null) {

+                    return null;

+                }

+

+                Element surface = mDom.getElementById(surfaceName);

+                if (surface == null) {

+                    return null;

+                }

+                nl = surface.getElementsByTagName("init_from");

+                if (nl != null && nl.getLength() == 1) {

+                    ref = (Element)nl.item(0);

+                    texName = getString(ref);

+                }

             }

         }

-        return null;

+

+        //Log.v(TAG, "Extracted texture name " + texName);

+        return mImages.get(texName);

     }

 

     void extractParams(Element fx, ArrayList<ShaderParam> params) {

@@ -342,6 +361,14 @@
         }

     }

 

+    private void convertGeometries(Element geo) {

+        String id = geo.getAttribute("id");

+        String name = geo.getAttribute("name");

+        if (!id.equals(name)) {

+            mMeshIdNameMap.put(id, name);

+        }

+    }

+

     private void convertEffects(Element fx) {

         String id = fx.getAttribute("id");

         ArrayList<ShaderParam> params = new ArrayList<ShaderParam>();

@@ -417,7 +444,7 @@
         }

 

         Float3 color = getFloat3(light, "color");

-        sceneLight.setColor(color);

+        sceneLight.setColor(color.x, color.y, color.z);

         sceneLight.setName(name);

         mScene.appendLight(sceneLight);

         mLights.put(id, sceneLight);

@@ -428,7 +455,14 @@
     private void convertCamera(Element camera) {

         String name = camera.getAttribute("name");

         String id = camera.getAttribute("id");

-        float fov = getFloat(camera, "yfov");

+        float fov = 30.0f;

+        if (getString(camera, "yfov") != null) {

+            fov = getFloat(camera, "yfov");

+        } else if(getString(camera, "xfov") != null) {

+            float aspect = getFloat(camera, "aspect_ratio");

+            fov = getFloat(camera, "xfov") / aspect;

+        }

+

         float near = getFloat(camera, "znear");

         float far = getFloat(camera, "zfar");

 

@@ -470,7 +504,7 @@
     private String getString(Element elem, String name) {

         String text = null;

         NodeList nl = elem.getElementsByTagName(name);

-        if (nl != null) {

+        if (nl != null && nl.getLength() != 0) {

             text = ((Element)nl.item(0)).getFirstChild().getNodeValue();

         }

         return text;

diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
index 7aad1f8..2214a95 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
@@ -20,21 +20,25 @@
 import java.util.ArrayList;
 
 import android.renderscript.Float3;
+import android.renderscript.Float4;
 import android.renderscript.Matrix4f;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramStore;
-import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
 import android.util.Log;
 
 /**
  * @hide
  */
-public class LightBase extends SceneGraphBase {
+public abstract class LightBase extends SceneGraphBase {
+    static final int RS_LIGHT_POINT = 0;
+    static final int RS_LIGHT_DIRECTIONAL = 1;
+
+    ScriptField_Light_s mField;
+    ScriptField_Light_s.Item mFieldData;
     Transform mTransform;
-    Float3 mColor;
+    Float4 mColor;
     float mIntensity;
     public LightBase() {
-        mColor = new Float3(0.0f, 0.0f, 0.0f);
+        mColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
         mIntensity = 1.0f;
     }
 
@@ -42,13 +46,44 @@
         mTransform = t;
     }
 
+    public void setColor(float r, float g, float b) {
+        mColor.x = r;
+        mColor.y = g;
+        mColor.z = b;
+    }
+
     public void setColor(Float3 c) {
-        mColor = c;
+        mColor.x = c.x;
+        mColor.y = c.y;
+        mColor.z = c.z;
     }
 
     public void setIntensity(float i) {
         mIntensity = i;
     }
+
+    abstract void initLocalData();
+
+    protected void updateBaseData(RenderScriptGL rs) {
+        if (mField == null) {
+            mField = new ScriptField_Light_s(rs, 1);
+            mFieldData = new ScriptField_Light_s.Item();
+        }
+
+        mFieldData.transformMatrix = mTransform.getRSData(rs).getAllocation();
+        mFieldData.name = getStringAsAllocation(rs, getName());
+        mFieldData.color = mColor;
+        mFieldData.intensity = mIntensity;
+    }
+
+    ScriptField_Light_s getRSData(RenderScriptGL rs) {
+        updateBaseData(rs);
+        initLocalData();
+
+        mField.set(mFieldData, 0, true);
+
+        return mField;
+    }
 }
 
 
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
index 41a54c6..574bafc 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
@@ -31,6 +31,10 @@
 public class PointLight extends LightBase {
     public PointLight() {
     }
+
+     void initLocalData() {
+        mFieldData.type = RS_LIGHT_POINT;
+    }
 }
 
 
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
index a308f43..d5d374c 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
@@ -253,6 +253,18 @@
         }
         cameraData.copyFrom(cameraAllocs);
         sceneManager.mRenderLoop.set_gCameras(cameraData);
+
+        if (mLights.size() != 0) {
+            Allocation lightData = Allocation.createSized(rs,
+                                                          Element.ALLOCATION(rs),
+                                                          mCameras.size());
+            Allocation[] lightAllocs = new Allocation[mLights.size()];
+            for (int i = 0; i < mLights.size(); i ++) {
+                lightAllocs[i] = mLights.get(i).getRSData(rs).getAllocation();
+            }
+            lightData.copyFrom(lightAllocs);
+            sceneManager.mRenderLoop.set_gLights(lightData);
+        }
     }
 }
 
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
index 5759fcc..716c958 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
@@ -38,6 +38,7 @@
 
     ScriptC_render mRenderLoop;
     ScriptC_camera mCameraScript;
+    ScriptC_light mLightScript;
     ScriptC_transform mTransformScript;
 
     RenderScriptGL mRS;
@@ -128,10 +129,12 @@
         mTransformScript.set_gTransformScript(mTransformScript);
 
         mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
+        mLightScript = new ScriptC_light(rs, res, R.raw.light);
 
         mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
         mRenderLoop.set_gTransformScript(mTransformScript);
         mRenderLoop.set_gCameraScript(mCameraScript);
+        mRenderLoop.set_gLightScript(mLightScript);
 
         Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
                                                          MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
index e00e507..dbf1d48 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
@@ -16,13 +16,14 @@
 
 #pragma rs java_package_name(com.android.scenegraph)
 
-// The sole purpose of this script is to have various structs exposed 
-// so that java reflected classes are generated 
+// The sole purpose of this script is to have various structs exposed
+// so that java reflected classes are generated
 #include "transform_def.rsh"
 SgTransform *exportPtr;
 SgRenderState *sExport;
 SgRenderable *drExport;
 SgRenderPass *pExport;
 SgCamera *exportPtrCam;
+SgLight *exportPtrLight;
 FBlurOffsets *blurExport;
 VertexShaderInputs *iExport;
\ No newline at end of file
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
new file mode 100644
index 0000000..7310b2d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
@@ -0,0 +1,33 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+//#define DEBUG_LIGHT
+#include "transform_def.rsh"
+
+void root(const rs_allocation *v_in, rs_allocation *v_out) {
+
+    SgLight *light = (SgLight *)rsGetElementAt(*v_in, 0);
+    const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+
+    float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
+    light->position = rsMatrixMultiply(&lTransform->globalMat, zero);
+
+#ifdef DEBUG_LIGHT
+    printLightInfo(light);
+#endif //DEBUG_CAMERA
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
index 8187fbc..9919295 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -21,9 +21,11 @@
 
 rs_script gTransformScript;
 rs_script gCameraScript;
+rs_script gLightScript;
 
 SgTransform *gRootNode;
 rs_allocation gCameras;
+rs_allocation gLights;
 rs_allocation gRenderableObjects;
 
 rs_allocation gRenderPasses;
@@ -182,6 +184,12 @@
     rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect));
 }
 
+static void prepareLights() {
+    if (rsIsObject(gLights)) {
+        rsForEach(gLightScript, gLights, nullAlloc);
+    }
+}
+
 static void drawSorted() {
     for (int i = 0; i < gFrontToBackCount; i ++) {
         SgRenderable *current = (SgRenderable*)gFrontToBack[i];
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh
index 143e50d..ce4b78d 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh
@@ -96,6 +96,18 @@
     rs_allocation transformMatrix;
 } SgCamera;
 
+#define LIGHT_POINT 0
+#define LIGHT_DIRECTIONAL 1
+
+typedef struct __attribute__((packed, aligned(4))) Light_s {
+    float4 position;
+    float4 color;
+    float intensity;
+    int type;
+    rs_allocation name;
+    rs_allocation transformMatrix;
+} SgLight;
+
 typedef struct VShaderParams_s {
     rs_matrix4x4 model;
     rs_matrix4x4 viewProj;
@@ -134,6 +146,19 @@
     rsDebug("View: ", &cam->view);
 }
 
+static void printLightInfo(SgLight *light) {
+    rsDebug("***** Light information. ptr:", light);
+    printName(light->name);
+    const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+    rsDebug("Transform name:", lTransform);
+    printName(lTransform->name);
+
+    rsDebug("Position: ", light->position);
+    rsDebug("Color : ", light->color);
+    rsDebug("Intensity: ", light->intensity);
+    rsDebug("Type: ", light->type);
+}
+
 static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
     rsDebug("=================================", screenX);
     rsDebug("Point X", screenX);