public ArrayList UpdateFrustumSelection(Instance3DCollection InstanceList) { ArrayList selected_items = new ArrayList(); Plane[] fplanes; MdxRender.Camera.GetFrustumPlanes(selectionBoxStartX, selectionBoxStartY, selectionBoxEndX, selectionBoxEndY, out fplanes); float test; //there seems to be a little bit of a plane calculation bug, objects within the bounding box are //not always selected perfectly bool bInsideFrustum = false; int sel_count = 0; for (int i = 0; i < InstanceList.Count; i++) { bInsideFrustum = true; for (int p = 0; p < fplanes.Length; p++) //for(int p=0; p<2; p++) { test = InstanceList[i].Translation.X * fplanes[p].A + InstanceList[i].Translation.Y * fplanes[p].B + InstanceList[i].Translation.Z * fplanes[p].C + fplanes[p].D; if (test < 0) //test for behind plane (outside of frustum) (normals point to inside of frustum) { bInsideFrustum = false; break; } } InstanceList[i].Selected = bInsideFrustum; if (bInsideFrustum) { selected_items.Add(InstanceList[i]); sel_count++; } else { } } //Trace.WriteLine("---------------------------------"); //Trace.WriteLine(string.Format("selected: {0}/{1}", sel_count, this.Count)); //Trace.WriteLine(string.Format("near Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[0].A, fplanes[0].B, fplanes[0].C, fplanes[0].D)); //Trace.WriteLine(string.Format("far Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[1].A, fplanes[1].B, fplanes[1].C, fplanes[1].D)); //Trace.WriteLine(string.Format("right Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[2].A, fplanes[2].B, fplanes[2].C, fplanes[2].D)); //Trace.WriteLine(string.Format("left Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[3].A, fplanes[3].B, fplanes[3].C, fplanes[3].D)); //Trace.WriteLine(string.Format("top Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[4].A, fplanes[4].B, fplanes[4].C, fplanes[4].D)); //Trace.WriteLine(string.Format("Bottom Nx={0:N3} Ny={1:N3} Nz={2:N3} D={3:N3}", fplanes[5].A, fplanes[5].B, fplanes[5].C, fplanes[5].D)); return(selected_items); }
public void Render() { // View Frustum Culling //MdxRender.Camera.CalculateViewFrustum(); // Just for fun, I tried to implement frustum culling based on some code and articles // that I found. Long story short - it doesn't work ;p // Maybe it's on the right track and would be a good base to work off of? // Instance3DCollection culledObjects = new Instance3DCollection(); // foreach (Instance3D instance in this.InnerList) // { // // Looks like billboards don't have a bounding box. // if (instance.Model.m_BoundingBox == null) continue; // // Matrix viewMatrix = MdxRender.Camera.GetViewMatrix(); // Vector3 min = new Vector3(instance.Model.m_BoundingBox.min[0], // instance.Model.m_BoundingBox.min[1], // instance.Model.m_BoundingBox.min[2]); // min = Vector3.TransformCoordinate(min, MdxRender.Dev.Transform.View); // // Vector3 max = new Vector3(instance.Model.m_BoundingBox.max[0], // instance.Model.m_BoundingBox.max[1], // instance.Model.m_BoundingBox.max[2]); // max = Vector3.TransformCoordinate(max, MdxRender.Dev.Transform.View); // // if (MdxRender.Camera.CullAABB(min, max) > 0) // culledObjects.Add(instance); // } // Implemented a more .NET approach to distance sorting. // Resulted in a 6fps gain on my system (AthlonXP 3000+, Radeon 9800 Pro) Instance3DCollection culledObjects = this; culledObjects.DistanceSort(); for (int i = culledObjects.Count - 1; i >= 0; i--) { culledObjects[i].Render(); } //for(int i=0; i<Count; i++) // for(int i=Count-1; i>=0; i--) // { // temp = this[distanceSortArray[i]]; // temp.Render(); // } multiSelectBox.Render(); //m_DebugObject1.Render(); }