Merge "Keep the '+' when normalizing the phone number"
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 8fea91f..889bf7b 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -28,6 +28,11 @@
     public Float2() {
     }
 
+    public Float2(float initX, float initY) {
+        x = initX;
+        y = initY;
+    }
+
     public float x;
     public float y;
 }
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index 9d9e406..ebe140d 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -27,6 +27,11 @@
 public class Float3 {
     public Float3() {
     }
+    public Float3(float initX, float initY, float initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
 
     public float x;
     public float y;
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index a703e80..847732f 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -28,6 +28,13 @@
     public Float4() {
     }
 
+    public Float4(float initX, float initY, float initZ, float initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
     public float x;
     public float y;
     public float z;
diff --git a/libs/rs/java/SceneGraph/Android.mk b/libs/rs/java/SceneGraph/Android.mk
new file mode 100644
index 0000000..5520446
--- /dev/null
+++ b/libs/rs/java/SceneGraph/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := SceneGraph
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/libs/rs/java/SceneGraph/AndroidManifest.xml b/libs/rs/java/SceneGraph/AndroidManifest.xml
new file mode 100644
index 0000000..8a8f87a
--- /dev/null
+++ b/libs/rs/java/SceneGraph/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.scenegraph">
+    <application android:label="SceneGraph">
+        <activity android:name="SceneGraph"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/libs/rs/java/SceneGraph/res/drawable/robot.png b/libs/rs/java/SceneGraph/res/drawable/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/drawable/robot.png
Binary files differ
diff --git a/libs/rs/java/SceneGraph/res/raw/robot.a3d b/libs/rs/java/SceneGraph/res/raw/robot.a3d
new file mode 100644
index 0000000..2d7d32b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/raw/robot.a3d
Binary files differ
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
new file mode 100644
index 0000000..5daa4ac
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+package com.android.scenegraph;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class SceneGraph extends Activity {
+
+    private SceneGraphView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new SceneGraphView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.onPause();
+    }
+
+}
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
new file mode 100644
index 0000000..3db4a2b6
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+package com.android.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+
+public class SceneGraphRS {
+
+    private final int STATE_LAST_FOCUS = 1;
+
+    int mWidth;
+    int mHeight;
+    int mRotation;
+
+    public SceneGraphRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+        mWidth = width;
+        mHeight = height;
+        mRotation = 0;
+        initRS();
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private Sampler mSampler;
+    private ProgramStore mPSBackground;
+    private ProgramFragment mPFBackground;
+    private ProgramVertex mPVBackground;
+    private ProgramVertex.MatrixAllocation mPVA;
+
+    private Allocation mGridImage;
+    private Allocation mAllocPV;
+
+    private Mesh mMesh;
+
+    private Font mItalic;
+    private Allocation mTextAlloc;
+
+    private ScriptC_Scenegraph mScript;
+    private ScriptC_Transform mTransformScript;
+
+    int mLastX;
+    int mLastY;
+
+    public void touchEvent(int x, int y) {
+        int dx = mLastX - x;
+        if(Math.abs(dx) > 50 || Math.abs(dx) < 3) {
+            dx = 0;
+        }
+
+        mRotation -= dx;
+        if(mRotation > 360) {
+            mRotation -= 360;
+        }
+        if(mRotation < 0) {
+            mRotation += 360;
+        }
+
+        mScript.set_gRotate(-(float)mRotation);
+
+        mLastX = x;
+        mLastY = y;
+    }
+
+    private void initPFS() {
+        ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null);
+
+        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+        b.setDitherEnable(false);
+        b.setDepthMask(true);
+        mPSBackground = b.create();
+
+        mScript.set_gPFSBackground(mPSBackground);
+    }
+
+    private void initPF() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMin(Sampler.Value.LINEAR);
+        bs.setMag(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.CLAMP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        mSampler = bs.create();
+
+        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
+        b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+                     ProgramFragment.Builder.Format.RGBA, 0);
+        mPFBackground = b.create();
+        mPFBackground.bindSampler(mSampler, 0);
+
+        mScript.set_gPFBackground(mPFBackground);
+    }
+
+    private void initPV() {
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        mPVBackground = pvb.create();
+
+        mPVA = new ProgramVertex.MatrixAllocation(mRS);
+        mPVBackground.bindAllocation(mPVA);
+        mPVA.setupProjectionNormalized(mWidth, mHeight);
+
+        mScript.set_gPVBackground(mPVBackground);
+    }
+
+    private void loadImage() {
+        mGridImage = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.robot, Element.RGB_565(mRS), true);
+        mGridImage.uploadToTexture(0);
+
+        mScript.set_gTGrid(mGridImage);
+    }
+
+    private void initTextAllocation() {
+        String allocString = "Displaying file: R.raw.robot";
+        mTextAlloc = Allocation.createFromString(mRS, allocString);
+        mScript.set_gTextAlloc(mTextAlloc);
+    }
+
+    SgTransform mRootTransform;
+    SgTransform mGroup1;
+
+    SgTransform mRobot1;
+    SgTransform mRobot2;
+
+    void initTransformHierarchy() {
+        mRootTransform = new SgTransform(mRS);
+
+        mGroup1 = new SgTransform(mRS);
+        mRootTransform.addChild(mGroup1);
+
+        mRobot1 = new SgTransform(mRS);
+        mRobot2 = new SgTransform(mRS);
+
+        mGroup1.addChild(mRobot1);
+        mGroup1.addChild(mRobot2);
+
+        mGroup1.setTransform(0, new Float4(0.0f, 0.0f, 5.0f, 0.0f), TransformType.TRANSLATE);
+        mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE);
+
+        mRobot1.setTransform(0, new Float4(-2.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
+        mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE);
+        mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE);
+
+        mRobot2.setTransform(0, new Float4(2.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
+        mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE);
+        mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE);
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_Scenegraph(mRS, mRes, R.raw.scenegraph, true);
+        mTransformScript = new ScriptC_Transform(mRS, mRes, R.raw.transform, false);
+        mTransformScript.set_transformScript(mTransformScript);
+
+        mScript.set_gTransformRS(mTransformScript);
+
+        initPFS();
+        initPF();
+        initPV();
+
+        loadImage();
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+            Log.e("rs", "could not load model");
+        }
+        else {
+            mMesh = (Mesh)entry.getObject();
+            mScript.set_gTestMesh(mMesh);
+        }
+
+        mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+        mScript.set_gItalic(mItalic);
+
+        initTextAllocation();
+
+        initTransformHierarchy();
+
+        Log.v("========SceneGraph========", "transform hierarchy initialized");
+
+        mScript.bind_gRootNode(mRootTransform.getField());
+
+        mScript.bind_gGroup(mGroup1.mParent.mChildField);
+        mScript.bind_gRobot1(mRobot1.mParent.mChildField);
+        mScript.set_gRobot1Index(mRobot1.mIndexInParentGroup);
+        mScript.bind_gRobot2(mRobot2.mParent.mChildField);
+        mScript.set_gRobot2Index(mRobot2.mIndexInParentGroup);
+
+        mRS.contextBindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
new file mode 100644
index 0000000..ae94869
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+package com.android.scenegraph;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class SceneGraphView extends RSSurfaceView {
+
+    public SceneGraphView(Context context) {
+        super(context);
+        //setFocusable(true);
+    }
+
+    private RenderScriptGL mRS;
+    private SceneGraphRS mRender;
+
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        if (mRS == null) {
+            mRS = createRenderScript(true);
+            mRS.contextSetSurface(w, h, holder.getSurface());
+            mRender = new SceneGraphRS();
+            mRender.init(mRS, getResources(), w, h);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if(mRS != null) {
+            mRS = null;
+            destroyRenderScript();
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event)
+    {
+        // break point at here
+        // this method doesn't work when 'extends View' include 'extends ScrollView'.
+        return super.onKeyDown(keyCode, event);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        boolean ret = true;
+        int act = ev.getAction();
+        if (act == ev.ACTION_UP) {
+            ret = false;
+        }
+
+        mRender.touchEvent((int)ev.getX(), (int)ev.getY());
+        return ret;
+    }
+}
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
new file mode 100644
index 0000000..e81f1a7
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+package com.android.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+enum TransformType {
+
+    NONE(0),
+    TRANSLATE(1),
+    ROTATE(2),
+    SCALE(3);
+
+    int mID;
+    TransformType(int id) {
+        mID = id;
+    }
+}
+
+public class SgTransform {
+
+
+    ScriptField_SgTransform mTransformField;
+    ScriptField_SgTransform mChildField;
+    public ScriptField_SgTransform.Item mTransformData;
+
+    Float4[] mTransforms;
+    TransformType[] mTransformTypes;
+
+    RenderScript mRS;
+
+    Vector mChildren;
+    SgTransform mParent;
+    int mIndexInParentGroup;
+
+    public void setParent(SgTransform parent, int parentIndex) {
+        mParent = parent;
+        mIndexInParentGroup = parentIndex;
+    }
+
+    public void addChild(SgTransform child) {
+        mChildren.add(child);
+        child.setParent(this, mChildren.size() - 1);
+    }
+
+    public void setTransform(int index, Float4 value, TransformType type) {
+        mTransforms[index] = value;
+        mTransformTypes[index] = type;
+    }
+
+    void initData() {
+        int numTransforms = 16;
+        mTransforms = new Float4[numTransforms];
+        mTransformTypes = new TransformType[numTransforms];
+        for(int i = 0; i < numTransforms; i ++) {
+            mTransforms[i] = new Float4(0, 0, 0, 0);
+            mTransformTypes[i] = TransformType.NONE;
+        }
+    }
+
+    void setData() {
+
+        mTransformData.globalMat_Row0 = new Float4(1, 0, 0, 0);
+        mTransformData.globalMat_Row1 = new Float4(0, 1, 0, 0);
+        mTransformData.globalMat_Row2 = new Float4(0, 0, 1, 0);
+        mTransformData.globalMat_Row3 = new Float4(0, 0, 0, 1);
+
+        mTransformData.localMat_Row0 = new Float4(1, 0, 0, 0);
+        mTransformData.localMat_Row1 = new Float4(0, 1, 0, 0);
+        mTransformData.localMat_Row2 = new Float4(0, 0, 1, 0);
+        mTransformData.localMat_Row3 = new Float4(0, 0, 0, 1);
+
+        mTransformData.transforms0 = mTransforms[0];
+        mTransformData.transforms1 = mTransforms[1];
+        mTransformData.transforms2 = mTransforms[2];
+        mTransformData.transforms3 = mTransforms[3];
+        mTransformData.transforms4 = mTransforms[4];
+        mTransformData.transforms5 = mTransforms[5];
+        mTransformData.transforms6 = mTransforms[6];
+        mTransformData.transforms7 = mTransforms[7];
+        mTransformData.transforms8 = mTransforms[8];
+        mTransformData.transforms9 = mTransforms[9];
+        mTransformData.transforms10 = mTransforms[10];
+        mTransformData.transforms11 = mTransforms[11];
+        mTransformData.transforms12 = mTransforms[12];
+        mTransformData.transforms13 = mTransforms[13];
+        mTransformData.transforms14 = mTransforms[14];
+        mTransformData.transforms15 = mTransforms[15];
+
+        mTransformData.transformType0 = mTransformTypes[0].mID;
+        mTransformData.transformType1 = mTransformTypes[1].mID;
+        mTransformData.transformType2 = mTransformTypes[2].mID;
+        mTransformData.transformType3 = mTransformTypes[3].mID;
+        mTransformData.transformType4 = mTransformTypes[4].mID;
+        mTransformData.transformType5 = mTransformTypes[5].mID;
+        mTransformData.transformType6 = mTransformTypes[6].mID;
+        mTransformData.transformType7 = mTransformTypes[7].mID;
+        mTransformData.transformType8 = mTransformTypes[8].mID;
+        mTransformData.transformType9 = mTransformTypes[9].mID;
+        mTransformData.transformType10 = mTransformTypes[10].mID;
+        mTransformData.transformType11 = mTransformTypes[11].mID;
+        mTransformData.transformType12 = mTransformTypes[12].mID;
+        mTransformData.transformType13 = mTransformTypes[13].mID;
+        mTransformData.transformType14 = mTransformTypes[14].mID;
+        mTransformData.transformType15 = mTransformTypes[15].mID;
+
+        mTransformData.isDirty = 1;
+        mTransformData.children = null;
+
+    }
+
+    public SgTransform(RenderScript rs) {
+        mRS = rs;
+        mTransformData = new ScriptField_SgTransform.Item();
+        mChildren = new Vector();
+        initData();
+    }
+
+    public ScriptField_SgTransform.Item getData() {
+        setData();
+        if(mChildren.size() != 0) {
+            mChildField = new ScriptField_SgTransform(mRS, mChildren.size());
+            mTransformData.children = mChildField.getAllocation();
+
+            for(int i = 0; i < mChildren.size(); i ++) {
+                SgTransform child = (SgTransform)mChildren.get(i);
+                mChildField.set(child.getData(), i, false);
+            }
+            mChildField.copyAll();
+        }
+
+        return mTransformData;
+    }
+
+    public ScriptField_SgTransform getField() {
+        mTransformField = new ScriptField_SgTransform(mRS, 1);
+        mTransformField.set(getData(), 0, true);
+        return mTransformField;
+    }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
new file mode 100644
index 0000000..e6ae6df
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
@@ -0,0 +1,92 @@
+// Copyright (C) 2009 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)
+
+#include "rs_graphics.rsh"
+#include "transform_def.rsh"
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gTGrid;
+rs_mesh gTestMesh;
+
+rs_program_store gPFSBackground;
+
+float gRotate;
+
+rs_font gItalic;
+rs_allocation gTextAlloc;
+
+rs_script gTransformRS;
+
+SgTransform *gGroup;
+SgTransform *gRobot1;
+int gRobot1Index;
+SgTransform *gRobot2;
+int gRobot2Index;
+
+SgTransform *gRootNode;
+
+#pragma rs export_var(gPVBackground, gPFBackground, gTGrid, gTestMesh, gPFSBackground, gRotate, gItalic, gTextAlloc, gTransformRS, gGroup, gRobot1, gRobot1Index, gRobot2, gRobot2Index, gRootNode)
+
+float gDT;
+int64_t gLastTime;
+
+void init() {
+    gRotate = 0.0f;
+}
+
+int root(int launchID) {
+
+    gGroup->transforms1.w += 0.5f;
+    gGroup->isDirty = 1;
+
+    SgTransform *robot1Ptr = gRobot1 + gRobot1Index;
+
+    robot1Ptr->transforms1.w -= 1.5f;
+    robot1Ptr->isDirty = 1;
+
+    SgTransform *robot2Ptr = gRobot2 + gRobot2Index;
+    robot2Ptr->transforms1.w += 2.5f;
+    robot2Ptr->isDirty = 1;
+
+    rsForEach(gTransformRS, gRootNode->children, gRootNode->children, 0);
+
+    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgClearDepth(1.0f);
+
+    rsgBindProgramVertex(gPVBackground);
+
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindProgramStore(gPFSBackground);
+    rsgBindTexture(gPFBackground, 0, gTGrid);
+
+    rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot1Ptr->globalMat_Row0);
+    rsgDrawMesh(gTestMesh);
+
+    rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot2Ptr->globalMat_Row0);
+    rsgDrawMesh(gTestMesh);
+
+    color(0.3f, 0.3f, 0.3f, 1.0f);
+    rsgDrawText("Renderscript transform test", 30, 695);
+
+    rsgBindFont(gItalic);
+    rsgDrawText(gTextAlloc, 30, 730);
+
+    return 10;
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
new file mode 100644
index 0000000..a62d12b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -0,0 +1,102 @@
+// Copyright (C) 2009 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)
+
+#include "transform_def.rsh"
+
+rs_script transformScript;
+
+#pragma rs export_var(transformScript)
+
+typedef struct {
+    int changed;
+    rs_matrix4x4 *mat;
+} ParentData;
+
+void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
+    rs_matrix4x4 temp;
+
+    switch(type) {
+    case TRANSFORM_TRANSLATE:
+        rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
+        break;
+    case TRANSFORM_ROTATE:
+        rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
+        break;
+    case TRANSFORM_SCALE:
+        rsMatrixLoadScale(&temp, data.x, data.y, data.z);
+        break;
+    }
+    rsMatrixMultiply(mat, &temp);
+}
+
+void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
+
+    SgTransform *data = (SgTransform *)v_out;
+    const ParentData *parent = (const ParentData *)usrData;
+
+    //rsDebug("Transform data", (int)data);
+    //rsDebug("Entering parent", (int)parent);
+
+    rs_matrix4x4 *localMat = (rs_matrix4x4*)&data->localMat_Row0;
+    rs_matrix4x4 *globalMat = (rs_matrix4x4*)&data->globalMat_Row0;
+
+    ParentData toChild;
+    toChild.changed = 0;
+    toChild.mat = globalMat;
+
+    //rsDebug("Transform is dirty", data->isDirty);
+
+    // Refresh matrices if dirty
+    if(data->isDirty) {
+        data->isDirty = 0;
+        toChild.changed = 1;
+
+        // Reset our local matrix
+        rsMatrixLoadIdentity(localMat);
+
+        float4 *transformSource = &data->transforms0;
+        int *transformTypes = &data->transformType0;
+
+        for(int i = 0; i < 16; i ++) {
+            if(transformTypes[i] == TRANSFORM_NONE) {
+                break;
+            }
+            //rsDebug("Transform adding transformation", transformTypes[i]);
+            appendTransformation(transformTypes[i], transformSource[i], localMat);
+        }
+    }
+
+    //rsDebug("Transform checking parent", (int)0);
+
+    if(parent) {
+        if(parent->changed) {
+            toChild.changed = 1;
+
+            rsMatrixLoad(globalMat, parent->mat);
+            rsMatrixMultiply(globalMat, localMat);
+        }
+    }
+    else {
+        rsMatrixLoad(globalMat, localMat);
+    }
+
+    //rsDebug("Transform calling self with child ", (int)data->children.p);
+    if(data->children.p) {
+        rsForEach(transformScript, data->children, data->children, (void*)&toChild);
+    }
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
new file mode 100644
index 0000000..10aac37
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
@@ -0,0 +1,73 @@
+// Copyright (C) 2009 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 TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+typedef struct {
+    float4 globalMat_Row0;
+    float4 globalMat_Row1;
+    float4 globalMat_Row2;
+    float4 globalMat_Row3;
+
+    float4 localMat_Row0;
+    float4 localMat_Row1;
+    float4 localMat_Row2;
+    float4 localMat_Row3;
+
+    float4 transforms0;
+    float4 transforms1;
+    float4 transforms2;
+    float4 transforms3;
+    float4 transforms4;
+    float4 transforms5;
+    float4 transforms6;
+    float4 transforms7;
+    float4 transforms8;
+    float4 transforms9;
+    float4 transforms10;
+    float4 transforms11;
+    float4 transforms12;
+    float4 transforms13;
+    float4 transforms14;
+    float4 transforms15;
+
+    int transformType0;
+    int transformType1;
+    int transformType2;
+    int transformType3;
+    int transformType4;
+    int transformType5;
+    int transformType6;
+    int transformType7;
+    int transformType8;
+    int transformType9;
+    int transformType10;
+    int transformType11;
+    int transformType12;
+    int transformType13;
+    int transformType14;
+    int transformType15;
+
+    int isDirty;
+
+    rs_allocation children;
+
+} SgTransform;