decalSphere.cpp
Engine/source/T3D/decal/decalSphere.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "T3D/decal/decalSphere.h" 26 27#include "scene/zones/sceneZoneSpaceManager.h" 28#include "T3D/decal/decalInstance.h" 29 30 31F32 DecalSphere::smDistanceTolerance = 30.0f; 32F32 DecalSphere::smRadiusTolerance = 40.0f; 33 34 35//----------------------------------------------------------------------------- 36 37bool DecalSphere::tryAddItem( DecalInstance* inst ) 38{ 39 // If we are further away from the center than our tolerance 40 // allows, don't use this sphere. 41 // 42 // Note that we take the distance from the nearest point on the 43 // bounding sphere rather than the distance to the center of the 44 // decal. This takes decal sizes into account and generally works 45 // better. 46 47 const F32 distCenterToCenter = ( mWorldSphere.center - inst->mPosition ).len(); 48 const F32 distBoundsToCenter = distCenterToCenter - inst->mSize / 2.f; 49 50 if( distBoundsToCenter > smDistanceTolerance ) 51 return false; 52 53 // Also, if adding the current decal to the sphere would make 54 // it larger than our radius tolerance, don't use it. 55 56 const F32 newRadius = distCenterToCenter + inst->mSize / 2.f + 0.5f; 57 if( newRadius > mWorldSphere.radius && newRadius > smRadiusTolerance ) 58 return false; 59 60 // Otherwise, go with this sphere and add the item to it. 61 62 mItems.push_back( inst ); 63 64 // Update the sphere bounds, if necessary. 65 66 if( newRadius > mWorldSphere.radius ) 67 updateWorldSphere(); 68 69 return true; 70} 71 72//----------------------------------------------------------------------------- 73 74void DecalSphere::updateWorldSphere() 75{ 76 AssertFatal( mItems.size() >= 1, "DecalSphere::updateWorldSphere - Sphere is empty!" ); 77 78 Box3F aabb( mItems[ 0 ]->getWorldBox() ); 79 80 const U32 numItems = mItems.size(); 81 for( U32 i = 1; i < numItems; ++ i ) 82 aabb.intersect( mItems[ i ]->getWorldBox() ); 83 84 mWorldSphere = aabb.getBoundingSphere(); 85 86 // Clear the zoning data so that it gets recomputed. 87 mZones.clear(); 88} 89 90//----------------------------------------------------------------------------- 91 92void DecalSphere::updateZoning( SceneZoneSpaceManager* zoneManager ) 93{ 94 mZones.clear(); 95 96 // If there's only a single zone in the world, it must be the 97 // outdoor zone, so there's no point maintaining zoning information 98 // on all the decalspheres. 99 100 if( zoneManager->getNumZones() == 1 ) 101 return; 102 103 // Otherwise query the scene graph for all zones that intersect with the 104 // AABB around our world sphere. 105 106 Box3F aabb( mWorldSphere.radius ); 107 aabb.setCenter( mWorldSphere.center ); 108 109 zoneManager->findZones( aabb, mZones ); 110} 111