Beispiel #1
0
        bool ICullable.CullTest(ICuller culler)
        {
#if DEBUG
            return(true);
#else
            return(false);
#endif
        }
Beispiel #2
0
 internal bool CullChild(ICuller culler, ref Matrix instance)
 {
     if (modelData == null)
     {
         throw new InvalidOperationException("ModelData is null");
     }
     return(culler.TestBox(ref modelData.staticBounds.minimum, ref modelData.staticBounds.maximum, ref instance));
 }
        /// <summary>
        /// [Requires <see cref="SupportsHardwareInstancing"/>] Draws multiple instances of a vertex buffer in an efficient way, using an optional callback to determine if an instance should be drawn. Using Shader Instancing is highly recommended for smaller batches of simple geometry.
        /// </summary>
        /// <param name="vertices">Vertex buffer of the instances to be drawn</param>
        /// <param name="indices">Index buffer of the instances to be drawn</param>
        /// <param name="primitiveType">Primitive type to be drawn</param>
        /// <param name="CanDrawItem">[optional] callback to determine if an instance index should be drawn or not (may be null)</param>
        /// <param name="instances">Array of instances to draw</param>
        /// <param name="instancesLength">Number of instances in the array to draw</param>
        /// <returns>number of instances drawn</returns>
        /// <param name="startIndex">starting index in the <paramref name="instances"/> array</param>
        public int DrawBatch(Xen.Graphics.IVertices vertices, Graphics.IIndices indices, PrimitiveType primitiveType, Callback <bool, int, ICuller> CanDrawItem, Vector3[] instances, int instancesLength, int startIndex)
        {
            ValidateProtected();

            if (instancesLength == 0)
            {
                return(0);
            }

            StreamBuffer buffer = GetBuffer(instancesLength);
            int          start;

            Graphics.StreamFrequency.InstanceMatrix[] instanceMartixData = buffer.Prepare(out start);

            int count = 0;

            if (CanDrawItem != null)
            {
                ICuller culler = this;
                for (int i = 0; i < instancesLength; i++)
                {
                    PushWorldTranslateMultiply(ref instances[i + startIndex]);

                    if (CanDrawItem(i + startIndex, culler))
                    {
                        GetWorldMatrix(ref instanceMartixData[start++]);
                        count++;
                    }

                    PopWorldMatrix();
                }
            }
            else
            {
                if (ms_World.isIdentity || (instancesLength > 4 && ms_World.value == Matrix.Identity))
                {
                    for (int i = 0; i < instancesLength; i++)
                    {
                        instanceMartixData[start++].Set(ref instances[i + startIndex]);
                    }
                    count = instancesLength;
                }
                else
                {
                    for (int i = 0; i < instancesLength; i++)
                    {
                        PushWorldTranslateMultiply(ref instances[i + startIndex]);
                        instanceMartixData[start].Set(ref ms_World.value);
                        start++;
                        count++;
                        PopWorldMatrix();
                    }
                }
            }

            return(DrawBatch(buffer.Fill(vertices, count), indices, primitiveType, count));
        }
        public bool CullTest(ICuller culler)
        {
            //make sure the world matrix is up to date first
            UpdateWorldMatrix();

            //the model implements ICullableInstance interface, which allows a matrix to be passed in
            //the DepthDrawSorter requires a cull test be performed to sort this actor into front-back rendering order

            return(model.CullTest(culler, ref this.worldMatrix));
        }
Beispiel #5
0
        //Fully implement CullTest
        public bool CullTest(ICuller culler)
        {
            //cull test with a bounding box...
            //the box is represented as 'min / max' positions.
            //the vertex positions range from -1,-1,0 to 1,1,0

            //If the camera were changed, and this quad were offscreen, the cull test
            //would return false, and it would not be drawn.
            return(culler.TestBox(new Vector3(-1, -1, 0), new Vector3(1, 1, 0)));
        }
Beispiel #6
0
        //cull test ALL of them :-)
        public bool CullTest(ICuller culler)
        {
            bool visible = false;

            for (int i = 0; i < this.bursts.Length; i++)
            {
                visible |= this.bursts[i].CullTest(culler);
            }

            return(visible);
        }
