1aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk/*
2dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk *
4aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * you may not use this file except in compliance with the License.
6aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * You may obtain a copy of the License at
7aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk *
8aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk *
10aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * See the License for the specific language governing permissions and
14aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk * limitations under the License.
15aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk */
16aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
17aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukpackage com.android.modelviewer;
18aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
19aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukimport java.io.Writer;
20aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
21aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukimport android.content.res.Resources;
22aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukimport android.renderscript.*;
23aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukimport android.renderscript.ProgramStore.DepthFunc;
24aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukimport android.util.Log;
25aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
26aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
2732e09b5891da0174f161d99e2d3ebe67d6efa39cAlex Sakhartchoukpublic class SimpleModelRS {
28aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
2932e09b5891da0174f161d99e2d3ebe67d6efa39cAlex Sakhartchouk    public SimpleModelRS() {
30aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
31aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
32dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void init(RenderScriptGL rs, Resources res) {
33aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mRS = rs;
34aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mRes = res;
35aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        initRS();
36aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
37aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
38dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void surfaceChanged() {
39dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mRS.getWidth();
40dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mRS.getHeight();
41dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    }
42dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
43aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private Resources mRes;
44aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private RenderScriptGL mRS;
45aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private Sampler mSampler;
46aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private ProgramStore mPSBackground;
47aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private ProgramFragment mPFBackground;
48aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private ProgramVertex mPVBackground;
49b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    private ProgramVertexFixedFunction.Constants mPVA;
50aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
51aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private Allocation mGridImage;
52aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private Allocation mAllocPV;
53aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk    private Font mItalic;
559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk    private Allocation mTextAlloc;
569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk
57dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    private ScriptField_MeshInfo mMeshes;
5893a958f0958b852c0a2c7b940c74eeae283ba02bStephen Hines    private ScriptC_simplemodel mScript;
59aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
60aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
61dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void onActionDown(float x, float y) {
62dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mScript.invoke_onActionDown(x, y);
63dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    }
64aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
65dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void onActionScale(float scale) {
66dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mScript.invoke_onActionScale(scale);
67dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    }
68aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
69dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void onActionMove(float x, float y) {
70dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mScript.invoke_onActionMove(x, y);
71aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
72aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
7335ccf46533c76cdc7c2f6c0ce8f33b34b29bc5e6Mathias Agopian    public void onPostureChanged(Matrix4f posture) {
7435ccf46533c76cdc7c2f6c0ce8f33b34b29bc5e6Mathias Agopian        mScript.set_gPostureMatrix(posture);
7535ccf46533c76cdc7c2f6c0ce8f33b34b29bc5e6Mathias Agopian    }
7635ccf46533c76cdc7c2f6c0ce8f33b34b29bc5e6Mathias Agopian
77aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private void initPFS() {
7832e09b5891da0174f161d99e2d3ebe67d6efa39cAlex Sakhartchouk        ProgramStore.Builder b = new ProgramStore.Builder(mRS);
79aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
80aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
81b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        b.setDitherEnabled(false);
82b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        b.setDepthMaskEnabled(true);
83aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mPSBackground = b.create();
84aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
85aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mScript.set_gPFSBackground(mPSBackground);
86aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
87aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
88aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private void initPF() {
89aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        Sampler.Builder bs = new Sampler.Builder(mRS);
90b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        bs.setMinification(Sampler.Value.LINEAR);
91b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        bs.setMagnification(Sampler.Value.LINEAR);
92aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        bs.setWrapS(Sampler.Value.CLAMP);
93db6f11bd30ad8afc94fdaffd81c9588289a3f6e5Alex Sakhartchouk        bs.setWrapT(Sampler.Value.CLAMP);
94aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mSampler = bs.create();
95aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
96b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
97b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
98b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
99aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mPFBackground = b.create();
100aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mPFBackground.bindSampler(mSampler, 0);
101aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
102aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mScript.set_gPFBackground(mPFBackground);
103aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
104aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
105aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private void initPV() {
106b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
107aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mPVBackground = pvb.create();
108aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
109b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
110b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
111aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
112aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mScript.set_gPVBackground(mPVBackground);
113aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
114aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
115aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private void loadImage() {
1166d8eb266dd398abf0511685fdaf98abba3396174Jason Sams        mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
1176d8eb266dd398abf0511685fdaf98abba3396174Jason Sams                                                         Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
1186d8eb266dd398abf0511685fdaf98abba3396174Jason Sams                                                         Allocation.USAGE_GRAPHICS_TEXTURE);
119aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mScript.set_gTGrid(mGridImage);
120aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
121aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
122dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    private void initTextAllocation(String fileName) {
123dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        String allocString = "Displaying file: " + fileName;
1245476b450e50939940dcf3f15c92335cee2fc572dJason Sams        mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
1259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk        mScript.set_gTextAlloc(mTextAlloc);
1269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk    }
1279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk
128dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    private void initMeshes(FileA3D model) {
129dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        int numEntries = model.getIndexEntryCount();
130dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        int numMeshes = 0;
131dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        for (int i = 0; i < numEntries; i ++) {
132dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            FileA3D.IndexEntry entry = model.getIndexEntry(i);
133dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
134dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                numMeshes ++;
135dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            }
136dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        }
137dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
138dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        if (numMeshes > 0) {
139dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
140dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
141dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            for (int i = 0; i < numEntries; i ++) {
142dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                FileA3D.IndexEntry entry = model.getIndexEntry(i);
143dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
144dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                    Mesh mesh = entry.getMesh();
145dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                    mMeshes.set_mMesh(i, mesh, false);
146dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                    mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
147dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk                }
148dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            }
149dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            mMeshes.copyAll();
150dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        } else {
151dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk            throw new RSRuntimeException("No valid meshes in file");
152dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        }
153dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
154dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mScript.bind_gMeshes(mMeshes);
155dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        mScript.invoke_updateMeshInfo();
156dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    }
157dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
158dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    public void loadA3DFile(String path) {
159dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        FileA3D model = FileA3D.createFromFile(mRS, path);
160dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        initMeshes(model);
161dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        initTextAllocation(path);
162dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk    }
163dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk
164aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    private void initRS() {
165aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
1663ba02b3d2f6fb49677466a2e93c96f307d2a7a41Jason Sams        mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel);
167aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
168aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        initPFS();
169aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        initPF();
170aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        initPV();
171aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
172aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        loadImage();
173aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
174aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
175dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        initMeshes(model);
176aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
177e27cdeeecba5b445e307d653d9cb7da007adfac3Alex Sakhartchouk        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
1789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk        mScript.set_gItalic(mItalic);
1799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk
180dc165b3365ca3e8fd7c4eb11b1154646977a6d0aAlex Sakhartchouk        initTextAllocation("R.raw.robot");
1819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk
182bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams        mRS.bindRootScript(mScript);
183aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
184aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk}
185aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
186aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
187aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
188