1// Copyright (C) 2011 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma version(1)
16
17#pragma rs java_package_name(com.android.modelviewer)
18
19#include "rs_graphics.rsh"
20
21rs_program_vertex gPVBackground;
22rs_program_fragment gPFBackground;
23
24rs_allocation gTGrid;
25
26rs_program_store gPFSBackground;
27
28rs_font gItalic;
29rs_allocation gTextAlloc;
30
31rs_matrix4x4 gPostureMatrix;
32
33typedef struct MeshInfo {
34    rs_mesh mMesh;
35    int mNumIndexSets;
36    float3 bBoxMin;
37    float3 bBoxMax;
38} MeshInfo_t;
39
40MeshInfo_t *gMeshes;
41
42static float3 gLookAt;
43
44static float gRotateX;
45static float gRotateY;
46static float gZoom;
47
48static float gLastX;
49static float gLastY;
50
51static float3 toFloat3(float x, float y, float z) {
52    float3 f;
53    f.x = x;
54    f.y = y;
55    f.z = z;
56    return f;
57}
58
59void onActionDown(float x, float y) {
60    gLastX = x;
61    gLastY = y;
62}
63
64void onActionScale(float scale) {
65
66    gZoom *= 1.0f / scale;
67    gZoom = max(0.1f, min(gZoom, 500.0f));
68}
69
70void onActionMove(float x, float y) {
71    float dx = gLastX - x;
72    float dy = gLastY - y;
73
74    if (fabs(dy) <= 2.0f) {
75        dy = 0.0f;
76    }
77    if (fabs(dx) <= 2.0f) {
78        dx = 0.0f;
79    }
80
81    gRotateY -= dx;
82    if (gRotateY > 360) {
83        gRotateY -= 360;
84    }
85    if (gRotateY < 0) {
86        gRotateY += 360;
87    }
88
89    gRotateX -= dy;
90    gRotateX = min(gRotateX, 80.0f);
91    gRotateX = max(gRotateX, -80.0f);
92
93    gLastX = x;
94    gLastY = y;
95}
96
97void init() {
98    gRotateX = 0.0f;
99    gRotateY = 0.0f;
100    gZoom = 50.0f;
101    gLookAt = 0.0f;
102    rsMatrixLoadIdentity(&gPostureMatrix);
103}
104
105void updateMeshInfo() {
106    rs_allocation allMeshes = rsGetAllocation(gMeshes);
107    int size = rsAllocationGetDimX(allMeshes);
108    gLookAt = 0.0f;
109    float minX, minY, minZ, maxX, maxY, maxZ;
110    for (int i = 0; i < size; i++) {
111        MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
112        rsgMeshComputeBoundingBox(info->mMesh,
113                                  &minX, &minY, &minZ,
114                                  &maxX, &maxY, &maxZ);
115        info->bBoxMin = toFloat3(minX, minY, minZ);
116        info->bBoxMax = toFloat3(maxX, maxY, maxZ);
117        gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
118    }
119    gLookAt = gLookAt / (float)size;
120}
121
122static void renderAllMeshes() {
123    rs_allocation allMeshes = rsGetAllocation(gMeshes);
124    int size = rsAllocationGetDimX(allMeshes);
125    gLookAt = 0.0f;
126    float minX, minY, minZ, maxX, maxY, maxZ;
127    for (int i = 0; i < size; i++) {
128        MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
129        rsgDrawMesh(info->mMesh);
130    }
131}
132
133void drawDescription() {
134    uint width = rsgGetWidth();
135    uint height = rsgGetHeight();
136    int left = 0, right = 0, top = 0, bottom = 0;
137
138    rsgBindFont(gItalic);
139
140    rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
141    rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom);
142}
143
144int root(void) {
145
146    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
147    rsgClearDepth(1.0f);
148
149    rsgBindProgramVertex(gPVBackground);
150    rs_matrix4x4 proj;
151    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
152    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
153    rsgProgramVertexLoadProjectionMatrix(&proj);
154
155    rsgBindProgramFragment(gPFBackground);
156    rsgBindProgramStore(gPFSBackground);
157    rsgBindTexture(gPFBackground, 0, gTGrid);
158
159    rs_matrix4x4 matrix;
160    rsMatrixLoadIdentity(&matrix);
161    // Position our models on the screen
162    rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
163    rsMatrixMultiply(&matrix, &gPostureMatrix);
164    rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
165    rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
166    
167    rsgProgramVertexLoadModelMatrix(&matrix);
168
169    renderAllMeshes();
170
171    drawDescription();
172
173    return 0;
174}
175