SetExtents() public method

Sets both Minimum and Maximum at once, so that UpdateCorners only needs to be called once as well.
public SetExtents ( Vector3 min, Vector3 max ) : void
min Vector3
max Vector3
return void
Beispiel #1
0
		/// <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 ) );
			}
		}
Beispiel #2
0
		/// <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;
		}
Beispiel #3
0
		/// <summary>
		///		Utility method for extruding a bounding box.
		/// </summary>
		/// <param name="box">Original bounding box, will be updated in-place.</param>
		/// <param name="lightPosition">4D light position in object space, when w=0.0f this
		/// represents a directional light</param>
		/// <param name="extrudeDistance">The distance to extrude.</param>
		protected virtual void ExtrudeBounds( AxisAlignedBox box, Vector4 lightPosition, float extrudeDistance )
		{
			Vector3 extrusionDir = Vector3.Zero;

			if ( lightPosition.w == 0 )
			{
				extrusionDir.x = -lightPosition.x;
				extrusionDir.y = -lightPosition.y;
				extrusionDir.z = -lightPosition.z;
				extrusionDir.Normalize();
				extrusionDir *= extrudeDistance;
				box.SetExtents( box.Minimum + extrusionDir, box.Maximum + extrusionDir );
			}
			else
			{
				Vector3[] corners = box.Corners;
				Vector3 vmin = new Vector3();
				Vector3 vmax = new Vector3();

				for ( int i = 0; i < 8; i++ )
				{
					extrusionDir.x = corners[ i ].x - lightPosition.x;
					extrusionDir.y = corners[ i ].y - lightPosition.y;
					extrusionDir.z = corners[ i ].z - lightPosition.z;
					extrusionDir.Normalize();
					extrusionDir *= extrudeDistance;
					Vector3 res = corners[ i ] + extrusionDir;

					if ( i == 0 )
					{
						vmin = res;
						vmax = res;
					}
					else
					{
						vmin.Floor( res );
						vmax.Ceil( res );
					}
				}

				box.SetExtents( vmin, vmax );
			}
		}
