1a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/* 2a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project 3a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 4a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 5a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * you may not use this file except in compliance with the License. 6a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * You may obtain a copy of the License at 7a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 8a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 9a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 10a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 11a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 12a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * See the License for the specific language governing permissions and 14a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * limitations under the License. 15a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */ 16a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 17a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpackage com.android.scenegraph; 18a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 19a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.File; 20a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.IOException; 21a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.InputStream; 22a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.FileInputStream; 23a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.BufferedInputStream; 24a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.Writer; 25a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.ArrayList; 26a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.HashMap; 27a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.Map; 28a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.Vector; 29a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 30a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.content.res.Resources; 31a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.graphics.Bitmap; 32a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.graphics.BitmapFactory; 33a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.os.AsyncTask; 34a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.*; 35a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Allocation.MipmapControl; 36a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Element.Builder; 37a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Font.Style; 38a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Program.TextureType; 39a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.ProgramStore.DepthFunc; 40a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.Log; 41a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport com.android.scenegraph.SceneManager.SceneLoadedCallback; 42a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 43a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 44a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpublic class ColladaScene { 45a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 46a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private String modelName; 47a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private static String TAG = "ColladaScene"; 48a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private final int STATE_LAST_FOCUS = 1; 491168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk boolean mLoadFromSD = false; 50a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 51a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk SceneLoadedCallback mCallback; 52a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 53a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public ColladaScene(String name, SceneLoadedCallback cb) { 54a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk modelName = name; 55a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mCallback = cb; 56a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 57a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 58a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public void init(RenderScriptGL rs, Resources res) { 59a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRS = rs; 60a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRes = res; 61a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 62f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk mLoadFromSD = SceneManager.isSDCardPath(modelName); 631168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk 641168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk new ColladaLoaderTask().execute(modelName); 65a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 66a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 67a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private Resources mRes; 68a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private RenderScriptGL mRS; 69a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk Scene mActiveScene; 70a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 71a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> { 72a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk ColladaParser sceneSource; 73a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk protected Boolean doInBackground(String... names) { 741168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk String rootDir = names[0].substring(0, names[0].lastIndexOf('/') + 1); 75a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk long start = System.currentTimeMillis(); 76a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk sceneSource = new ColladaParser(); 77a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk InputStream is = null; 78a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk try { 79a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (!mLoadFromSD) { 80a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk is = mRes.getAssets().open(names[0]); 81a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } else { 821168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk File f = new File(names[0]); 83a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk is = new BufferedInputStream(new FileInputStream(f)); 84a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 85a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } catch (IOException e) { 86a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk Log.e(TAG, "Could not open collada file"); 87a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return new Boolean(false); 88a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 89a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk long end = System.currentTimeMillis(); 90a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk Log.v("TIMER", "Stream load time: " + (end - start)); 91a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 92a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk start = System.currentTimeMillis(); 931168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk sceneSource.init(is, rootDir); 94a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk end = System.currentTimeMillis(); 95a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk Log.v("TIMER", "Collada parse time: " + (end - start)); 96a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return new Boolean(true); 97a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 98a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 99a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk protected void onPostExecute(Boolean result) { 100a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActiveScene = sceneSource.getScene(); 101a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (mCallback != null) { 102a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mCallback.mLoadedScene = mActiveScene; 103a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mCallback.run(); 104a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 105a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 1061168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk String shortName = modelName.substring(0, modelName.lastIndexOf('.')); 1071168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk new A3DLoaderTask().execute(shortName + ".a3d"); 108a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 109a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 110a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 111a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private class A3DLoaderTask extends AsyncTask<String, Void, Boolean> { 112a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk protected Boolean doInBackground(String... names) { 113a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk long start = System.currentTimeMillis(); 114a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk FileA3D model; 115a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (!mLoadFromSD) { 116a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk model = FileA3D.createFromAsset(mRS, mRes.getAssets(), names[0]); 117a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } else { 1181168868e766f0696c30f644292a5a833ee3983e4Alex Sakhartchouk model = FileA3D.createFromFile(mRS, names[0]); 119a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 120a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk int numModels = model.getIndexEntryCount(); 121a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk for (int i = 0; i < numModels; i ++) { 122a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk FileA3D.IndexEntry entry = model.getIndexEntry(i); 123a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { 124a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActiveScene.meshLoaded(entry.getMesh()); 125a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 126a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 127a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk long end = System.currentTimeMillis(); 128a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk Log.v("TIMER", "A3D load time: " + (end - start)); 129a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return new Boolean(true); 130a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 131a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 132a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk protected void onPostExecute(Boolean result) { 133a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 134a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 135a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 136a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk} 137a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 138a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 139a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 140