Beispiel #7
0
        //Anything that implements IDraw (such as this class) also implements ICullable.
        //this requires an object to implement the CullTest method declared below.
        //CullTest returns true or false.
        //For the majority of cases, CullTest will perform frustum culling ('on-screen culling').
        //A return value of true means on-screen, false means off screen.
        //
        //The 'culler' object passed in is smart. It knows the current draw context,
        //for example it knows the world matrix.
        //
        //In the example above, the Sphere geometry class ('this.sphereGeometry') internally
        //implements CullTest as:
        //
        //return culler.TestSphere(this.radius);
        //
        //The sphere need not know where it is being drawn (ie, it's current world matrix)
        //because the ICuller already knows this.
        public bool CullTest(ICuller culler)
        {
            //in this case, however, simply return true.
            //this means 'always draw'.

            //This is because in this case, a world-matrix will be applied during the
            //draw() method, which will potentially change the result of the sphereGeometry
            //cull test.

            //What this means is that:

            //return sphereGeometry.CullTest(culler);

            //would be invalid here.

            //However,
            //culler.TestSphere(this.sphereGeometry.Radius, this.worldMatrix.Translation);
            //would be correct, assuming the world matrix was not scaling/rotating

            return(true);
        }
Beispiel #8
0
        /// <summary>
        /// FrustumCull test the model
        /// </summary>
        /// <param name="culler"></param>
        /// <returns></returns>
        public bool CullTest(ICuller culler)
        {
            if (modelData == null)
            {
                throw new InvalidOperationException("ModelData is null");
            }

            if (shaderProvider != null && shaderProvider.ProviderModifiesWorldMatrixInBeginDraw)
            {
                return(true);
            }

            if (controller == null)
            {
                return(culler.TestBox(ref modelData.staticBounds.minimum, ref modelData.staticBounds.maximum));
            }
            else
            {
                controller.WaitForAsyncAnimation(culler.GetState(), culler.FrameIndex, false);
                return(culler.TestBox(ref controller.boundsMin, ref controller.boundsMax));
            }
        }
Beispiel #9
0
        /// <summary>
        /// FrustumCull test the model at the given location
        /// </summary>
        public bool CullTest(ICuller culler, ref Matrix instance)
        {
            if (modelData == null)
            {
                return(false);
            }

            if (shaderProvider != null && shaderProvider.ProviderModifiesWorldMatrixInBeginDraw)
            {
                return(true);
            }

            if (controller == null)
            {
                return(culler.TestBox(ref modelData.staticBounds.minimum, ref modelData.staticBounds.maximum, ref instance));
            }
            else
            {
                controller.WaitForAsyncAnimation(culler.GetState(), culler.FrameIndex, false);
                return(culler.TestBox(ref controller.boundsMin, ref controller.boundsMax, ref instance));
            }
        }
		/// <summary>
		/// Cull test this box using a local world matrix
		/// </summary>
		public bool CullTest(ICuller culler, ref Matrix instance)
		{
			return culler.TestBox(ref min, ref max, ref instance);
		}
		public bool CullTest(ICuller culler)
		{
			//make sure the world matrix is up to date first
			UpdateWorldMatrix();

			//the model implements ICullableInstance interface, which allows a matrix to be passed in
			//the DepthDrawSorter requires a cull test be performed to sort this actor into front-back rendering order

			return model.CullTest(culler, ref this.worldMatrix);
		}
		//each instance will call this culling method
		public bool CullTestInstance(ICuller culler, ref Vector3 translation)
		{
			return culler.TestSphere(1,ref translation);
		}
Beispiel #13
0
 public bool CullTest(ICuller culler)
 {
     return(instanceCount > 0);
 }
		/// <summary></summary>
		/// <param name="culler"></param>
		/// <returns></returns>
		public bool CullTest(ICuller culler)
		{
			return addList.Count > 0 || CullTestItems(culler);
		}
Beispiel #15
0
 public bool CullTest(ICuller culler)
 {
     return(scene.CullTest(culler));
 }
