Home | History | Annotate | Download | only in scenegraph
      1 // Copyright (C) 2012 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.scenegraph)
     18 
     19 #include "scenegraph_objects.rsh"
     20 
     21 static void getTransformedSphere(SgRenderable *obj) {
     22     obj->worldBoundingSphere = obj->boundingSphere;
     23     obj->worldBoundingSphere.w = 1.0f;
     24     const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
     25     obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere);
     26 
     27     const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f};
     28     float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec);
     29     scaledVec.w = 0.0f;
     30     obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec);
     31 }
     32 
     33 static bool frustumCulled(SgRenderable *obj, SgCamera *cam) {
     34     if (!obj->bVolInitialized) {
     35         float minX, minY, minZ, maxX, maxY, maxZ;
     36         rsgMeshComputeBoundingBox(obj->mesh,
     37                                   &minX, &minY, &minZ,
     38                                   &maxX, &maxY, &maxZ);
     39         //rsDebug("min", minX, minY, minZ);
     40         //rsDebug("max", maxX, maxY, maxZ);
     41         float4 sphere;
     42         sphere.x = (maxX + minX) * 0.5f;
     43         sphere.y = (maxY + minY) * 0.5f;
     44         sphere.z = (maxZ + minZ) * 0.5f;
     45         float3 radius;
     46         radius.x = (maxX - sphere.x);
     47         radius.y = (maxY - sphere.y);
     48         radius.z = (maxZ - sphere.z);
     49 
     50         sphere.w = length(radius);
     51         obj->boundingSphere = sphere;
     52         obj->bVolInitialized = 1;
     53         //rsDebug("Sphere", sphere);
     54     }
     55 
     56     getTransformedSphere(obj);
     57 
     58     return !rsIsSphereInFrustum(&obj->worldBoundingSphere,
     59                                 &cam->frustumPlanes[0], &cam->frustumPlanes[1],
     60                                 &cam->frustumPlanes[2], &cam->frustumPlanes[3],
     61                                 &cam->frustumPlanes[4], &cam->frustumPlanes[5]);
     62 }
     63 
     64 
     65 void root(rs_allocation *v_out, const void *usrData) {
     66 
     67     SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
     68     const SgCamera *camera = (const SgCamera*)usrData;
     69 
     70     drawable->isVisible = 0;
     71     // Not loaded yet
     72     if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) {
     73         return;
     74     }
     75 
     76     // check to see if we are culling this object and if it's
     77     // outside the frustum
     78     if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) {
     79 #ifdef DEBUG_RENDERABLES
     80         rsDebug("Culled", drawable);
     81         printName(drawable->name);
     82 #endif // DEBUG_RENDERABLES
     83         return;
     84     }
     85     drawable->isVisible = 1;
     86 }
     87