public PCZCamera( string name, SceneManager sceneManager ) : base( name, sceneManager ) { this.box = new AxisAlignedBox( new Vector3( -0.1f, -0.1f, -0.1f ), new Vector3( 0.1f, 0.1f, 0.1f ) ); this.extraCullingFrustum = new PCZFrustum(); this.extraCullingFrustum.SetUseOriginPlane( true ); }
public void Merge( AxisAlignedBox boxBounds, Sphere sphereBounds, Camera cam, bool receiver ) { aabb.Merge( boxBounds ); if ( receiver ) receiverAabb.Merge( boxBounds ); Real camDistToCenter = ( cam.DerivedPosition - sphereBounds.Center ).Length; minDistance = System.Math.Min( minDistance, System.Math.Max( (Real)0, camDistToCenter - sphereBounds.Radius ) ); maxDistance = System.Math.Max( maxDistance, camDistToCenter + sphereBounds.Radius ); }
public OctreeZone( PCZSceneManager creator, string name ) : base( creator, name ) { mZoneTypeName = "ZoneType_Octree"; // init octree AxisAlignedBox b = new AxisAlignedBox( new Vector3( -10000, -10000, -10000 ), new Vector3( 10000, 10000, 10000 ) ); int depth = 8; rootOctree = null; Init( b, depth ); }
/// <summary> /// Default ctor. /// </summary> /// <param name="radius">Radius of orbits</param> /// <param name="count">Number of quads</param> /// <param name="qSize">Size of quads</param> public ThingRendable( float radius, int count, float qSize ) { this.radius = radius; this.count = count; this.qSize = qSize; box = new AxisAlignedBox( new Vector3( -radius, -radius, -radius ), new Vector3( radius, radius, radius ) ); Initialize(); FillBuffer(); }
public void TestMergePoint() { AxisAlignedBox actual = new AxisAlignedBox( new Vector3(0,0,0), new Vector3(50,50,50)); AxisAlignedBox expected = new AxisAlignedBox(new Vector3(0, 0, 0), new Vector3(150, 150, 150)); Vector3 point = new Vector3(150, 150, 150); actual.Merge(point); Assert.AreEqual(expected, actual); }
/// <summary> /// /// </summary> /// <param name="slices"></param> /// <param name="size"></param> /// <param name="texture"></param> public VolumeRendable( int slices, int size, string texture ) { this.slices = slices; this.size = size; this.texture = texture; this.radius = Utility.Sqrt( size*size + size*size + size*size )/2.0f; box = new AxisAlignedBox( new Vector3( -size, -size, -size ), new Vector3( size, size, size ) ); CastShadows = false; Initialize(); }
private GeometryBucket(MaterialBucket parent, String formatString, GeometryBucket bucket) : base() { mParent = parent; mFormatString = formatString; mBatch = mParent.Parent.Parent.Parent; if (mBatch.BaseSkeleton != null) { SetCustomParameter(0, new Vector4(mBatch.BaseSkeleton.BoneCount, 0, 0, 0)); } renderOperation = bucket.RenderOperation; mVertexData = renderOperation.vertexData; mIndexData = renderOperation.indexData; BoundingBox = new BoundingBox(new Vector3(-10000, -10000, -10000), new Vector3(10000, 10000, 10000)); }
public void Init( AxisAlignedBox box, int depth ) { if ( null != rootOctree ) rootOctree = null; rootOctree = new Octree( this, null ); maxDepth = depth; this.box = box; rootOctree.Box = box; Vector3 min = box.Minimum; Vector3 max = box.Maximum; rootOctree.HalfSize = ( max - min ) / 2; }
// this version checks against extra culling planes public new bool IsObjectVisible( AxisAlignedBox bound, out FrustumPlane culledBy ) { culledBy = FrustumPlane.None; // Null boxes always invisible if ( bound.IsNull ) { return false; } // infinite boxes always visible if ( bound.IsInfinite ) { return true; } // Make any pending updates to the calculated frustum planes UpdateFrustumPlanes(); // check extra culling planes bool extraResults; extraResults = this.extraCullingFrustum.IsObjectVisible( bound ); if ( !extraResults ) { return false; } // check "regular" camera frustum bool regcamresults = base.IsObjectVisible( bound, out culledBy ); if ( !regcamresults ) { // culled by regular culling planes return regcamresults; } return true; }
/// <summary> /// Allows for merging two boxes together (combining). /// </summary> /// <param name="box">Source box.</param> public void Merge(AxisAlignedBox box) { if (box.IsNull) { // nothing to merge with in this case, just return return; } else if (box.IsInfinite) { this.IsInfinite = true; } else if (this.IsNull) { SetExtents(box.Minimum, box.Maximum); } else if (!this.IsInfinite) { minVector.Floor(box.Minimum); maxVector.Ceil(box.Maximum); UpdateCorners(); } }
public OctreeSceneManager( string name ) : base( name ) { Vector3 Min = new Vector3( -500f, -500f, -500f ); Vector3 Max = new Vector3( 500f, 500f, 500f ); int depth = 5; AxisAlignedBox box = new AxisAlignedBox( Min, Max ); Init( box, depth ); }
protected void SetBounds( AxisAlignedBox box, float radius ) { this.aab = box; this.boundingRadius = radius; }
/// <summary> /// Calculate the area of intersection of this box and another /// </summary> public AxisAlignedBox Intersection(AxisAlignedBox b2) { if (!Intersects(b2)) { return(new AxisAlignedBox()); } Vector3 intMin = Vector3.Zero; Vector3 intMax = Vector3.Zero; Vector3 b2max = b2.maxVector; Vector3 b2min = b2.minVector; if (b2max.x > maxVector.x && maxVector.x > b2min.x) { intMax.x = maxVector.x; } else { intMax.x = b2max.x; } if (b2max.y > maxVector.y && maxVector.y > b2min.y) { intMax.y = maxVector.y; } else { intMax.y = b2max.y; } if (b2max.z > maxVector.z && maxVector.z > b2min.z) { intMax.z = maxVector.z; } else { intMax.z = b2max.z; } if (b2min.x < minVector.x && minVector.x < b2max.x) { intMin.x = minVector.x; } else { intMin.x = b2min.x; } if (b2min.y < minVector.y && minVector.y < b2max.y) { intMin.y = minVector.y; } else { intMin.y = b2min.y; } if (b2min.z < minVector.z && minVector.z < b2max.z) { intMin.z = minVector.z; } else { intMin.z = b2min.z; } return(new AxisAlignedBox(intMin, intMax)); }
public AxisAlignedBox( AxisAlignedBox box ) { SetExtents( box.Minimum, box.Maximum ); isNull = box.IsNull; isInfinite = box.IsInfinite; }
/// <summary> /// Internal method for locating a list of shadow casters which /// could be affecting the frustum for a given light. /// </summary> /// <remarks> /// Custom scene managers are encouraged to override this method to add optimizations, /// and to add their own custom shadow casters (perhaps for world geometry) /// </remarks> /// <param name="light"></param> /// <param name="camera"></param> protected virtual IList FindShadowCastersForLight( Light light, Camera camera ) { this.shadowCasterList.Clear(); if ( light.Type == LightType.Directional ) { // Basic AABB query encompassing the frustum and the extrusion of it AxisAlignedBox aabb = new AxisAlignedBox(); Vector3[] corners = camera.WorldSpaceCorners; Vector3 min, max; Vector3 extrude = light.DerivedDirection * -this.shadowDirLightExtrudeDist; // do first corner min = max = corners[ 0 ]; min.Floor( corners[ 0 ] + extrude ); max.Ceil( corners[ 0 ] + extrude ); for ( int c = 1; c < 8; ++c ) { min.Floor( corners[ c ] ); max.Ceil( corners[ c ] ); min.Floor( corners[ c ] + extrude ); max.Ceil( corners[ c ] + extrude ); } aabb.SetExtents( min, max ); if ( this.shadowCasterAABBQuery == null ) { this.shadowCasterAABBQuery = this.CreateAABBRegionQuery( aabb ); } else { this.shadowCasterAABBQuery.Box = aabb; } // Execute, use callback this.shadowCasterQueryListener.Prepare( false, light.GetFrustumClipVolumes( camera ), light, camera, this.shadowCasterList, light.ShadowFarDistanceSquared ); this.shadowCasterAABBQuery.Execute( this.shadowCasterQueryListener ); } else { Sphere s = new Sphere( light.DerivedPosition, light.AttenuationRange ); // eliminate early if camera cannot see light sphere if ( camera.IsObjectVisible( s ) ) { // create or init a sphere region query if ( this.shadowCasterSphereQuery == null ) { this.shadowCasterSphereQuery = this.CreateSphereRegionQuery( s ); } else { this.shadowCasterSphereQuery.Sphere = s; } // check if the light is within view of the camera bool lightInFrustum = camera.IsObjectVisible( light.DerivedPosition ); PlaneBoundedVolumeList volumeList = null; // Only worth building an external volume list if // light is outside the frustum if ( !lightInFrustum ) { volumeList = light.GetFrustumClipVolumes( camera ); } // prepare the query and execute using the callback this.shadowCasterQueryListener.Prepare( lightInFrustum, volumeList, light, camera, this.shadowCasterList, light.ShadowFarDistanceSquared ); this.shadowCasterSphereQuery.Execute( this.shadowCasterQueryListener ); } } return this.shadowCasterList; }
/// <summary> /// Creates a <see cref="AxisAlignedBoxRegionSceneQuery"/> for this scene manager. /// </summary> /// <remarks> /// This method creates a new instance of a query object for this scene manager, /// for querying for objects within a AxisAlignedBox region. /// </remarks> /// <param name="box">AxisAlignedBox to use for the region query.</param> /// <param name="mask">Custom user defined flags to use for the query.</param> /// <returns>A specialized implementation of AxisAlignedBoxRegionSceneQuery for this scene manager.</returns> public virtual AxisAlignedBoxRegionSceneQuery CreateAABBRegionQuery( AxisAlignedBox box, uint mask ) { DefaultAxisAlignedBoxRegionSceneQuery query = new DefaultAxisAlignedBoxRegionSceneQuery( this ); query.Box = box; query.QueryMask = mask; return query; }
/// <summary> /// Adds a bounding box to draw if turned on. /// </summary> protected void AddBoundingBox( AxisAlignedBox aab, bool visible ) { }
/* get the aabb of the zone - default implementation uses the enclosure node, but there are other perhaps better ways */ public virtual void GetAABB( ref AxisAlignedBox aabb ) { // if there is no node, just return a null box if ( null == this.mEnclosureNode ) { aabb = AxisAlignedBox.Null; } else { aabb = this.mEnclosureNode.WorldAABB; // since this is the "local" AABB, subtract out any translations aabb.Minimum = aabb.Minimum - this.mEnclosureNode.DerivedPosition; aabb.Maximum = aabb.Maximum - this.mEnclosureNode.DerivedPosition; } }
/*public void AddOctreeNode(OctreeNode node, Octree octree) { }*/ /** Resizes the octree to the given size */ public void Resize( AxisAlignedBox box ) { NodeCollection nodes = new NodeCollection(); FindNodes( this.octree.Box, base.sceneNodeList, null, true, this.octree ); octree = new Octree( null ); octree.Box = box; foreach ( OctreeNode node in nodes.Values ) { node.Octant = null; UpdateOctreeNode( node ); } }
public Intersection Intersect( Sphere sphere, AxisAlignedBox box ) { intersect++; float Radius = sphere.Radius; Vector3 Center = sphere.Center; Vector3[] Corners = box.Corners; float s = 0; float d = 0; int i; bool Partial; Radius *= Radius; Vector3 MinDistance = ( Corners[ 0 ] - Center ); Vector3 MaxDistance = ( Corners[ 4 ] - Center ); if ( ( MinDistance.LengthSquared < Radius ) && ( MaxDistance.LengthSquared < Radius ) ) { return Intersection.Inside; } //find the square of the distance //from the sphere to the box for ( i = 0; i < 3; i++ ) { if ( Center[ i ] < Corners[ 0 ][ i ] ) { s = Center[ i ] - Corners[ 0 ][ i ]; d += s * s; } else if ( Center[ i ] > Corners[ 4 ][ i ] ) { s = Center[ i ] - Corners[ 4 ][ i ]; d += s * s; } } Partial = ( d <= Radius ); if ( !Partial ) { return Intersection.Outside; } else { return Intersection.Intersect; } }
public OctreeSceneManager( string name, AxisAlignedBox box, int max_depth ) : base( name ) { Init( box, max_depth ); }
public AxisAlignedBox(AxisAlignedBox box) { SetExtents(box.Minimum, box.Maximum); isNull = box.IsNull; isInfinite = box.IsInfinite; }
/// <summary> /// Tests whether this ray intersects the given box. /// </summary> /// <param name="box"></param> /// <returns> /// Struct containing info on whether there was a hit, and the distance from the /// origin of this ray where the intersect happened. /// </returns> public IntersectResult Intersects(AxisAlignedBox box) { return(Utility.Intersects(this, box)); }
public Intersection Intersect( AxisAlignedBox box1, AxisAlignedBox box2 ) { intersect++; Vector3[] outside = box1.Corners; Vector3[] inside = box2.Corners; if ( inside[ 4 ].x < outside[ 0 ].x || inside[ 4 ].y < outside[ 0 ].y || inside[ 4 ].z < outside[ 0 ].z || inside[ 0 ].x > outside[ 4 ].x || inside[ 0 ].y > outside[ 4 ].y || inside[ 0 ].z > outside[ 4 ].z ) { return Intersection.Outside; } if ( inside[ 0 ].x > outside[ 0 ].x && inside[ 0 ].y > outside[ 0 ].y && inside[ 0 ].z > outside[ 0 ].z && inside[ 4 ].x < outside[ 4 ].x && inside[ 4 ].y < outside[ 4 ].y && inside[ 4 ].z < outside[ 4 ].z ) { return Intersection.Inside; } else { return Intersection.Intersect; } }
public new bool IsObjectVisible( AxisAlignedBox box, out FrustumPlane culledBy ) { if ( null != CullFrustum ) { return CullFrustum.IsObjectVisible( box, out culledBy ); } else { return base.IsObjectVisible( box, out culledBy ); } }
public void Init( AxisAlignedBox box, int depth ) { rootSceneNode = new OctreeNode( this, "SceneRoot" ); rootSceneNode.SetAsRootNode(); defaultRootNode = rootSceneNode; maxDepth = depth; octree = new Octree( null ); octree.Box = box; Vector3 Min = box.Minimum; Vector3 Max = box.Maximum; octree.HalfSize = ( Max - Min ) / 2; numObjects = 0; Vector3 scalar = new Vector3( 1.5f, 1.5f, 1.5f ); scaleFactor.Scale = scalar; }
public void Merge( AxisAlignedBox boxBounds, Sphere sphereBounds, Camera cam ) { Merge( boxBounds, sphereBounds, cam, true ); }
public void FindNodes( AxisAlignedBox box, SceneNodeCollection sceneNodeList, SceneNode exclude, bool full, Octree octant ) { List<OctreeNode> localList = new List<OctreeNode>(); if ( octant == null ) { octant = this.octree; } if ( !full ) { AxisAlignedBox obox = octant.CullBounds; Intersection isect = this.Intersect( box, obox ); if ( isect == Intersection.Outside ) { return; } full = ( isect == Intersection.Inside ); } foreach ( OctreeNode node in octant.NodeList.Values ) { if ( node != exclude ) { if ( full ) { localList.Add( node ); } else { Intersection nsect = this.Intersect( box, node.WorldAABB ); if ( nsect != Intersection.Outside ) { localList.Add( node ); } } } } if ( octant.Children[ 0, 0, 0 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 0, 0, 0 ] ); if ( octant.Children[ 1, 0, 0 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 1, 0, 0 ] ); if ( octant.Children[ 0, 1, 0 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 0, 1, 0 ] ); if ( octant.Children[ 1, 1, 0 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 1, 1, 0 ] ); if ( octant.Children[ 0, 0, 1 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 0, 0, 1 ] ); if ( octant.Children[ 1, 0, 1 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 1, 0, 1 ] ); if ( octant.Children[ 0, 1, 1 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 0, 1, 1 ] ); if ( octant.Children[ 1, 1, 1 ] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[ 1, 1, 1 ] ); }
/// <summary> /// Returns whether or not this sphere interects a box. /// </summary> /// <param name="box"></param> /// <returns>True if the box intersects, false otherwise.</returns> public bool Intersects(AxisAlignedBox box) { return(Utility.Intersects(this, box)); }
/* Functions for finding Nodes that intersect various shapes */ public abstract void FindNodes( AxisAlignedBox t, ref List<PCZSceneNode> list, List<Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude );
/// <summary> /// Calculate the area of intersection of this box and another /// </summary> public AxisAlignedBox Intersection( AxisAlignedBox b2 ) { if( !Intersects( b2 ) ) { return new AxisAlignedBox(); } Vector3 intMin = Vector3.Zero; Vector3 intMax = Vector3.Zero; Vector3 b2max = b2.maxVector; Vector3 b2min = b2.minVector; if( b2max.x > maxVector.x && maxVector.x > b2min.x ) { intMax.x = maxVector.x; } else { intMax.x = b2max.x; } if( b2max.y > maxVector.y && maxVector.y > b2min.y ) { intMax.y = maxVector.y; } else { intMax.y = b2max.y; } if( b2max.z > maxVector.z && maxVector.z > b2min.z ) { intMax.z = maxVector.z; } else { intMax.z = b2max.z; } if( b2min.x < minVector.x && minVector.x < b2max.x ) { intMin.x = minVector.x; } else { intMin.x = b2min.x; } if( b2min.y < minVector.y && minVector.y < b2max.y ) { intMin.y = minVector.y; } else { intMin.y = b2min.y; } if( b2min.z < minVector.z && minVector.z < b2max.z ) { intMin.z = minVector.z; } else { intMin.z = b2min.z; } return new AxisAlignedBox( intMin, intMax ); }
// --- find nodes which intersect various types of BV's --- public override void FindNodes( AxisAlignedBox t, ref List<PCZSceneNode> list, List<Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude ) { // if this zone has an enclosure, check against the enclosure AABB first if ( null != mEnclosureNode ) { if ( !mEnclosureNode.WorldAABB.Intersects( t ) ) { // AABB of zone does not intersect t, just return. return; } } foreach ( PCZSceneNode pczsn in mHomeNodeList ) { if ( pczsn != exclude ) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if ( !list.Contains( pczsn ) ) { bool nsect = t.Intersects( pczsn.WorldAABB ); if ( nsect ) { list.Add( pczsn ); } } } } if ( includeVisitors ) { // check visitor nodes foreach ( PCZSceneNode pczsn in mVisitorNodeList ) { if ( pczsn != exclude ) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if ( !list.Contains( pczsn ) ) { bool nsect = t.Intersects( pczsn.WorldAABB ); if ( nsect ) { list.Add( pczsn ); } } } } } // if asked to, recurse through portals if ( recurseThruPortals ) { foreach ( Portal portal in mPortals ) { // check portal versus bounding box if ( portal.intersects( t ) ) { // make sure portal hasn't already been recursed through if ( !visitedPortals.Contains( portal ) ) { // save portal to the visitedPortals list visitedPortals.Add( portal ); // recurse into the connected zone portal.getTargetZone().FindNodes( t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude ); } } } } }
/// <summary> /// Returns whether or not this box intersects another. /// </summary> /// <param name="box2"></param> /// <returns>True if the 2 boxes intersect, false otherwise.</returns> public bool Intersects( AxisAlignedBox box2 ) { // Early-fail for nulls if( this.IsNull || box2.IsNull ) { return false; } if( this.IsInfinite || box2.IsInfinite ) { return true; } // Use up to 6 separating planes if( this.maxVector.x < box2.minVector.x ) { return false; } if( this.maxVector.y < box2.minVector.y ) { return false; } if( this.maxVector.z < box2.minVector.z ) { return false; } if( this.minVector.x > box2.maxVector.x ) { return false; } if( this.minVector.y > box2.maxVector.y ) { return false; } if( this.minVector.z > box2.maxVector.z ) { return false; } // otherwise, must be intersecting return true; }
/// <summary> /// Creates a <see cref="AxisAlignedBoxRegionSceneQuery"/> for this scene manager. /// </summary> /// <remarks> /// This method creates a new instance of a query object for this scene manager, /// for querying for objects within a AxisAlignedBox region. /// </remarks> /// <param name="box">AxisAlignedBox to use for the region query.</param> /// <returns>A specialized implementation of AxisAlignedBoxRegionSceneQuery for this scene manager.</returns> public AxisAlignedBoxRegionSceneQuery CreateAABBRegionQuery( AxisAlignedBox box ) { return this.CreateAABBRegionQuery( box, 0xffffffff ); }
/// <summary> /// Allows for merging two boxes together (combining). /// </summary> /// <param name="box">Source box.</param> public void Merge( AxisAlignedBox box ) { if( box.IsNull ) { // nothing to merge with in this case, just return return; } else if( box.IsInfinite ) { this.IsInfinite = true; } else if( this.IsNull ) { SetExtents( box.Minimum, box.Maximum ); } else if( !this.IsInfinite ) { minVector.Floor( box.Minimum ); maxVector.Ceil( box.Maximum ); UpdateCorners(); } }
/// <summary> /// Sets the corners of the rectangle, in relative coordinates. /// </summary> /// <param name="left">Left position in screen relative coordinates, -1 = left edge, 1.0 = right edge.</param> /// <param name="top">Top position in screen relative coordinates, 1 = top edge, -1 = bottom edge.</param> /// <param name="right">Position in screen relative coordinates.</param> /// <param name="bottom">Position in screen relative coordinates.</param> /// <param name="updateAABB"></param> public void SetCorners( float left, float top, float right, float bottom, bool updateAABB ) { var data = new float[] { left, top, -1, left, bottom, -1, right, top, -1, // Fix for Issue #1187096 right, bottom, -1 }; var buffer = vertexData.vertexBufferBinding.GetBuffer( POSITION ); buffer.WriteData( 0, buffer.Size, data, true ); if ( updateAABB ) { box = new AxisAlignedBox(); box.SetExtents( new Vector3( left, top, 0 ), new Vector3( right, bottom, 0 ) ); } }
/// <summary> /// Calculate the area of intersection of this box and another /// </summary> public AxisAlignedBox Intersection(AxisAlignedBox b2) { if (!Intersects(b2)) { return(new AxisAlignedBox()); } var intMin = Vector3.Zero; var intMax = Vector3.Zero; var b2max = b2.maxVector; var b2min = b2.minVector; if (b2max.x > this.maxVector.x && this.maxVector.x > b2min.x) { intMax.x = this.maxVector.x; } else { intMax.x = b2max.x; } if (b2max.y > this.maxVector.y && this.maxVector.y > b2min.y) { intMax.y = this.maxVector.y; } else { intMax.y = b2max.y; } if (b2max.z > this.maxVector.z && this.maxVector.z > b2min.z) { intMax.z = this.maxVector.z; } else { intMax.z = b2max.z; } if (b2min.x < this.minVector.x && this.minVector.x < b2max.x) { intMin.x = this.minVector.x; } else { intMin.x = b2min.x; } if (b2min.y < this.minVector.y && this.minVector.y < b2max.y) { intMin.y = this.minVector.y; } else { intMin.y = b2min.y; } if (b2min.z < this.minVector.z && this.minVector.z < b2max.z) { intMin.z = this.minVector.z; } else { intMin.z = b2min.z; } return(new AxisAlignedBox(intMin, intMax)); }