Beispiel #16
0
        /// <summary>
        /// Draw the items in sorted order
        /// </summary>
        /// <param name="state"></param>
        public void Draw(DrawState state)
        {
            if (itemCount == 0)
            {
                return;
            }

            sortFrameIndex++;

            //sortEvery so many frames...
            if (sortFrameIndex > sortEvery)
            {
                sortFrameIndex = 0;                 // ok, time to sort
            }
            else
            {
                //otherwise,
                //draw using the previous frame sorting...

                if (sortMode == DepthSortMode.FrontToBack)
                {
                    for (int i = 0; i < previousFrameVisibleCount; i++)
                    {
                        IDraw item = items[i].item;
                        if (item.CullTest(state))
                        {
                            item.Draw(state);
                        }
                    }
                }
                else
                {
                    for (int i = previousFrameVisibleCount - 1; i >= 0; i--)
                    {
                        IDraw item = items[i].item;
                        if (item.CullTest(state))
                        {
                            item.Draw(state);
                        }
                    }
                }
                int drawn = 0;
                //draw the rest...
                for (int i = previousFrameVisibleCount; i < this.itemCount; i++)
                {
                    IDraw item = items[i].item;
                    if (item.CullTest(state))
                    {
                        item.Draw(state);
                        drawn++;
                    }
                }
                return;
            }

            //sort and draw...

            ICuller culler = state;

            state.PushPostCuller(postCuller);

            postCuller.BeginPreCullItem(state);

            int index           = 0;
            int visible         = 0;
            int backIndex       = itemCount - 1;
            int backIndexCulled = itemCount - 1;
            int unsortedItems   = 0;

            Vector3 position, camera, direction;

            state.Camera.GetCameraPosition(out camera);
            state.Camera.GetCameraViewDirection(out direction);

            for (int i = 0; i < itemCount; i++)
            {
                Entry item = items[index];

                postCuller.ResetPreCullItem();

                bool cullTest = item.item.CullTest(culler);

                if (cullTest && postCuller.TryGetPosition(out position))
                {
                    //keep item in the list
                    items[index] = items[visible];

                    //centre of cull tests
                    position.X -= camera.X;
                    position.Y -= camera.Y;
                    position.Z -= camera.Z;

                    float depth = direction.X * position.X + direction.Y * position.Y + direction.Z * position.Z;

                    if (depth > 0)
                    {
                        depth = position.X * position.X + position.Y * position.Y + position.Z * position.Z;
                    }

                    depths[visible] = depth;
                    items[visible]  = item;

                    visible++;
                    index++;
                }
                else
                {
                    //swap the back culled element to this one, don't increment index
                    items[index]           = items[backIndexCulled];
                    items[backIndexCulled] = item;
                    backIndexCulled--;

                    if (cullTest)
                    {
                        //as the last step, put this item at the very back.
                        items[backIndexCulled + 1] = items[backIndex];
                        items[backIndex]           = item;
                        depths[backIndex]          = item.addIndex;

                        backIndex--;
                        unsortedItems++;
                    }
                }
            }

            state.PopPostCuller();

            if (unsortedItems > 0)
            {
                backIndex++;

                //due to the way the algorithm works, the unsorted list is usually ordered like so:
                //1,2,3,4,5,6,7,0

                //so put the last element first, and check if they are out of order

                float lastD      = this.depths[this.itemCount - 1];
                Entry lastE      = this.items[this.itemCount - 1];
                bool  outOfOrder = lastD > this.depths[backIndex];

                for (int i = this.itemCount - 2; i >= backIndex; i--)
                {
                    if (i != this.itemCount - 2)
                    {
                        outOfOrder |= this.depths[i] > this.depths[i + 1];
                    }

                    this.items[i + 1]  = this.items[i];
                    this.depths[i + 1] = this.depths[i];
                }
                this.depths[backIndex] = lastD;
                this.items[backIndex]  = lastE;

                //draw the unsorted items in their add order (which was written to depths)
                //this sort won't be all that efficient
                if (outOfOrder)
                {
                    Array.Sort(this.depths, this.items, backIndex, unsortedItems);
                }

                for (int i = 0; i < unsortedItems; i++)
                {
                    items[backIndex++].item.Draw(state);
                }
            }

            if (visible > 0)
            {
                //if the frame hasn't changed, the items should already be in sorted order,
                //so this sort should be quick

                //test if the values are already sorted...
                float depth      = this.depths[0];
                bool  outOfOrder = false;
                for (int i = 1; i < visible; i++)
                {
                    outOfOrder |= depths[i] < depth;
                    depth       = depths[i];
                }

                if (outOfOrder)
                {
                    Array.Sort(this.depths, this.items, 0, visible);
                }

                if (sortMode == DepthSortMode.FrontToBack)
                {
                    for (int i = 0; i < visible; i++)
                    {
                        items[i].item.Draw(state);
                    }
                }
                else
                {
                    for (int i = visible - 1; i >= 0; i--)
                    {
                        items[i].item.Draw(state);
                    }
                }
            }
            previousFrameVisibleCount = visible;
        }
