blob: 024e026b69dff125779e50072503e705714715bd [file] [log] [blame]
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma version(1)
#pragma rs java_package_name(com.android.scenegraph)
#include "scenegraph_objects.rsh"
static void getTransformedSphere(SgRenderable *obj) {
obj->worldBoundingSphere = obj->boundingSphere;
obj->worldBoundingSphere.w = 1.0f;
const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere);
const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f};
float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec);
scaledVec.w = 0.0f;
obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec);
}
static bool frustumCulled(SgRenderable *obj, SgCamera *cam) {
if (!obj->bVolInitialized) {
float minX, minY, minZ, maxX, maxY, maxZ;
rsgMeshComputeBoundingBox(obj->mesh,
&minX, &minY, &minZ,
&maxX, &maxY, &maxZ);
//rsDebug("min", minX, minY, minZ);
//rsDebug("max", maxX, maxY, maxZ);
float4 sphere;
sphere.x = (maxX + minX) * 0.5f;
sphere.y = (maxY + minY) * 0.5f;
sphere.z = (maxZ + minZ) * 0.5f;
float3 radius;
radius.x = (maxX - sphere.x);
radius.y = (maxY - sphere.y);
radius.z = (maxZ - sphere.z);
sphere.w = length(radius);
obj->boundingSphere = sphere;
obj->bVolInitialized = 1;
//rsDebug("Sphere", sphere);
}
getTransformedSphere(obj);
return !rsIsSphereInFrustum(&obj->worldBoundingSphere,
&cam->frustumPlanes[0], &cam->frustumPlanes[1],
&cam->frustumPlanes[2], &cam->frustumPlanes[3],
&cam->frustumPlanes[4], &cam->frustumPlanes[5]);
}
void root(rs_allocation *v_out, const void *usrData) {
SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
const SgCamera *camera = (const SgCamera*)usrData;
drawable->isVisible = 0;
// Not loaded yet
if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) {
return;
}
// check to see if we are culling this object and if it's
// outside the frustum
if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) {
#ifdef DEBUG_RENDERABLES
rsDebug("Culled", drawable);
printName(drawable->name);
#endif // DEBUG_RENDERABLES
return;
}
drawable->isVisible = 1;
}