Home | History | Annotate | Download | only in scenegraph
      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 
     21 rs_script gTransformScript;
     22 
     23 typedef struct {
     24     int changed;
     25     rs_matrix4x4 *mat;
     26 } ParentData;
     27 
     28 //#define DEBUG_TRANSFORMS
     29 static 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 
     57 static 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 
     74 void 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