diff --git a/tools/a3dconvert/Android.mk b/tools/a3dconvert/Android.mk
new file mode 100644
index 0000000..7bc634e
--- /dev/null
+++ b/tools/a3dconvert/Android.mk
@@ -0,0 +1,40 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# Host executable
+include $(CLEAR_VARS)
+LOCAL_MODULE := a3dconvert
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -DANDROID_RS_SERIALIZE
+# Needed for colladaDom
+LOCAL_CFLAGS += -DNO_BOOST -DDOM_INCLUDE_TINYXML -DNO_ZAE
+
+LOCAL_SRC_FILES := \
+    a3dconvert.cpp \
+    ObjLoader.cpp \
+    ColladaConditioner.cpp \
+    ColladaGeometry.cpp \
+    ColladaLoader.cpp
+
+
+LOCAL_C_INCLUDES += external/collada/include
+LOCAL_C_INCLUDES += external/collada/include/1.4
+LOCAL_C_INCLUDES += frameworks/base/libs/rs
+
+LOCAL_LDLIBS := -lpthread
+LOCAL_STATIC_LIBRARIES += libRSserialize libutils libcutils
+LOCAL_STATIC_LIBRARIES += colladadom libtinyxml libpcrecpp libpcre
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/a3dconvert/ColladaConditioner.cpp b/tools/a3dconvert/ColladaConditioner.cpp
new file mode 100644
index 0000000..0b0f694
--- /dev/null
+++ b/tools/a3dconvert/ColladaConditioner.cpp
@@ -0,0 +1,203 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#include "ColladaConditioner.h"
+unsigned int ColladaConditioner::getMaxOffset( domInputLocalOffset_Array &input_array ) {
+
+    unsigned int maxOffset = 0;
+    for ( unsigned int i = 0; i < input_array.getCount(); i++ ) {
+        if ( input_array[i]->getOffset() > maxOffset ) {
+            maxOffset = (unsigned int)input_array[i]->getOffset();
+        }
+    }
+    return maxOffset;
+}
+
+void ColladaConditioner::createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist ) {
+
+    // Create a new <triangles> inside the mesh that has the same material as the <polylist>
+    domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
+    //thisTriangles->setCount( 0 );
+    unsigned int triangles = 0;
+    thisTriangles->setMaterial(thisPolylist->getMaterial());
+    domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
+
+    // Give the new <triangles> the same <_dae> and <parameters> as the old <polylist>
+    for(int i=0; i<(int)(thisPolylist->getInput_array().getCount()); i++) {
+
+        thisTriangles->placeElement( thisPolylist->getInput_array()[i]->clone() );
+    }
+
+    // Get the number of inputs and primitives for the polygons array
+    int numberOfInputs = (int)getMaxOffset(thisPolylist->getInput_array()) + 1;
+    int numberOfPrimitives = (int)(thisPolylist->getVcount()->getValue().getCount());
+
+    unsigned int offset = 0;
+
+    // Triangulate all the primitives, this generates all the triangles in a single <p> element
+    for(int j = 0; j < numberOfPrimitives; j++) {
+
+        int triangleCount = (int)thisPolylist->getVcount()->getValue()[j] -2;
+        // Write out the primitives as triangles, just fan using the first element as the base
+        int idx = numberOfInputs;
+        for(int k = 0; k < triangleCount; k++) {
+            // First vertex
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + l]);
+            }
+            // Second vertex
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
+            }
+            // Third vertex
+            idx += numberOfInputs;
+            for(int l = 0; l < numberOfInputs; l++) {
+
+                p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
+            }
+            triangles++;
+        }
+        offset += (unsigned int)thisPolylist->getVcount()->getValue()[j] * numberOfInputs;
+    }
+    thisTriangles->setCount( triangles );
+
+}
+
+void ColladaConditioner::createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons ) {
+
+    // Create a new <triangles> inside the mesh that has the same material as the <polygons>
+    domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
+    thisTriangles->setCount( 0 );
+    thisTriangles->setMaterial(thisPolygons->getMaterial());
+    domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
+
+    // Give the new <triangles> the same <_dae> and <parameters> as the old <polygons>
+    for(int i=0; i<(int)(thisPolygons->getInput_array().getCount()); i++) {
+
+        thisTriangles->placeElement( thisPolygons->getInput_array()[i]->clone() );
+    }
+
+    // Get the number of inputs and primitives for the polygons array
+    int numberOfInputs = (int)getMaxOffset(thisPolygons->getInput_array()) +1;
+    int numberOfPrimitives = (int)(thisPolygons->getP_array().getCount());
+
+    // Triangulate all the primitives, this generates all the triangles in a single <p> element
+    for(int j = 0; j < numberOfPrimitives; j++) {
+
+        // Check the polygons for consistancy (some exported files have had the wrong number of indices)
+        domP * thisPrimitive = thisPolygons->getP_array()[j];
+        int elementCount = (int)(thisPrimitive->getValue().getCount());
+        // Skip the invalid primitive
+        if((elementCount % numberOfInputs) != 0) {
+            continue;
+        } else {
+            int triangleCount = (elementCount/numberOfInputs)-2;
+            // Write out the primitives as triangles, just fan using the first element as the base
+            int idx = numberOfInputs;
+            for(int k = 0; k < triangleCount; k++) {
+                // First vertex
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[l]);
+                }
+                // Second vertex
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
+                }
+                // Third vertex
+                idx += numberOfInputs;
+                for(int l = 0; l < numberOfInputs; l++) {
+
+                    p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
+                }
+                thisTriangles->setCount(thisTriangles->getCount()+1);
+            }
+        }
+    }
+
+}
+
+
+bool ColladaConditioner::triangulate(DAE *dae) {
+
+    int error = 0;
+
+    // How many geometry elements are there?
+    int geometryElementCount = (int)(dae->getDatabase()->getElementCount(NULL, "geometry" ));
+
+    for(int currentGeometry = 0; currentGeometry < geometryElementCount; currentGeometry++) {
+
+        // Find the next geometry element
+        domGeometry *thisGeometry;
+        //      error = _dae->getDatabase()->getElement((daeElement**)&thisGeometry,currentGeometry, NULL, "geometry");
+        daeElement * element = 0;
+        error = dae->getDatabase()->getElement(&element,currentGeometry, NULL, "geometry");
+        thisGeometry = (domGeometry *) element;
+
+        // Get the mesh out of the geometry
+        domMesh *thisMesh = thisGeometry->getMesh();
+
+        if (thisMesh == NULL){
+            continue;
+        }
+
+        // Loop over all the polygon elements
+        for(int currentPolygons = 0; currentPolygons < (int)(thisMesh->getPolygons_array().getCount()); currentPolygons++) {
+
+            // Get the polygons out of the mesh
+            // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
+            domPolygons *thisPolygons = thisMesh->getPolygons_array()[currentPolygons];
+            createTrianglesFromPolygons( thisMesh, thisPolygons );
+        }
+        while (thisMesh->getPolygons_array().getCount() > 0) {
+
+            domPolygons *thisPolygons = thisMesh->getPolygons_array().get(0);
+            // Remove the polygons from the mesh
+            thisMesh->removeChildElement(thisPolygons);
+        }
+        int polylistElementCount = (int)(thisMesh->getPolylist_array().getCount());
+        for(int currentPolylist = 0; currentPolylist < polylistElementCount; currentPolylist++) {
+
+            // Get the polylist out of the mesh
+            // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
+            domPolylist *thisPolylist = thisMesh->getPolylist_array()[currentPolylist];
+            createTrianglesFromPolylist( thisMesh, thisPolylist );
+        }
+        while (thisMesh->getPolylist_array().getCount() > 0) {
+
+            domPolylist *thisPolylist = thisMesh->getPolylist_array().get(0);
+            // Remove the polylist from the mesh
+            thisMesh->removeChildElement(thisPolylist);
+        }
+    }
+    return (error == 0);
+}
+
+bool ColladaConditioner::triangulate(const char *inputFile) {
+
+    DAE dae;
+    bool convertSuceeded = true;
+    domCOLLADA* root = dae.open(inputFile);
+
+    if (!root) {
+        printf("Failed to read file %s.\n", inputFile);
+        return false;
+    }
+
+    convertSuceeded = triangulate(&dae);
+
+    dae.writeAll();
+    if(!convertSuceeded) {
+        printf("Encountered errors\n");
+    }
+
+    return convertSuceeded;
+}
\ No newline at end of file
diff --git a/tools/a3dconvert/ColladaConditioner.h b/tools/a3dconvert/ColladaConditioner.h
new file mode 100644
index 0000000..470b7b6
--- /dev/null
+++ b/tools/a3dconvert/ColladaConditioner.h
@@ -0,0 +1,28 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#ifndef COLLADA_CONDITIONER
+#define COLLADA_CONDITIONER
+
+#include <dae.h>
+#include <dom/domConstants.h>
+#include <dom/domCOLLADA.h>
+
+class ColladaConditioner {
+
+private:
+    unsigned int getMaxOffset( domInputLocalOffset_Array &input_array );
+    void createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist );
+    void createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons );
+
+public:
+    bool triangulate(DAE *dae);
+    bool triangulate(const char *inputFile);
+};
+
+#endif //COLLADA_CONDITIONER
diff --git a/tools/a3dconvert/ColladaGeometry.cpp b/tools/a3dconvert/ColladaGeometry.cpp
new file mode 100644
index 0000000..1aba4f1
--- /dev/null
+++ b/tools/a3dconvert/ColladaGeometry.cpp
@@ -0,0 +1,319 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#include "ColladaGeometry.h"
+#include <iostream>
+#include <sstream>
+
+ColladaGeometry::ColladaGeometry() :
+        mPositionFloats(NULL), mPositionOffset(-1),
+        mNormalFloats(NULL), mNormalOffset(-1),
+        mTangentFloats(NULL), mTangentOffset(-1),
+        mBinormalFloats(NULL), mBinormalOffset(-1),
+        mTexture1Floats(NULL), mTexture1Offset(-1),
+        mMultiIndexOffset(-1),
+        mPositionsStride(3), mNormalsStride(3),
+        mTextureCoordsStride(2), mTangentssStride(3), mBinormalsStride(3) {
+
+    mConvertedMesh.appendChannel("position", mPositionsStride);
+    mConvertedMesh.appendChannel("normal", mNormalsStride);
+    mConvertedMesh.appendChannel("texture0", mTextureCoordsStride);
+    mConvertedMesh.appendChannel("binormal", mBinormalsStride);
+    mConvertedMesh.appendChannel("tangent", mTangentssStride);
+
+    mPositions = &mConvertedMesh.mChannels[0].mData;
+    mNormals = &mConvertedMesh.mChannels[1].mData;
+    mTextureCoords = &mConvertedMesh.mChannels[2].mData;
+    mBinormals = &mConvertedMesh.mChannels[3].mData;
+    mTangents = &mConvertedMesh.mChannels[4].mData;
+}
+
+bool ColladaGeometry::init(domGeometryRef geometry) {
+
+    bool convertSuceeded = true;
+
+    const char* geoName = geometry->getName();
+    if (geoName == NULL) {
+        geoName = geometry->getId();
+    }
+    mConvertedMesh.mName = geoName;
+    mMesh = geometry->getMesh();
+
+    // Iterate over all the index groups and build up a simple resolved tri list and vertex array
+    const domTriangles_Array &allTriLists = mMesh->getTriangles_array();
+    int numTriLists = allTriLists.getCount();
+    mConvertedMesh.mTriangleLists.reserve(numTriLists);
+    mConvertedMesh.mTriangleListNames.reserve(numTriLists);
+    for (int i = 0; i < numTriLists; i ++) {
+        addTriangles(allTriLists[i]);
+    }
+
+    return convertSuceeded;
+}
+
+void ColladaGeometry::addTriangles(domTriangles * colladaTriangles) {
+
+    int numTriangles = colladaTriangles->getCount();
+    int triListIndex = mConvertedMesh.mTriangleLists.size();
+    mConvertedMesh.mTriangleLists.resize(triListIndex + 1);
+    std::string materialName = colladaTriangles->getMaterial();
+    if (materialName.size() == 0) {
+        char buffer[128];
+        sprintf(buffer, "index%d", triListIndex);
+        materialName = buffer;
+    }
+    mConvertedMesh.mTriangleListNames.push_back(materialName);
+
+    // It's a good idea to tell stl how much memory we intend to use
+    // to limit the number of reallocations
+    mPositions->reserve(numTriangles * 3);
+    mNormals->reserve(numTriangles * 3);
+    mTangents->reserve(numTriangles * 3);
+    mBinormals->reserve(numTriangles * 3);
+    mTextureCoords->reserve(numTriangles * 3);
+
+    // Stores the pointers to the image data and where in the tri list that data comes from
+    cacheOffsetsAndDataPointers(colladaTriangles);
+
+    // Collapse the multiindex that collada uses
+    const domListOfUInts &colladaIndexList = colladaTriangles->getP()->getValue();
+    std::vector<uint32_t> &a3dIndexList = mConvertedMesh.mTriangleLists[triListIndex];
+    a3dIndexList.resize(numTriangles * 3);
+    for (int i = 0; i < numTriangles * 3; i ++) {
+
+        a3dIndexList[i] = remapIndexAndStoreData(colladaIndexList, i);
+    }
+
+}
+
+void ColladaGeometry::cacheOffsetsAndDataPointers(domTriangles * colladaTriangles) {
+    // Define the names of known vertex channels
+    const char *positionSemantic = "POSITION";
+    const char *vertexSemantic = "VERTEX";
+    const char *normalSemantic = "NORMAL";
+    const char *tangentSemantic = "TANGENT";
+    const char *binormalSemantic = "BINORMAL";
+    const char *texture1Semantic = "TEXCOORD";
+
+    const domInputLocalOffset_Array &inputs = colladaTriangles->getInput_array();
+    mMultiIndexOffset = inputs.getCount();
+
+    // inputs with offsets
+    // There are two places collada can put links to our data
+    // 1 - in the VERTEX, which is its way of saying follow a link to the vertex structure
+    //     then every geometry array you find there is the same size as the position array
+    // 2 - a direct link to the channel from the primitive list. This tells us that there are
+    //     potentially more or less floats in those channels because there is some vertex re-use
+    //     or divergence in that data channel. For example, highly segmented uv set would produce a
+    //     larger array because for every physical vertex position thre might be 2 or more uv coords
+    for (uint32_t i = 0; i < inputs.getCount(); i ++) {
+
+        int currentOffset = inputs[i]->getOffset();
+        const char *currentSemantic = inputs[i]->getSemantic();
+
+        domSource * source = (domSource*) (domElement*) inputs[i]->getSource().getElement();
+        if (strcmp(vertexSemantic, currentSemantic) == 0) {
+            mPositionOffset = currentOffset;
+        }
+        else if (strcmp(normalSemantic, currentSemantic) == 0) {
+            mNormalOffset = currentOffset;
+            mNormalFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(tangentSemantic, currentSemantic) == 0) {
+            mTangentOffset = currentOffset;
+            mTangentFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(binormalSemantic, currentSemantic) == 0) {
+            mBinormalOffset = currentOffset;
+            mBinormalFloats = &source->getFloat_array()->getValue();
+        }
+        else if (strcmp(texture1Semantic, currentSemantic) == 0) {
+            mTexture1Offset = currentOffset;
+            mTexture1Floats = & source->getFloat_array()->getValue();
+        }
+    }
+
+    // There are multiple ways of getting to data, so follow them all
+    domVertices * vertices = mMesh->getVertices();
+    const domInputLocal_Array &verticesInputs = vertices->getInput_array();
+    for (uint32_t i = 0; i < verticesInputs.getCount(); i ++) {
+
+        const char *currentSemantic = verticesInputs[i]->getSemantic();
+
+        domSource * source = (domSource*) (domElement*) verticesInputs[i]->getSource().getElement();
+        if (strcmp(positionSemantic, currentSemantic) == 0) {
+            mPositionFloats = & source->getFloat_array()->getValue();
+            // TODO: Querry this from the accessor in the future because
+            // I supopose it's possible to have 4 floats if we hide something in w
+            int numberOfFloatsPerPoint = 3;
+            // We want to cllapse duplicate vertices, otherwise we could just unroll the tri list
+            mVertexRemap.resize(source->getFloat_array()->getCount()/numberOfFloatsPerPoint);
+        }
+        else if (strcmp(normalSemantic, currentSemantic) == 0) {
+            mNormalFloats = & source->getFloat_array()->getValue();
+            mNormalOffset = mPositionOffset;
+        }
+        else if (strcmp(tangentSemantic, currentSemantic) == 0) {
+            mTangentFloats = & source->getFloat_array()->getValue();
+            mTangentOffset = mPositionOffset;
+        }
+        else if (strcmp(binormalSemantic, currentSemantic) == 0) {
+            mBinormalFloats = & source->getFloat_array()->getValue();
+            mBinormalOffset = mPositionOffset;
+        }
+        else if (strcmp(texture1Semantic, currentSemantic) == 0) {
+            mTexture1Floats = & source->getFloat_array()->getValue();
+            mTexture1Offset = mPositionOffset;
+        }
+    }
+}
+
+int ColladaGeometry::remapIndexAndStoreData(const domListOfUInts &colladaIndexList, int indexToRemap) {
+
+    domUint positionIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mPositionOffset];
+
+    float posX = (*mPositionFloats)[positionIndex * mPositionsStride + 0];
+    float posY = (*mPositionFloats)[positionIndex * mPositionsStride + 1];
+    float posZ = (*mPositionFloats)[positionIndex * mPositionsStride + 2];
+
+    float normX = 0;
+    float normY = 0;
+    float normZ = 0;
+
+    if (mNormalOffset != -1) {
+        domUint normalIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mNormalOffset];
+        normX = (*mNormalFloats)[normalIndex * mNormalsStride + 0];
+        normY = (*mNormalFloats)[normalIndex * mNormalsStride + 1];
+        normZ = (*mNormalFloats)[normalIndex * mNormalsStride + 2];
+    }
+
+    float tanX = 0;
+    float tanY = 0;
+    float tanZ = 0;
+
+    if (mTangentOffset != -1) {
+        domUint tangentIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mTangentOffset];
+        tanX = (*mTangentFloats)[tangentIndex * mTangentssStride + 0];
+        tanY = (*mTangentFloats)[tangentIndex * mTangentssStride + 1];
+        tanZ = (*mTangentFloats)[tangentIndex * mTangentssStride + 2];
+    }
+
+    float binormX = 0;
+    float binormY = 0;
+    float binormZ = 0;
+
+    if (mBinormalOffset != -1) {
+        domUint binormalIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mNormalOffset];
+        binormX = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 0];
+        binormY = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 1];
+        binormZ = (*mBinormalFloats)[binormalIndex * mBinormalsStride + 2];
+    }
+
+    float texCoordX = 0;
+    float texCoordY = 0;
+
+    if (mTexture1Offset != -1) {
+        domUint texCoordIndex = colladaIndexList[indexToRemap*mMultiIndexOffset + mTexture1Offset];
+        texCoordX = (*mTexture1Floats)[texCoordIndex * mTextureCoordsStride + 0];
+        texCoordY = (*mTexture1Floats)[texCoordIndex * mTextureCoordsStride + 1];
+    }
+
+    std::vector<uint32_t> &ithRemapList = mVertexRemap[positionIndex];
+    // We may have some potential vertices we can reuse
+    // loop over all the potential candidates and see if any match our guy
+    for (uint32_t i = 0; i < ithRemapList.size(); i ++) {
+
+        int ithRemap = ithRemapList[i];
+        // compare existing vertex with the new one
+        if ((*mPositions)[ithRemap * mPositionsStride + 0] != posX ||
+            (*mPositions)[ithRemap * mPositionsStride + 1] != posY ||
+            (*mPositions)[ithRemap * mPositionsStride + 2] != posZ) {
+            continue;
+        }
+
+        // Now go over normals
+        if (mNormalOffset != -1) {
+            if ((*mNormals)[ithRemap * mNormalsStride + 0] != normX ||
+                (*mNormals)[ithRemap * mNormalsStride + 1] != normY ||
+                (*mNormals)[ithRemap * mNormalsStride + 2] != normZ) {
+                continue;
+            }
+        }
+
+        // Now go over tangents
+        if (mTangentOffset != -1) {
+            if ((*mTangents)[ithRemap * mTangentssStride + 0] != tanX ||
+                (*mTangents)[ithRemap * mTangentssStride + 1] != tanY ||
+                (*mTangents)[ithRemap * mTangentssStride + 2] != tanZ) {
+                continue;
+            }
+        }
+
+        // Now go over binormals
+        if (mBinormalOffset != -1) {
+            if ((*mBinormals)[ithRemap * mBinormalsStride + 0] != binormX ||
+                (*mBinormals)[ithRemap * mBinormalsStride + 1] != binormY ||
+                (*mBinormals)[ithRemap * mBinormalsStride + 2] != binormZ) {
+                continue;
+            }
+        }
+
+        // And texcoords
+        if (mTexture1Offset != -1) {
+            if ((*mTextureCoords)[ithRemap * mTextureCoordsStride + 0] != texCoordX ||
+                (*mTextureCoords)[ithRemap * mTextureCoordsStride + 1] != texCoordY) {
+               continue;
+            }
+        }
+
+        // If we got here the new vertex is identical to the one that we already stored
+        return ithRemap;
+    }
+
+    // We did not encounter this vertex yet, store it and return its index
+    mPositions->push_back(posX);
+    mPositions->push_back(posY);
+    mPositions->push_back(posZ);
+
+    if (mNormalOffset != -1) {
+        mNormals->push_back(normX);
+        mNormals->push_back(normY);
+        mNormals->push_back(normZ);
+    }
+
+    if (mTangentOffset != -1) {
+        mTangents->push_back(tanX);
+        mTangents->push_back(tanY);
+        mTangents->push_back(tanZ);
+    }
+
+    if (mBinormalOffset != -1) {
+        mBinormals->push_back(binormX);
+        mBinormals->push_back(binormY);
+        mBinormals->push_back(binormZ);
+    }
+
+    if (mTexture1Offset != -1) {
+        mTextureCoords->push_back(texCoordX);
+        mTextureCoords->push_back(texCoordY);
+    }
+
+    // We need to remember this mapping. Since we are storing floats, not vec3's, need to
+    // divide by position size to get the right index
+    int currentVertexIndex = (mPositions->size()/mPositionsStride) - 1;
+    ithRemapList.push_back(currentVertexIndex);
+
+    return currentVertexIndex;
+}
+
+
+
+
+
+
+
diff --git a/tools/a3dconvert/ColladaGeometry.h b/tools/a3dconvert/ColladaGeometry.h
new file mode 100644
index 0000000..5774997
--- /dev/null
+++ b/tools/a3dconvert/ColladaGeometry.h
@@ -0,0 +1,84 @@
+/*
+* Copyright 2006 Sony Computer Entertainment Inc.
+*
+* Licensed under the MIT Open Source License, for details please see license.txt or the website
+* http://www.opensource.org/licenses/mit-license.php
+*
+*/
+
+#ifndef _COLLADA_GEOMETRY_H_
+#define _COLLADA_GEOMETRY_H_
+
+#include <dae.h>
+#include <dom/domCOLLADA.h>
+#include <vector>
+#include <string>
+
+#include "rsContext.h"
+#include "rsMesh.h"
+#include "SimpleMesh.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+class ColladaGeometry {
+public:
+    ColladaGeometry();
+    bool init(domGeometryRef geometry);
+
+    Mesh *getMesh(Context *rsc) {
+        return mConvertedMesh.getMesh(rsc);
+    }
+
+private:
+
+    //Store some collada stuff
+    domMesh *mMesh;
+
+    // Cache the pointers to the collada version of the data
+    // This contains raw vertex data that is not necessarily the same size for all
+    // Offset refers to the way collada packs each triangle's index to position / normal / etc.
+    domListOfFloats *mPositionFloats;
+    int mPositionOffset;
+    domListOfFloats *mNormalFloats;
+    int mNormalOffset;
+    domListOfFloats *mTangentFloats;
+    int mTangentOffset;
+    domListOfFloats *mBinormalFloats;
+    int mBinormalOffset;
+    domListOfFloats *mTexture1Floats;
+    int mTexture1Offset;
+
+    // In the list of triangles, collada uses multiple indecies per triangle to point to the correct
+    // index in all the different arrays. We need to know the total number of these guys so we can
+    // just to the next triangle to process
+    int mMultiIndexOffset;
+
+    // All these vectors would contain the same number of "points"
+    // index*stride would properly get to the uv, normal etc.
+    // collada, like maya and many others keep point array, normal array etc
+    // different size in the cases the same vertex produces divergent normals for different faces
+    std::vector<float> *mPositions;
+    unsigned int mPositionsStride;
+    std::vector<float> *mNormals;
+    unsigned int mNormalsStride;
+    std::vector<float> *mTextureCoords;
+    unsigned int mTextureCoordsStride;
+    std::vector<float> *mTangents;
+    unsigned int mTangentssStride;
+    std::vector<float> *mBinormals;
+    unsigned int mBinormalsStride;
+
+    SimpleMesh mConvertedMesh;
+
+    // This vector is used to remap a position index into a list of all divergent vertices
+    std::vector<std::vector<unsigned int> > mVertexRemap;
+
+    void addTriangles(domTriangles * colladaTriangles);
+    void cacheOffsetsAndDataPointers(domTriangles * colladaTriangles);
+    int remapIndexAndStoreData(const domListOfUInts &colladaIndexList, int indexToRemap);
+
+};
+
+#endif //COLLADA_TO_A3D_GEOMETRY
diff --git a/tools/a3dconvert/ColladaLoader.cpp b/tools/a3dconvert/ColladaLoader.cpp
new file mode 100644
index 0000000..8a74748
--- /dev/null
+++ b/tools/a3dconvert/ColladaLoader.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#include "ColladaLoader.h"
+#include "ColladaConditioner.h"
+#include "ColladaGeometry.h"
+#include "rsContext.h"
+#include "rsFileA3D.h"
+
+#include <dae.h>
+#include <dom/domCOLLADA.h>
+
+ColladaLoader::ColladaLoader() {
+
+}
+
+ColladaLoader::~ColladaLoader() {
+    clearGeometry();
+}
+
+void ColladaLoader::clearGeometry() {
+    for (uint32_t i = 0; i < mGeometries.size(); i++) {
+        delete mGeometries[i];
+    }
+    mGeometries.clear();
+}
+
+bool ColladaLoader::init(const char *colladaFile) {
+    DAE dae;
+
+    clearGeometry();
+
+    bool convertSuceeded = true;
+
+    domCOLLADA* root = dae.open(colladaFile);
+    if (!root) {
+        fprintf(stderr, "Failed to read file %s.\n", colladaFile);
+        return false;
+    }
+
+    // We only want to deal with triangulated meshes since rendering complex polygons is not feasible
+    ColladaConditioner conditioner;
+    conditioner.triangulate(&dae);
+
+    domLibrary_geometries *allGeometry = daeSafeCast<domLibrary_geometries>(root->getDescendant("library_geometries"));
+
+    if (allGeometry) {
+        convertSuceeded = convertAllGeometry(allGeometry) && convertSuceeded;
+    }
+
+    return convertSuceeded;
+}
+
+bool ColladaLoader::convertToA3D(const char *a3dFile) {
+    if (mGeometries.size() == 0) {
+        return false;
+    }
+    // Now write all this stuff out
+    Context rsc;
+    FileA3D file(&rsc);
+
+    for (uint32_t i = 0; i < mGeometries.size(); i++) {
+        Mesh *exportedMesh = mGeometries[i]->getMesh(&rsc);
+        file.appendToFile(exportedMesh);
+        delete exportedMesh;
+    }
+
+    file.writeFile(a3dFile);
+    return true;
+}
+
+bool ColladaLoader::convertAllGeometry(domLibrary_geometries *allGeometry) {
+
+    bool convertSuceeded = true;
+    domGeometry_Array &geo_array = allGeometry->getGeometry_array();
+    for (size_t i = 0; i < geo_array.getCount(); i++) {
+        domGeometry *geometry = geo_array[i];
+        const char *geometryName = geometry->getName();
+        if (geometryName == NULL) {
+            geometryName = geometry->getId();
+        }
+
+        domMeshRef mesh = geometry->getMesh();
+        if (mesh != NULL) {
+            printf("Converting geometry: %s\n", geometryName);
+            convertSuceeded = convertGeometry(geometry) && convertSuceeded;
+        } else {
+            printf("Skipping geometry: %s, unsupported type\n", geometryName);
+        }
+
+    }
+
+    return convertSuceeded;
+}
+
+bool ColladaLoader::convertGeometry(domGeometry *geometry) {
+    bool convertSuceeded = true;
+
+    domMeshRef mesh = geometry->getMesh();
+
+    ColladaGeometry *convertedGeo = new ColladaGeometry();
+    convertedGeo->init(geometry);
+
+    mGeometries.push_back(convertedGeo);
+
+    return convertSuceeded;
+}
diff --git a/tools/a3dconvert/ColladaLoader.h b/tools/a3dconvert/ColladaLoader.h
new file mode 100644
index 0000000..aa66e7d
--- /dev/null
+++ b/tools/a3dconvert/ColladaLoader.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#ifndef _COLLADA_LOADER_H_
+#define _COLLADA_LOADER_H_
+
+#include <vector>
+
+class domLibrary_geometries;
+class domGeometry;
+class ColladaGeometry;
+
+class ColladaLoader {
+public:
+    ColladaLoader();
+    ~ColladaLoader();
+
+    bool init(const char *colladaFile);
+    bool convertToA3D(const char *a3dFile);
+
+private:
+    void clearGeometry();
+    std::vector<ColladaGeometry*> mGeometries;
+
+    bool convertAllGeometry(domLibrary_geometries *allGeometry);
+    bool convertGeometry(domGeometry *geometry);
+
+};
+
+#endif
\ No newline at end of file
diff --git a/tools/a3dconvert/ObjLoader.cpp b/tools/a3dconvert/ObjLoader.cpp
new file mode 100644
index 0000000..4465f4f
--- /dev/null
+++ b/tools/a3dconvert/ObjLoader.cpp
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+#include "ObjLoader.h"
+#include <rsFileA3D.h>
+#include <sstream>
+
+ObjLoader::ObjLoader() :
+    mPositionsStride(3), mNormalsStride(3), mTextureCoordsStride(2) {
+
+}
+
+bool isWhitespace(char c) {
+    const char whiteSpace[] = { ' ', '\n', '\t', '\f', '\r' };
+    const uint32_t numWhiteSpaceChars = 5;
+    for (uint32_t i = 0; i < numWhiteSpaceChars; i ++) {
+        if (whiteSpace[i] == c) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void eatWhitespace(std::istream &is) {
+    while(is.good() && isWhitespace(is.peek())) {
+        is.get();
+    }
+}
+
+bool getToken(std::istream &is, std::string &token) {
+    eatWhitespace(is);
+    token.clear();
+    char c;
+    while(is.good() && !isWhitespace(is.peek())) {
+        c = is.get();
+        if (is.good()){
+            token += c;
+        }
+    }
+    return token.size() > 0;
+}
+
+void appendDataFromStream(std::vector<float> &dataVec, uint32_t numFloats, std::istream &is) {
+    std::string token;
+    for (uint32_t i = 0; i < numFloats; i ++){
+        bool valid = getToken(is, token);
+        if (valid) {
+            dataVec.push_back((float)atof(token.c_str()));
+        } else {
+            fprintf(stderr, "Encountered error reading geometry data");
+            dataVec.push_back(0.0f);
+        }
+    }
+}
+
+bool checkNegativeIndex(int idx) {
+    if(idx < 0) {
+        fprintf(stderr, "Negative indices are not supported. Skipping face\n");
+        return false;
+    }
+    return true;
+}
+
+void ObjLoader::parseRawFaces(){
+    // We need at least a triangle
+    if (mRawFaces.size() < 3) {
+        return;
+    }
+
+    const char slash = '/';
+    mParsedFaces.resize(mRawFaces.size());
+    for (uint32_t i = 0; i < mRawFaces.size(); i ++) {
+        size_t firstSeparator = mRawFaces[i].find_first_of(slash);
+        size_t nextSeparator = mRawFaces[i].find_last_of(slash);
+
+        // Use the string as a temp buffer to parse the index
+        // Insert 0 instead of the slash to avoid substrings
+        if (firstSeparator != std::string::npos) {
+            mRawFaces[i][firstSeparator] = 0;
+        }
+        // Simple case, only one index
+        int32_t vIdx = atoi(mRawFaces[i].c_str());
+        // We do not support negative indices
+        if (!checkNegativeIndex(vIdx)) {
+            return;
+        }
+        // obj indices things beginning 1
+        mParsedFaces[i].vertIdx = (uint32_t)vIdx - 1;
+
+        if (nextSeparator != std::string::npos && nextSeparator != firstSeparator) {
+            mRawFaces[i][nextSeparator] = 0;
+            uint32_t nIdx = atoi(mRawFaces[i].c_str() + nextSeparator + 1);
+            if (!checkNegativeIndex(nIdx)) {
+                return;
+            }
+            // obj indexes things beginning 1
+            mParsedFaces[i].normIdx = (uint32_t)nIdx - 1;
+        }
+
+        // second case is where we have vertex and texture indices
+        if (nextSeparator != std::string::npos &&
+           (nextSeparator > firstSeparator + 1 || nextSeparator == firstSeparator)) {
+            uint32_t tIdx = atoi(mRawFaces[i].c_str() + firstSeparator + 1);
+            if (!checkNegativeIndex(tIdx)) {
+                return;
+            }
+            // obj indexes things beginning 1
+            mParsedFaces[i].texIdx = (uint32_t)tIdx - 1;
+        }
+    }
+
+    // Make sure a face list exists before we go adding to it
+    if (mMeshes.back().mUnfilteredFaces.size() == 0) {
+        mMeshes.back().appendUnfilteredFaces(mLastMtl);
+    }
+
+    // Now we have our parsed face, that we need to triangulate as necessary
+    // Treat more complex polygons as fans.
+    // This approach will only work only for convex polygons
+    // but concave polygons need to be addressed elsewhere anyway
+    for (uint32_t next = 1; next < mParsedFaces.size() - 1; next ++) {
+        // push it to our current mesh
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[0]);
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[next]);
+        mMeshes.back().mUnfilteredFaces.back().push_back(mParsedFaces[next + 1]);
+    }
+}
+
+void ObjLoader::checkNewMeshCreation(std::string &newGroup) {
+    // start a new mesh if we have some faces
+    // accumulated on the current mesh.
+    // It's possible to have multiple group statements
+    // but we only care to actually start a new mesh
+    // once we can have something we can draw on the previous one
+    if (mMeshes.back().mUnfilteredFaces.size()) {
+        mMeshes.push_back(ObjMesh());
+    }
+
+    mMeshes.back().mName = newGroup;
+    printf("Converting vertex group: %s\n", newGroup.c_str());
+}
+
+void ObjLoader::handleObjLine(char *line) {
+    const char* vtxToken    = "v";
+    const char* normToken   = "vn";
+    const char* texToken    = "vt";
+    const char* groupToken  = "g";
+    const char* mtlToken    = "usemtl";
+    const char* faceToken   = "f";
+
+    std::istringstream lineStream(line, std::istringstream::in);
+
+    std::string token;
+    bool valid = getToken(lineStream, token);
+    if (!valid) {
+        return;
+    }
+
+    if (token == vtxToken) {
+        appendDataFromStream(mObjPositions, 3, lineStream);
+    } else if (token == normToken) {
+        appendDataFromStream(mObjNormals, 3, lineStream);
+    } else if (token == texToken) {
+        appendDataFromStream(mObjTextureCoords, 2, lineStream);
+    } else if (token == groupToken) {
+        valid = getToken(lineStream, token);
+        checkNewMeshCreation(token);
+    } else if (token == faceToken) {
+        mRawFaces.clear();
+        while(getToken(lineStream, token)) {
+            mRawFaces.push_back(token);
+        }
+        parseRawFaces();
+    }
+    // Ignore materials for now
+    else if (token == mtlToken) {
+        valid = getToken(lineStream, token);
+        mLastMtl = token;
+
+        mMeshes.back().appendUnfilteredFaces(token);
+    }
+}
+
+bool ObjLoader::init(const char *fileName) {
+
+    std::ifstream ifs(fileName , std::ifstream::in);
+    if (!ifs.good()) {
+        fprintf(stderr, "Failed to read file %s.\n", fileName);
+        return false;
+    }
+
+    mMeshes.clear();
+
+    const uint32_t maxBufferSize = 2048;
+    char *buffer = new char[maxBufferSize];
+
+    mMeshes.push_back(ObjMesh());
+
+    std::string token;
+    bool isDone = false;
+    while(!isDone) {
+        ifs.getline(buffer, maxBufferSize);
+        if (ifs.good() && ifs.gcount() > 0) {
+            handleObjLine(buffer);
+        } else {
+            isDone = true;
+        }
+    }
+
+    ifs.close();
+    delete buffer;
+
+    reIndexGeometry();
+
+    return true;
+}
+
+bool ObjLoader::convertToA3D(const char *a3dFile) {
+    if (!getNumMeshes()) {
+        return false;
+    }
+    // Now write all this stuff out
+    Context rsc;
+    FileA3D file(&rsc);
+
+    for (uint32_t i = 0; i < getNumMeshes(); i ++) {
+        Mesh *exportedMesh = getMesh(&rsc, i);
+        file.appendToFile(exportedMesh);
+        delete exportedMesh;
+    }
+
+    file.writeFile(a3dFile);
+    return true;
+}
+
+void ObjLoader::reIndexGeometry() {
+    // We want to know where each vertex lands
+    mVertexRemap.resize(mObjPositions.size() / mPositionsStride);
+
+    for (uint32_t m = 0; m < mMeshes.size(); m ++) {
+        // clear the remap vector of old data
+        for (uint32_t r = 0; r < mVertexRemap.size(); r ++) {
+            mVertexRemap[r].clear();
+        }
+
+        for (uint32_t i = 0; i < mMeshes[m].mUnfilteredFaces.size(); i ++) {
+            mMeshes[m].mTriangleLists[i].reserve(mMeshes[m].mUnfilteredFaces[i].size() * 2);
+            for (uint32_t fI = 0; fI < mMeshes[m].mUnfilteredFaces[i].size(); fI ++) {
+                uint32_t newIndex = reIndexGeometryPrim(mMeshes[m], mMeshes[m].mUnfilteredFaces[i][fI]);
+                mMeshes[m].mTriangleLists[i].push_back(newIndex);
+            }
+        }
+    }
+}
+
+uint32_t ObjLoader::reIndexGeometryPrim(ObjMesh &mesh, PrimitiveVtx &prim) {
+
+    std::vector<float> &mPositions = mesh.mChannels[0].mData;
+    std::vector<float> &mNormals = mesh.mChannels[1].mData;
+    std::vector<float> &mTextureCoords = mesh.mChannels[2].mData;
+
+    float posX = mObjPositions[prim.vertIdx * mPositionsStride + 0];
+    float posY = mObjPositions[prim.vertIdx * mPositionsStride + 1];
+    float posZ = mObjPositions[prim.vertIdx * mPositionsStride + 2];
+
+    float normX = 0.0f;
+    float normY = 0.0f;
+    float normZ = 0.0f;
+    if (prim.normIdx != MAX_INDEX) {
+        normX = mObjNormals[prim.normIdx * mNormalsStride + 0];
+        normY = mObjNormals[prim.normIdx * mNormalsStride + 1];
+        normZ = mObjNormals[prim.normIdx * mNormalsStride + 2];
+    }
+
+    float texCoordX = 0.0f;
+    float texCoordY = 0.0f;
+    if (prim.texIdx != MAX_INDEX) {
+        texCoordX = mObjTextureCoords[prim.texIdx * mTextureCoordsStride + 0];
+        texCoordY = mObjTextureCoords[prim.texIdx * mTextureCoordsStride + 1];
+    }
+
+    std::vector<unsigned int> &ithRemapList = mVertexRemap[prim.vertIdx];
+    // We may have some potential vertices we can reuse
+    // loop over all the potential candidates and see if any match our guy
+    for (unsigned int i = 0; i < ithRemapList.size(); i ++) {
+
+        int ithRemap = ithRemapList[i];
+        // compare existing vertex with the new one
+        if (mPositions[ithRemap * mPositionsStride + 0] != posX ||
+            mPositions[ithRemap * mPositionsStride + 1] != posY ||
+            mPositions[ithRemap * mPositionsStride + 2] != posZ) {
+            continue;
+        }
+
+        // Now go over normals
+        if (prim.normIdx != MAX_INDEX) {
+            if (mNormals[ithRemap * mNormalsStride + 0] != normX ||
+                mNormals[ithRemap * mNormalsStride + 1] != normY ||
+                mNormals[ithRemap * mNormalsStride + 2] != normZ) {
+                continue;
+            }
+        }
+
+        // And texcoords
+        if (prim.texIdx != MAX_INDEX) {
+            if (mTextureCoords[ithRemap * mTextureCoordsStride + 0] != texCoordX ||
+                mTextureCoords[ithRemap * mTextureCoordsStride + 1] != texCoordY) {
+                continue;
+            }
+        }
+
+        // If we got here the new vertex is identical to the one that we already stored
+        return ithRemap;
+    }
+
+    // We did not encounter this vertex yet, store it and return its index
+    mPositions.push_back(posX);
+    mPositions.push_back(posY);
+    mPositions.push_back(posZ);
+
+    if (prim.normIdx != MAX_INDEX) {
+        mNormals.push_back(normX);
+        mNormals.push_back(normY);
+        mNormals.push_back(normZ);
+    }
+
+    if (prim.texIdx != MAX_INDEX) {
+        mTextureCoords.push_back(texCoordX);
+        mTextureCoords.push_back(texCoordY);
+    }
+
+    // We need to remember this mapping. Since we are storing floats, not vec3's, need to
+    // divide by position size to get the right index
+    int currentVertexIndex = (mPositions.size()/mPositionsStride) - 1;
+    ithRemapList.push_back(currentVertexIndex);
+
+    return currentVertexIndex;
+}
diff --git a/tools/a3dconvert/ObjLoader.h b/tools/a3dconvert/ObjLoader.h
new file mode 100644
index 0000000..210b35f
--- /dev/null
+++ b/tools/a3dconvert/ObjLoader.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+#ifndef _OBJ_LOADER_H_
+#define _OBJ_LOADER_H_
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include "SimpleMesh.h"
+#include <rsContext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define MAX_INDEX 0xffffffff
+
+class ObjLoader {
+public:
+    ObjLoader();
+    bool init(const char *objFile);
+    bool convertToA3D(const char *a3dFile);
+private:
+
+    Mesh *getMesh(Context *rsc, uint32_t meshIndex) {
+        return mMeshes[meshIndex].getMesh(rsc);
+    }
+    uint32_t getNumMeshes() const {
+        return mMeshes.size();
+    }
+
+    // .obj has a global list of vertex data
+    std::vector<float> mObjPositions;
+    std::vector<float> mObjNormals;
+    std::vector<float> mObjTextureCoords;
+
+    struct PrimitiveVtx {
+        uint32_t vertIdx;
+        uint32_t normIdx;
+        uint32_t texIdx;
+
+        PrimitiveVtx() : vertIdx(MAX_INDEX),
+                         normIdx(MAX_INDEX),
+                         texIdx(MAX_INDEX){
+        }
+    };
+
+    // Scratch buffer for faces
+    std::vector<std::string> mRawFaces;
+    std::vector<PrimitiveVtx> mParsedFaces;
+    std::string mLastMtl;
+
+    // Groups are used to separate multiple meshes within the same .obj file
+    class ObjMesh : public SimpleMesh {
+    public:
+
+        std::vector<std::vector<PrimitiveVtx> > mUnfilteredFaces;
+
+        void appendUnfilteredFaces(std::string name) {
+            appendFaceList(name);
+            mUnfilteredFaces.push_back(std::vector<PrimitiveVtx>());
+            // Reserve some space for index data
+            static const uint32_t numReserveIndecies = 128;
+            mUnfilteredFaces.back().reserve(numReserveIndecies);
+        }
+
+        ObjMesh() {
+            appendChannel("position", 3);
+            appendChannel("normal", 3);
+            appendChannel("texture0", 2);
+        }
+    };
+
+    std::vector<ObjMesh> mMeshes;
+    void checkNewMeshCreation(std::string &newGroup);
+
+    void parseRawFaces();
+    void handleObjLine(char *line);
+
+    void reIndexGeometry();
+    uint32_t reIndexGeometryPrim(ObjMesh &mesh, PrimitiveVtx &prim);
+
+    unsigned int mPositionsStride;
+    unsigned int mNormalsStride;
+    unsigned int mTextureCoordsStride;
+
+    // This vector is used to remap a position index into a list
+    //  of all divergent vertices
+    std::vector<std::vector<unsigned int> > mVertexRemap;
+};
+
+#endif //_OBJ_LOADER_H_
diff --git a/tools/a3dconvert/SimpleMesh.h b/tools/a3dconvert/SimpleMesh.h
new file mode 100644
index 0000000..57e1a7c
--- /dev/null
+++ b/tools/a3dconvert/SimpleMesh.h
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+#ifndef _SIMPLE_MESH_H_
+#define _SIMPLE_MESH_H_
+
+#include <rsContext.h>
+#include <rsMesh.h>
+using namespace android;
+using namespace android::renderscript;
+
+class SimpleMesh {
+public:
+    struct Channel {
+        std::vector<float> mData;
+        std::string mName;
+        uint32_t mStride;
+    };
+
+    // Vertex channels (position, normal)
+    // This assumes all the data array are the same size
+    std::vector<Channel> mChannels;
+
+    // Triangle list index data
+    std::vector<std::vector<uint32_t> > mTriangleLists;
+    // Names of all the triangle lists
+    std::vector<std::string> mTriangleListNames;
+    // Name of the entire object
+    std::string mName;
+
+    // Adds another index set to the mesh
+    void appendFaceList(std::string name) {
+        mTriangleListNames.push_back(name);
+        mTriangleLists.push_back(std::vector<uint32_t>());
+    }
+
+    // Adds another data channel (position, normal, etc.)
+    void appendChannel(std::string name, uint32_t stride) {
+        mChannels.push_back(Channel());
+        static const uint32_t reserveVtx = 128;
+        mChannels.back().mData.reserve(reserveVtx*stride);
+        mChannels.back().mName = name;
+        mChannels.back().mStride = stride;
+    }
+
+    SimpleMesh() {
+        // reserve some data in the vectors
+        // simply letting it grow by itself tends to waste a lot of time on
+        // rallocations / copies when dealing with geometry data
+        static const uint32_t reserveFaces = 8;
+        static const uint32_t reserveChannels = 8;
+        mTriangleLists.reserve(reserveFaces);
+        mTriangleListNames.reserve(reserveFaces);
+        mChannels.reserve(reserveChannels);
+    }
+
+    // Generates a renderscript mesh that could be used for a3d serialization
+    Mesh *getMesh(Context *rsc) {
+        if (mChannels.size() == 0) {
+            return NULL;
+        }
+
+        // Generate the element that describes our channel layout
+        rsc->mStateElement.elementBuilderBegin();
+        for (uint32_t c = 0; c < mChannels.size(); c ++) {
+            // Skip empty channels
+            if (mChannels[c].mData.size() == 0) {
+                continue;
+            }
+            const Element *subElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, mChannels[c].mStride);
+            rsc->mStateElement.elementBuilderAdd(subElem, mChannels[c].mName.c_str(), 1);
+        }
+        const Element *vertexDataElem = rsc->mStateElement.elementBuilderCreate(rsc);
+
+        uint32_t numVerts = mChannels[0].mData.size()/mChannels[0].mStride;
+        Type *vertexDataType = Type::getType(rsc, vertexDataElem, numVerts, 0, 0, false, false);
+        vertexDataType->compute();
+
+        Allocation *vertexAlloc = new Allocation(rsc, vertexDataType, RS_ALLOCATION_USAGE_SCRIPT);
+
+        uint32_t vertexSize = vertexDataElem->getSizeBytes()/sizeof(float);
+        // Fill this allocation with some data
+        float *dataPtr = (float*)vertexAlloc->getPtr();
+        for (uint32_t i = 0; i < numVerts; i ++) {
+            // Find the pointer to the current vertex's data
+            uint32_t vertexPos = i*vertexSize;
+            float *vertexPtr = dataPtr + vertexPos;
+
+            for (uint32_t c = 0; c < mChannels.size(); c ++) {
+                // Skip empty channels
+                if (mChannels[c].mData.size() == 0) {
+                    continue;
+                }
+                for (uint32_t cStride = 0; cStride < mChannels[c].mStride; cStride ++) {
+                    *(vertexPtr++) = mChannels[c].mData[i * mChannels[c].mStride + cStride];
+                }
+            }
+        }
+
+        // Now lets write index data
+        const Element *indexElem = Element::create(rsc, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
+
+        Mesh *mesh = new Mesh(rsc);
+        mesh->setName(mName.c_str());
+        mesh->mVertexBufferCount = 1;
+        mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[1];
+        mesh->mVertexBuffers[0].set(vertexAlloc);
+
+        mesh->mPrimitivesCount = mTriangleLists.size();
+        mesh->mPrimitives = new Mesh::Primitive_t *[mesh->mPrimitivesCount];
+
+        // load all primitives
+        for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
+            Mesh::Primitive_t *prim = new Mesh::Primitive_t;
+            mesh->mPrimitives[pCount] = prim;
+
+            uint32_t numIndicies = mTriangleLists[pCount].size();
+            Type *indexType = Type::getType(rsc, indexElem, numIndicies, 0, 0, false, false );
+
+            indexType->compute();
+
+            Allocation *indexAlloc = new Allocation(rsc, indexType, RS_ALLOCATION_USAGE_SCRIPT);
+            uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
+            const std::vector<uint32_t> &indexList = mTriangleLists[pCount];
+            uint32_t numTries = numIndicies / 3;
+
+            for (uint32_t i = 0; i < numTries; i ++) {
+                indexPtr[i * 3 + 0] = (uint16_t)indexList[i * 3 + 0];
+                indexPtr[i * 3 + 1] = (uint16_t)indexList[i * 3 + 1];
+                indexPtr[i * 3 + 2] = (uint16_t)indexList[i * 3 + 2];
+            }
+            indexAlloc->setName(mTriangleListNames[pCount].c_str());
+            prim->mIndexBuffer.set(indexAlloc);
+            prim->mPrimitive = RS_PRIMITIVE_TRIANGLE;
+        }
+
+        return mesh;
+    }
+};
+
+#endif
diff --git a/tools/a3dconvert/a3dconvert.cpp b/tools/a3dconvert/a3dconvert.cpp
new file mode 100644
index 0000000..33f5733
--- /dev/null
+++ b/tools/a3dconvert/a3dconvert.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#include <iostream>
+#include <vector>
+
+#include "ColladaLoader.h"
+#include "ObjLoader.h"
+
+int main (int argc, char * const argv[]) {
+    const char *objExt = ".obj";
+    const char *daeExt = ".dae";
+
+    if(argc != 3) {
+        printf("-----------------------------------------------------------------\n");
+        printf("Usage:\n");
+        printf("a3dconvert input_file a3d_output_file\n");
+        printf("Currently .obj and .dae (collada) input files are accepted\n");
+        printf("-----------------------------------------------------------------\n");
+        return 1;
+    }
+
+    bool isSuccessful = false;
+
+    std::string filename = argv[1];
+    size_t dotPos = filename.find_last_of('.');
+    if (dotPos == std::string::npos) {
+        printf("Invalid input. Currently .obj and .dae (collada) input files are accepted\n");
+        return 1;
+    }
+
+    std::string ext = filename.substr(dotPos);
+    if (ext == daeExt) {
+        ColladaLoader converter;
+        isSuccessful = converter.init(argv[1]);
+        if (isSuccessful) {
+            isSuccessful = converter.convertToA3D(argv[2]);
+        }
+    } else if (ext == objExt) {
+        ObjLoader objConv;
+        isSuccessful = objConv.init(argv[1]);
+        if (isSuccessful) {
+            isSuccessful = objConv.convertToA3D(argv[2]);
+        }
+    } else {
+        printf("Invalid input. Currently .obj and .dae (collada) input files are accepted\n");
+        return 1;
+    }
+
+    if(isSuccessful) {
+        printf("---All done---\n");
+    } else {
+        printf("---Encountered errors, conversion failed---\n");
+    }
+
+    return isSuccessful ? 0 : 1;
+}
diff --git a/tools/a3dconvert/license.txt b/tools/a3dconvert/license.txt
new file mode 100755
index 0000000..354667a
--- /dev/null
+++ b/tools/a3dconvert/license.txt
@@ -0,0 +1,25 @@
+Parts of this code come from colladaDom with the license below. The rest is AOSP.
+
+
+
+The MIT License
+
+Copyright 2006 Sony Computer Entertainment Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