Beispiel #17
0
 public bool CullTest(ICuller culler)
 {
     return(culler.TestSphere(this.scale * 3, worldMatrix.Translation));
 }
		bool ICullable.CullTest(ICuller culler)
		{
#if DEBUG
			return true;
#else
			return false;
#endif
		}
		public bool CullTest(ICuller culler)
		{
			return parent.CullTestInstance(culler,ref translation);
		}
		public bool CullTest(ICuller culler)
		{
			return model.CullTest(culler, ref worldMatrix);
		}
Beispiel #21
0
 /// <summary>
 /// Run a cull test using the optional <see cref="CullProxy"/>
 /// </summary>
 /// <param name="culler"></param>
 /// <returns></returns>
 public bool CullTest(ICuller culler)
 {
     return(enabled && (cullProxy == null || cullProxy.CullTest(culler)));
 }
Beispiel #22
0
 bool ICullable.CullTest(ICuller culler)
 {
     return(itemCount > 0 && visible);
 }
			bool ICullable.CullTest(ICuller culler)
			{
				return true;
			}
		public bool CullTest(ICuller culler)
		{
			//apply the manual cull test
			return culler.TestSphere(this.sphereRadius, ref this.sphereOffset);
		}
Beispiel #25
0
 bool ICullable.CullTest(ICuller culler)
 {
     return(enabled);
 }
		public bool CullTest(ICuller culler)
		{
			return culler.TestSphere(this.effectRadius, ref this.effectPosition);
		}
Beispiel #27
0
 bool ICullable.CullTest(ICuller culler)
 {
     return(true);
 }
		//cull test ALL of them :-)
		public bool CullTest(ICuller culler)
		{
			bool visible = false;
			for (int i = 0; i < this.bursts.Length; i++)
				visible |= this.bursts[i].CullTest(culler);

			return visible;
		}
Beispiel #29
0
 //each instance will call this culling method
 public bool CullTestInstance(ICuller culler, ref Vector3 translation)
 {
     return(culler.TestSphere(1, ref translation));
 }
		public bool CullTest(ICuller culler)
		{
			return visible;
		}
 public bool CullTest(ICuller culler)
 {
     return(culler.TestBox(new Vector3(-radius, -radius, 0), new Vector3(radius, radius, 0)));
 }
		public bool CullTest(ICuller culler)
		{
			return culler.TestSphere(this.scale * 3, worldMatrix.Translation);
		}
		/// <summary>
		/// FrustumCull test the cube
		/// </summary>
		/// <param name="culler"></param>
		/// <returns></returns>
		public bool CullTest(ICuller culler) 
		{
			return culler.TestBox(ref min, ref max);
		}
		bool ICullable.CullTest(ICuller culler)
		{
			return Enabled;	//only draw when enabled
		}
		bool ICullable.CullTest(ICuller culler)
		{
			return itemCount > 0 && visible;
		}
Beispiel #36
0
 bool ICullable.CullTest(ICuller culler)
 {
     return(drawCount > 0);
 }
		public bool CullTest(ICuller culler)
		{
			return scene.CullTest(culler);
		}
Beispiel #38
0
 /// <summary>
 /// Cull test this instance of the BatchModel
 /// </summary>
 /// <param name="culler"></param>
 /// <returns></returns>
 public bool CullTest(ICuller culler)
 {
     return(parent.CullChild(culler));
 }
		bool ICullable.CullTest(ICuller culler)
		{
			return enabled;
		}
Beispiel #40
0
 /// <summary>
 /// Cull test this instance of the BatchModel
 /// </summary>
 public bool CullTest(ICuller culler, ref Matrix instance)
 {
     return(parent.CullChild(culler, ref instance));
 }
		public bool CullTest(ICuller culler)
		{
			//cull test with an bounding box...
			//this time taking into account the z values can also range between -1 and 1
			return culler.TestBox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1));
		}
Beispiel #42
0
 //cull test the avatar, in this case, the cull test is highly approximate.
 public bool CullTest(ICuller culler)
 {
     return(avatar.CullTest(culler));
 }
