blob: 941b5a8c292aa5865efe12892eb382f66695c3b7 [file] [log] [blame]
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -08001// 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
Alex Sakhartchoukd4cb9c52012-01-26 15:51:19 -080019#include "scenegraph_objects.rsh"
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080020
21rs_script gTransformScript;
22
23typedef struct {
24 int changed;
25 rs_matrix4x4 *mat;
26} ParentData;
27
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -080028//#define DEBUG_TRANSFORMS
29static void debugTransform(SgTransform *data, const ParentData *parent) {
30 rsDebug("****** <Transform> ******", (int)data);
31 printName(data->name);
32 rsDebug("isDirty", data->isDirty);
33 rsDebug("parent", (int)parent);
34 rsDebug("child ", rsIsObject(data->children));
35
36 // Refresh matrices if dirty
37 if (data->isDirty && rsIsObject(data->components)) {
38 uint32_t numComponenets = rsAllocationGetDimX(data->components);
39 for (int i = 0; i < numComponenets; i ++) {
40 const SgTransformComponent *comp = NULL;
41 comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
42
43 if (rsIsObject(comp->name)) {
44 rsDebug((const char*)rsGetElementAt(comp->name, 0), comp->value);
45 rsDebug("Type", comp->type);
46 } else {
47 rsDebug("no name", comp->value);
48 rsDebug("Type", comp->type);
49 }
50 }
51 }
52
53 rsDebug("timestamp", data->timestamp);
54 rsDebug("****** </Transform> ******", (int)data);
55}
56
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080057static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
58 rs_matrix4x4 temp;
59
60 switch (type) {
61 case TRANSFORM_TRANSLATE:
62 rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
63 break;
64 case TRANSFORM_ROTATE:
65 rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
66 break;
67 case TRANSFORM_SCALE:
68 rsMatrixLoadScale(&temp, data.x, data.y, data.z);
69 break;
70 }
71 rsMatrixMultiply(mat, &temp);
72}
73
74void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) {
75
76 SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0);
77 const ParentData *parent = (const ParentData *)usrData;
78
79#ifdef DEBUG_TRANSFORMS
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -080080 debugTransform(data, parent);
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080081#endif //DEBUG_TRANSFORMS
82
83 rs_matrix4x4 *localMat = &data->localMat;
84 rs_matrix4x4 *globalMat = &data->globalMat;
85
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080086 // Refresh matrices if dirty
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -080087 if (data->isDirty && rsIsObject(data->components)) {
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080088 bool resetLocal = false;
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -080089 uint32_t numComponenets = rsAllocationGetDimX(data->components);
90 for (int i = 0; i < numComponenets; i ++) {
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080091 if (!resetLocal) {
92 // Reset our local matrix only for component transforms
93 rsMatrixLoadIdentity(localMat);
94 resetLocal = true;
95 }
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -080096 const SgTransformComponent *comp = NULL;
97 comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
98 appendTransformation(comp->type, comp->value, localMat);
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -080099 }
100 }
101
102 if (parent) {
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -0800103 data->isDirty = (parent->changed || data->isDirty) ? 1 : 0;
104 if (data->isDirty) {
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -0800105 rsMatrixLoad(globalMat, parent->mat);
106 rsMatrixMultiply(globalMat, localMat);
107 }
108 } else if (data->isDirty) {
109 rsMatrixLoad(globalMat, localMat);
110 }
111
Alex Sakhartchouke92c78c2012-01-31 13:23:13 -0800112 ParentData toChild;
113 toChild.changed = 0;
114 toChild.mat = globalMat;
115
116 if (data->isDirty) {
117 toChild.changed = 1;
118 data->timestamp ++;
119 }
120
Alex Sakhartchouka7a211b2011-12-08 11:39:14 -0800121 if (rsIsObject(data->children)) {
122 rs_allocation nullAlloc;
123 rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
124 }
125
126 data->isDirty = 0;
127}