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 "scenegraph_objects.rsh" 20 21rs_script gTransformScript; 22 23typedef struct { 24 int changed; 25 rs_matrix4x4 *mat; 26} ParentData; 27 28//#define DEBUG_TRANSFORMS 29/* Unused function: 30static void debugTransform(SgTransform *data, const ParentData *parent) { 31 rsDebug("****** <Transform> ******", (int)data); 32 printName(data->name); 33 rsDebug("isDirty", data->isDirty); 34 rsDebug("parent", (int)parent); 35 rsDebug("child ", rsIsObject(data->children)); 36 37 // Refresh matrices if dirty 38 if (data->isDirty && rsIsObject(data->components)) { 39 uint32_t numComponenets = rsAllocationGetDimX(data->components); 40 for (int i = 0; i < numComponenets; i ++) { 41 const SgTransformComponent *comp = NULL; 42 comp = (const SgTransformComponent *)rsGetElementAt(data->components, i); 43 44 if (rsIsObject(comp->name)) { 45 rsDebug((const char*)rsGetElementAt(comp->name, 0), comp->value); 46 rsDebug("Type", comp->type); 47 } else { 48 rsDebug("no name", comp->value); 49 rsDebug("Type", comp->type); 50 } 51 } 52 } 53 54 rsDebug("timestamp", data->timestamp); 55 rsDebug("****** </Transform> ******", (int)data); 56} 57*/ 58 59static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) { 60 rs_matrix4x4 temp; 61 62 switch (type) { 63 case TRANSFORM_TRANSLATE: 64 rsMatrixLoadTranslate(&temp, data.x, data.y, data.z); 65 break; 66 case TRANSFORM_ROTATE: 67 rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z); 68 break; 69 case TRANSFORM_SCALE: 70 rsMatrixLoadScale(&temp, data.x, data.y, data.z); 71 break; 72 } 73 rsMatrixMultiply(mat, &temp); 74} 75 76void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) { 77 78 SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0); 79 const ParentData *parent = (const ParentData *)usrData; 80 81#ifdef DEBUG_TRANSFORMS 82 debugTransform(data, parent); 83#endif //DEBUG_TRANSFORMS 84 85 rs_matrix4x4 *localMat = &data->localMat; 86 rs_matrix4x4 *globalMat = &data->globalMat; 87 88 // Refresh matrices if dirty 89 if (data->isDirty && rsIsObject(data->components)) { 90 bool resetLocal = false; 91 uint32_t numComponenets = rsAllocationGetDimX(data->components); 92 for (int i = 0; i < numComponenets; i ++) { 93 if (!resetLocal) { 94 // Reset our local matrix only for component transforms 95 rsMatrixLoadIdentity(localMat); 96 resetLocal = true; 97 } 98 const SgTransformComponent *comp = NULL; 99 comp = (const SgTransformComponent *)rsGetElementAt(data->components, i); 100 appendTransformation(comp->type, comp->value, localMat); 101 } 102 } 103 104 if (parent) { 105 data->isDirty = (parent->changed || data->isDirty) ? 1 : 0; 106 if (data->isDirty) { 107 rsMatrixLoad(globalMat, parent->mat); 108 rsMatrixMultiply(globalMat, localMat); 109 } 110 } else if (data->isDirty) { 111 rsMatrixLoad(globalMat, localMat); 112 } 113 114 ParentData toChild; 115 toChild.changed = 0; 116 toChild.mat = globalMat; 117 118 if (data->isDirty) { 119 toChild.changed = 1; 120 data->timestamp ++; 121 } 122 123 if (rsIsObject(data->children)) { 124 rs_allocation nullAlloc = {0}; 125 rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild)); 126 } 127 128 data->isDirty = 0; 129} 130