Beispiel #43
0
 public bool CullTest(ICuller culler)
 {
     return(model.CullTest(culler, ref worldMatrix));
 }
		//Fully implement CullTest
		public bool CullTest(ICuller culler)
		{
			//cull test with a bounding box...
			//the box is represented as 'min / max' positions.
			//the vertex positions range from -1,-1,0 to 1,1,0

			//If the camera were changed, and this quad were offscreen, the cull test
			//would return false, and it would not be drawn.
			return culler.TestBox(new Vector3(-1, -1, 0), new Vector3(1, 1, 0));
		}
Beispiel #45
0
 public bool CullTest(ICuller culler)
 {
     return(true);
 }
		public bool CullTest(ICuller culler)
		{
			return true;
			//return Model.CullTest(culler);
		}
Beispiel #47
0
 public bool CullTest(ICuller culler)
 {
     return _enabled;
 }
		public bool CullTest(ICuller culler)
		{
			return culler.TestBox(new Vector3(-radius, -radius, 0), new Vector3(radius, radius, 0));
		}
		/// <summary>Implemented by a subclass</summary>
		protected abstract bool CullTestItems(ICuller culler);
Beispiel #50
0
 /// <summary>
 /// FrustumCull test the cube
 /// </summary>
 /// <param name="culler"></param>
 /// <returns></returns>
 public bool CullTest(ICuller culler)
 {
     return(culler.TestBox(ref min, ref max));
 }
		public bool CullTest(ICuller culler)
		{
			return true;
		}
		/// <summary>Culltest the cone with a specified radius</summary>
        public bool CullTest(ICuller culler, float radius)
        {
            return culler.TestSphere(radius);
        }
Beispiel #53
0
 public bool CullTest(ICuller culler)
 {
     return(parent.CullTestInstance(culler, ref translation));
 }
		bool ICullable.CullTest(ICuller culler)
		{
			//cull test on a single bounding box
			return culler.TestBox(ref bounds.Min, ref bounds.Max);
		}
Beispiel #55
0
        //from here everything is the same as the previous example

        public bool CullTest(ICuller culler)
        {
            return(model.CullTest(culler));
        }
		/// <summary>
		/// Run a cull test using the optional <see cref="CullProxy"/>
		/// </summary>
		/// <param name="culler"></param>
		/// <returns></returns>
		public bool CullTest(ICuller culler)
		{
			return enabled && (cullProxy == null || cullProxy.CullTest(culler));
		}
Beispiel #57
0
 /// <summary>
 /// Cull test this box using a local world matrix
 /// </summary>
 public bool CullTest(ICuller culler, ref Matrix instance)
 {
     return(culler.TestBox(ref min, ref max, ref instance));
 }
		//Anything that implements IDraw (such as this class) also implements ICullable.
		//this requires an object implement the CullTest method declared below.
		//CullTest returns true or false.
		//
		//For the majority of cases, CullTest will perform frustum culling ('on-screen culling').
		//A return value of true means on-screen, false means off screen.
		//
		//The 'culler' object passed in is smart. It typically knows the current world matrix.
		//
		//In the example above, the Sphere geometry class ('this.sphereGeometry') internally
		//implements CullTest as:
		//
		// return culler.TestSphere(this.radius);
		//
		//The sphere need not know where it is being drawn (ie, it's current world matrix)
		//because the ICuller already knows this.
		public bool CullTest(ICuller culler)
		{
			//in this case, however, simply return true.
			//this means 'always draw'.

			//This is because in this case, a world-matrix will be applied during the
			//draw() method, which will potentially change the result of the sphereGeometry
			//cull test.
			
			//What this means is that:

			//return sphereGeometry.CullTest(culler);

			//would be invalid here.

			//However,
			//culler.TestSphere(this.sphereGeometry.Radius, this.worldMatrix.Translation);
			//would be correct, assuming the world matrix was not scaling/rotating
			
			return true;
		}
		/// <summary>
		/// Culltest the cone with a instance world matrix providing the postion of the cone
		/// </summary>
		public bool CullTest(ICuller culler, ref Matrix instance)
		{
			return culler.TestSphere(this.radius, instance.Translation);
		}
 public SimpleRenderer(IXNAGame game, ICuller culler)
 {
     this.game   = game;
     this.culler = culler;
     initialized = false;
 }