SceneManager.java revision e57b34155269cc030b4b241f556207f7012a0f07
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
19e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.File;
20e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.IOException;
21e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.InputStream;
22e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.FileInputStream;
23e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.BufferedInputStream;
24e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport java.io.Writer;
25e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
26a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.lang.Math;
27a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.ArrayList;
28a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.HashMap;
29a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.regex.Matcher;
30a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.regex.Pattern;
31a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
32e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport android.graphics.Bitmap;
33e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchoukimport android.graphics.BitmapFactory;
34e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
35a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.RenderScriptGL;
36a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Mesh;
37a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.*;
38a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Allocation.MipmapControl;
39a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.content.res.Resources;
40a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.SurfaceHolder;
41a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.Log;
42a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.os.AsyncTask;
43a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
44a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/**
45a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * @hide
46a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */
47a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpublic class SceneManager extends SceneGraphBase {
48a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
49a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    ScriptC_render mRenderLoop;
50a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    ScriptC_camera mCameraScript;
51875a538d5db06e7e055401050e03b86bf8598536Alex Sakhartchouk    ScriptC_light mLightScript;
52dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    ScriptC_params mParamsScript;
53a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    ScriptC_transform mTransformScript;
54a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
55a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    RenderScriptGL mRS;
56a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    Resources mRes;
57a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    Mesh mQuad;
58a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    int mWidth;
59a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    int mHeight;
60a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
61f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    public static boolean isSDCardPath(String path) {
62f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        int sdCardIndex = path.indexOf("sdcard/");
63f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        // We are looking for /sdcard/ or sdcard/
64f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        if (sdCardIndex == 0 || sdCardIndex == 1) {
65f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk            return true;
66f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        }
67f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        sdCardIndex = path.indexOf("mnt/sdcard/");
68f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        if (sdCardIndex == 0 || sdCardIndex == 1) {
69f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk            return true;
70f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        }
71f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        return false;
72f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    }
73f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk
74e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    static Bitmap loadBitmap(String name, Resources res) {
75e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        InputStream is = null;
76e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        boolean loadFromSD = isSDCardPath(name);
77e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        try {
78e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            if (!loadFromSD) {
79e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                is = res.getAssets().open(name);
80e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            } else {
81e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                File f = new File(name);
82e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                is = new BufferedInputStream(new FileInputStream(f));
83e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            }
84e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        } catch (IOException e) {
85e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            Log.e("ImageLoaderTask", " Message: " + e.getMessage());
86e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            return null;
87e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        }
88e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
89e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        Bitmap b = BitmapFactory.decodeStream(is);
90e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        try {
91e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            is.close();
92e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        } catch (IOException e) {
93e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk            Log.e("ImageLoaderTask", " Message: " + e.getMessage());
94e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        }
95e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        return b;
96e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
97e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
98e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
99e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        Bitmap b = loadBitmap(name, res);
100e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        return Allocation.createCubemapFromBitmap(rs, b,
101e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                                                  MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
102e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                                                  Allocation.USAGE_GRAPHICS_TEXTURE);
103e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
104e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
105e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) {
106e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        Bitmap b = loadBitmap(name, res);
107e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk        return Allocation.createFromBitmap(rs, b,
108e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
109e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk                                           Allocation.USAGE_GRAPHICS_TEXTURE);
110e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk    }
111e57b34155269cc030b4b241f556207f7012a0f07Alex Sakhartchouk
112a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public static class SceneLoadedCallback implements Runnable {
113a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        Scene mLoadedScene;
114a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        String mName;
115a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        public void run() {
116a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        }
117a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
118a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
119a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public SceneManager() {
120a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
121a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
122a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public void loadModel(String name, SceneLoadedCallback cb) {
123a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        ColladaScene scene = new ColladaScene(name, cb);
124a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        scene.init(mRS, mRes);
125a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
126a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
127a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public Mesh getScreenAlignedQuad() {
128a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        if (mQuad != null) {
129a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk            return mQuad;
130a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        }
131a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
132a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
133a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk                                           3, Mesh.TriangleMeshBuilder.TEXTURE_0);
134a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
135a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.setTexture(0.0f, 1.0f);
136a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addVertex(-1.0f, 1.0f, 1.0f);
137a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
138a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.setTexture(0.0f, 0.0f);
139a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addVertex(-1.0f, -1.0f, 1.0f);
140a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
141a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.setTexture(1.0f, 0.0f);
142a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addVertex(1.0f, -1.0f, 1.0f);
143a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
144a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.setTexture(1.0f, 1.0f);
145a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addVertex(1.0f, 1.0f, 1.0f);
146a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
147a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addTriangle(0, 1, 2);
148a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        tmb.addTriangle(2, 3, 0);
149a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
150a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mQuad = tmb.create(true);
151a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        return mQuad;
152a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
153a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
154f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    public Renderable getRenderableQuad(String name, RenderState state) {
155f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        Renderable quad = new Renderable();
156f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setTransform(new MatrixTransform());
157f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setMesh(getScreenAlignedQuad());
158f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setName(name);
159f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setRenderState(state);
160f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        quad.setCullType(1);
161f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk        return quad;
162f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk    }
163f92189d2aea9856c11c26ebe392cd53dd969c0b8Alex Sakhartchouk
164a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
165a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRS = rs;
166a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRes = res;
167a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
168a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mTransformScript.set_gTransformScript(mTransformScript);
169a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
170a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
171875a538d5db06e7e055401050e03b86bf8598536Alex Sakhartchouk        mLightScript = new ScriptC_light(rs, res, R.raw.light);
172dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk        mParamsScript = new ScriptC_params(rs, res, R.raw.params);
173a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
174a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
175a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop.set_gTransformScript(mTransformScript);
176a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop.set_gCameraScript(mCameraScript);
177875a538d5db06e7e055401050e03b86bf8598536Alex Sakhartchouk        mRenderLoop.set_gLightScript(mLightScript);
178dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk        mRenderLoop.set_gParamsScript(mParamsScript);
179a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
180a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
181a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk                                                         MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
182a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk                                                         Allocation.USAGE_GRAPHICS_TEXTURE);
183a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mRenderLoop.set_gTGrid(checker);
184be5bdeb9471c4a04905edd34e6d3560315293427Alex Sakhartchouk        mRenderLoop.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
185a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
186a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
187a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public ScriptC_render getRenderLoop() {
188a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        return mRenderLoop;
189a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
190a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk}
191a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
192a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
193a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
194a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
195