1// Copyright (C) 2009 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 "transform_def.rsh"
20
21rs_script transformScript;
22
23typedef struct {
24    int changed;
25    rs_matrix4x4 *mat;
26} ParentData;
27
28static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
29    rs_matrix4x4 temp;
30
31    switch (type) {
32    case TRANSFORM_TRANSLATE:
33        rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
34        break;
35    case TRANSFORM_ROTATE:
36        rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
37        break;
38    case TRANSFORM_SCALE:
39        rsMatrixLoadScale(&temp, data.x, data.y, data.z);
40        break;
41    }
42    rsMatrixMultiply(mat, &temp);
43}
44
45void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
46
47    SgTransform *data = (SgTransform *)v_out;
48    const ParentData *parent = (const ParentData *)usrData;
49
50    //rsDebug("Transform data", (int)data);
51    //rsDebug("Entering parent", (int)parent);
52
53    rs_matrix4x4 *localMat = &data->localMat;
54    rs_matrix4x4 *globalMat = &data->globalMat;
55
56    ParentData toChild;
57    toChild.changed = 0;
58    toChild.mat = globalMat;
59
60    //rsDebug("Transform is dirty", data->isDirty);
61
62    // Refresh matrices if dirty
63    if (data->isDirty) {
64        data->isDirty = 0;
65        toChild.changed = 1;
66
67        // Reset our local matrix
68        rsMatrixLoadIdentity(localMat);
69
70        for (int i = 0; i < 16; i ++) {
71            if (data->transformTypes[i] == TRANSFORM_NONE) {
72                break;
73            }
74            //rsDebug("Transform adding transformation", transformTypes[i]);
75            appendTransformation(data->transformTypes[i], data->transforms[i], localMat);
76        }
77    }
78
79    //rsDebug("Transform checking parent", (int)0);
80
81    if (parent) {
82        if (parent->changed) {
83            toChild.changed = 1;
84
85            rsMatrixLoad(globalMat, parent->mat);
86            rsMatrixMultiply(globalMat, localMat);
87        }
88    } else {
89        rsMatrixLoad(globalMat, localMat);
90    }
91
92    //rsDebug("Transform calling self with child ", (int)data->children.p);
93    if (data->children.p) {
94        rsForEach(transformScript, data->children, data->children, (void*)&toChild, sizeof(toChild));
95    }
96}
97