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