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 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 57static 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 80 debugTransform(data, parent); 81#endif //DEBUG_TRANSFORMS 82 83 rs_matrix4x4 *localMat = &data->localMat; 84 rs_matrix4x4 *globalMat = &data->globalMat; 85 86 // Refresh matrices if dirty 87 if (data->isDirty && rsIsObject(data->components)) { 88 bool resetLocal = false; 89 uint32_t numComponenets = rsAllocationGetDimX(data->components); 90 for (int i = 0; i < numComponenets; i ++) { 91 if (!resetLocal) { 92 // Reset our local matrix only for component transforms 93 rsMatrixLoadIdentity(localMat); 94 resetLocal = true; 95 } 96 const SgTransformComponent *comp = NULL; 97 comp = (const SgTransformComponent *)rsGetElementAt(data->components, i); 98 appendTransformation(comp->type, comp->value, localMat); 99 } 100 } 101 102 if (parent) { 103 data->isDirty = (parent->changed || data->isDirty) ? 1 : 0; 104 if (data->isDirty) { 105 rsMatrixLoad(globalMat, parent->mat); 106 rsMatrixMultiply(globalMat, localMat); 107 } 108 } else if (data->isDirty) { 109 rsMatrixLoad(globalMat, localMat); 110 } 111 112 ParentData toChild; 113 toChild.changed = 0; 114 toChild.mat = globalMat; 115 116 if (data->isDirty) { 117 toChild.changed = 1; 118 data->timestamp ++; 119 } 120 121 if (rsIsObject(data->children)) { 122 rs_allocation nullAlloc; 123 rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild)); 124 } 125 126 data->isDirty = 0; 127} 128