Beispiel #4
0
		/// <summary>
		///     IsObjectVisible() function for portals.
		/// </summary>
		/// <remarks>
		///     Everything needs to be updated spatially before this function is
		///     called including portal corners, frustum planes, etc.
		/// </remarks>
		/// <param name="portal">
		///     The <see cref="Portal"/> to check visibility against.
		/// </param>
		/// <returns>
		///     true if the Portal is visible.
		/// </returns>
		public bool IsObjectVisible( Portal portal )
		{
			// if portal isn't open, it's not visible
			if ( !portal.IsOpen )
			{
				return false;
			}

			// if the frustum has no planes, just return true
			if ( mActiveCullingPlanes.Count == 0 )
			{
				return true;
			}
			// check if this portal is already in the list of active culling planes (avoid
			// infinite recursion case)
			foreach ( PCPlane plane in mActiveCullingPlanes )
			{
				if ( plane.Portal == portal )
				{
					return false;
				}
			}

			// if portal is of type AABB or Sphere, then use simple bound check against planes
			if ( portal.Type == PORTAL_TYPE.PORTAL_TYPE_AABB )
			{
				AxisAlignedBox aabb = new AxisAlignedBox();
				aabb.SetExtents( portal.getDerivedCorner( 0 ), portal.getDerivedCorner( 1 ) );
				return IsObjectVisible( aabb );
			}
			else if ( portal.Type == PORTAL_TYPE.PORTAL_TYPE_SPHERE )
			{
				return IsObjectVisible( portal.getDerivedSphere() );
			}

			// check if the portal norm is facing the frustum
			Vector3 frustumToPortal = portal.getDerivedCP() - mOrigin;
			Vector3 portalDirection = portal.getDerivedDirection();
			Real dotProduct = frustumToPortal.Dot( portalDirection );
			if ( dotProduct > 0 )
			{
				// portal is faced away from Frustum
				return false;
			}

			// check against frustum culling planes
			bool visible_flag;

			// Check originPlane if told to
			if ( mUseOriginPlane )
			{
				// set the visible flag to false
				visible_flag = false;
				// we have to check each corner of the portal
				for ( int corner = 0; corner < 4; corner++ )
				{
					PlaneSide side = mOriginPlane.GetSide( portal.getDerivedCorner( corner ) );
					if ( side != PlaneSide.Negative )
					{
						visible_flag = true;
					}
				}
				// if the visible_flag is still false, then the origin plane
				// culled all the portal points
				if ( visible_flag == false )
				{
					// ALL corners on negative side therefore out of view
					return false;
				}
			}

			// For each active culling plane, see if all portal points are on the negative
			// side. If so, the portal is not visible
			foreach ( PCPlane plane in mActiveCullingPlanes )
			{
				visible_flag = false;
				// we have to check each corner of the portal
				for ( int corner = 0; corner < 4; corner++ )
				{
					PlaneSide side = plane.GetSide( portal.getDerivedCorner( corner ) );
					if ( side != PlaneSide.Negative )
					{
						visible_flag = true;
					}
				}
				// if the visible_flag is still false, then this plane
				// culled all the portal points
				if ( visible_flag == false )
				{
					// ALL corners on negative side therefore out of view
					return false;
				}

			}

			// no plane culled all the portal points and the norm
			// was facing the frustum, so this portal is visible
			return true;
		}
		public unsafe void Initialize( int startx, int startz, Real[] pageHeightData )
		{

			if ( mOptions.maxGeoMipMapLevel != 0 )
			{
				int i = (int)1 << ( mOptions.maxGeoMipMapLevel - 1 );

				if ( ( i + 1 ) > mOptions.tileSize )
				{
					LogManager.Instance.Write( "Invalid maximum mipmap specifed, must be n, such that 2^(n-1)+1 < tileSize \n" );
					return;
				}
			}

			DeleteGeometry();

			//calculate min and max heights;
			Real min = 256000, max = 0;

			mTerrain = new VertexData();
			mTerrain.vertexStart = 0;
			mTerrain.vertexCount = mOptions.tileSize * mOptions.tileSize;

			renderOperation.useIndices = true;
			renderOperation.operationType = mOptions.useTriStrips ? OperationType.TriangleStrip : OperationType.TriangleList;
			renderOperation.vertexData = mTerrain;
			renderOperation.indexData = GetIndexData();

			VertexDeclaration decl = mTerrain.vertexDeclaration;
			VertexBufferBinding bind = mTerrain.vertexBufferBinding;

			// positions
			int offset = 0;
			decl.AddElement( MAIN_BINDING, offset, VertexElementType.Float3, VertexElementSemantic.Position );
			offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
			if ( mOptions.lit )
			{
				decl.AddElement( MAIN_BINDING, offset, VertexElementType.Float3, VertexElementSemantic.Position );
				offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
			}
			// texture coord sets
			decl.AddElement( MAIN_BINDING, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 );
			offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
			decl.AddElement( MAIN_BINDING, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1 );
			offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
			if ( mOptions.coloured )
			{
				decl.AddElement( MAIN_BINDING, offset, VertexElementType.Color, VertexElementSemantic.Diffuse );
				offset += VertexElement.GetTypeSize( VertexElementType.Color );
			}

			// Create shared vertex buffer
			mMainBuffer =
				HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( MAIN_BINDING ), mTerrain.vertexCount, BufferUsage.StaticWriteOnly );
			// Create system memory copy with just positions in it, for use in simple reads
			//mPositionBuffer = OGRE_ALLOC_T(float, mTerrain.vertexCount * 3, MEMCATEGORY_GEOMETRY);
			mPositionBuffer = new float[ mTerrain.vertexCount * 3 ];

			bind.SetBinding( MAIN_BINDING, mMainBuffer );

			if ( mOptions.lodMorph )
			{
				// Create additional element for delta
				decl.AddElement( DELTA_BINDING, 0, VertexElementType.Float1, VertexElementSemantic.BlendWeights );
				// NB binding is not set here, it is set when deriving the LOD
			}


			mInit = true;

			mRenderLevel = 0;

			mMinLevelDistSqr = new Real[ mOptions.maxGeoMipMapLevel ];

			int endx = startx + mOptions.tileSize;

			int endz = startz + mOptions.tileSize;

			Vector3 left, down, here;

			VertexElement poselem = decl.FindElementBySemantic( VertexElementSemantic.Position );
			VertexElement texelem0 = decl.FindElementBySemantic( VertexElementSemantic.TexCoords, 0 );
			VertexElement texelem1 = decl.FindElementBySemantic( VertexElementSemantic.TexCoords, 1 );
			//fixed ( float* pSysPos = mPositionBuffer )
			{
				int pos = 0;
				byte* pBase = (byte*)mMainBuffer.Lock( BufferLocking.Discard );

				for ( int j = startz; j < endz; j++ )
				{
					for ( int i = startx; i < endx; i++ )
					{
						float* pPos = (float*)( pBase + poselem.Offset );
						float* pTex0 = (float*)( pBase + texelem0.Offset );
						float* pTex1 = (float*)( pBase + texelem1.Offset );
						//poselem.baseVertexPointerToElement(pBase, &pPos);

						//texelem0.baseVertexPointerToElement(pBase, &pTex0);
						//texelem1.baseVertexPointerToElement(pBase, &pTex1);

						Real height = pageHeightData[ j * mOptions.pageSize + i ];
						height = height * mOptions.scale.y; // scale height

						//*pSysPos++ = *pPos++ = (float) i*mOptions.scale.x; //x
						//*pSysPos++ = *pPos++ = height; // y
						//*pSysPos++ = *pPos++ = (float) j*mOptions.scale.z; //z

						mPositionBuffer[ pos++ ] = *pPos++ = (float)i * mOptions.scale.x; //x
						mPositionBuffer[ pos++ ] = *pPos++ = height; // y
						mPositionBuffer[ pos++ ] = *pPos++ = (float)j * mOptions.scale.z; //z

						*pTex0++ = (float)i / (float)( mOptions.pageSize - 1 );
						*pTex0++ = (float)j / (float)( mOptions.pageSize - 1 );

						*pTex1++ = ( (float)i / (float)( mOptions.tileSize - 1 ) ) * mOptions.detailTile;
						*pTex1++ = ( (float)j / (float)( mOptions.tileSize - 1 ) ) * mOptions.detailTile;

						if ( height < min )
							min = (Real)height;

						if ( height > max )
							max = (Real)height;

						pBase += mMainBuffer.VertexSize;
					}
				}

				mMainBuffer.Unlock();
				mBounds = new AxisAlignedBox();
				mBounds.SetExtents( new Vector3( (Real)startx * mOptions.scale.x, min, (Real)startz * mOptions.scale.z ),
									new Vector3( (Real)( endx - 1 ) * mOptions.scale.x, max,
												 (Real)( endz - 1 ) * mOptions.scale.z ) );

				mCenter = new Vector3( ( startx * mOptions.scale.x + ( endx - 1 ) * mOptions.scale.x ) / 2,
									   ( min + max ) / 2,
									   ( startz * mOptions.scale.z + ( endz - 1 ) * mOptions.scale.z ) / 2 );
				boundingRadius = Math.Sqrt(
									  Utility.Sqr( max - min ) +
									  Utility.Sqr( ( endx - 1 - startx ) * mOptions.scale.x ) +
									  Utility.Sqr( ( endz - 1 - startz ) * mOptions.scale.z ) ) / 2;

				// Create delta buffer list if required to morph
				if ( mOptions.lodMorph )
				{
					// Create delta buffer for all except the lowest mip
					mDeltaBuffers = new AxiomSortedCollection<int, HardwareVertexBuffer>( mOptions.maxGeoMipMapLevel - 1 );
				}

				Real C = CalculateCFactor();

				CalculateMinLevelDist2( C );
			}
		}