bool ICullable.CullTest(ICuller culler) { #if DEBUG return(true); #else return(false); #endif }
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)); }
//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))); }
//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); }
//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); }
/// <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)); } }
/// <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); }
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); }
public bool CullTest(ICuller culler) { return(scene.CullTest(culler)); }
/// <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; }
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); }
/// <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))); }
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); }
bool ICullable.CullTest(ICuller culler) { return(enabled); }
public bool CullTest(ICuller culler) { return culler.TestSphere(this.effectRadius, ref this.effectPosition); }
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; }
//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; }
bool ICullable.CullTest(ICuller culler) { return(drawCount > 0); }
public bool CullTest(ICuller culler) { return scene.CullTest(culler); }
/// <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; }
/// <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)); }
//cull test the avatar, in this case, the cull test is highly approximate. public bool CullTest(ICuller culler) { return(avatar.CullTest(culler)); }
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)); }
public bool CullTest(ICuller culler) { return(true); }
public bool CullTest(ICuller culler) { return true; //return Model.CullTest(culler); }
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);
/// <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); }
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); }
//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)); }
/// <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; }