/// <summary> /// Inserts a node into the tree and returns "true" for success or "false" for failure. /// </summary> /// <param name="obj">the object to insert</param> /// <returns>"true" for success, "false" for failure</returns> public bool Insert(I3DObject obj) { var location = GetLocation(obj); switch (location) { case ObjectLocation.None: return(false); case ObjectLocation.Child: if (_children == null) { _children = CreateChildren(); } return(_children.Select(x => x.Insert(obj)).Aggregate((a, b) => a || b)); case ObjectLocation.Self: var tmpList = new List <I3DObject>(_objects) { obj }; _objects = tmpList.ToArray(); return(true); } throw new Exception("Unknown ObjectLocation"); }
public void Add(I3DObject o) { if (!Root.Insert(o, o.GetBoundingSphere())) { throw new Exception("Could not insert: " + o); } }
public int Add(BoxSpecs box, int level = 0, int location = 0) { I3DObject shape = CreateBox(box); if (level > 0 && location > 0) { bool succesfullAdd = facility[level, location].TryAdd(shape); if (succesfullAdd) { return(shape.Id); } return(-1); } for (int levels = 1; level < facility.GetLength(0); level++) { for (int locations = 1; locations < facility.GetLength(1); locations++) { if (facility[levels, locations].TryAdd(shape)) { return(shape.Id); } } } return(-1); }
public void Render() { Canvas.ClearObjects(); DrawGrid(); foreach (I3DObject o in Scene.DrawList) { I3DObject or = o; if (YRotation != 0) { or = or.RotateXZ(YRotation); } if (XRotation != 0) { or = or.RotateXY(XRotation); } if (ZRotation != 0) { or = or.RotateYZ(ZRotation); } or.Render(this); } }
protected override void RenderVertices(I3DObject obj) { BE.Alpha = obj.Alpha; BE.Texture = obj.Texture; base.RenderVertices(obj); }
protected virtual void RenderVertices(I3DObject obj) { ApplyPass(obj); GameInstanceProvider.Instance.GraphicsDevice.Indices = obj.IndexBuffer; GameInstanceProvider.Instance.GraphicsDevice.SetVertexBuffer(obj.VertexBuffer); GameInstanceProvider.Instance.GraphicsDevice.DrawIndexedPrimitives(_primitiveType, 0, 0, obj.IndexBuffer.IndexCount / 3); }
public new double GetReflectivityAt(Vect3 hitPoint) { I3DObject ret = GetObjectAt(hitPoint); if (ret != null) { return(ret.GetReflectivityAt(hitPoint)); } throw new Exception("internal error!"); }
public new Color GetColorAt(Vect3 hitPoint) { I3DObject ret = GetObjectAt(hitPoint); if (ret != null) { return(ret.GetColorAt(hitPoint)); } throw new Exception("internal error!"); }
public override Vect3 GetNormalAt(Vect3 hitPoint) { I3DObject ret = GetObjectAt(hitPoint); if (ret != null) { return(ret.GetNormalAt(hitPoint)); } throw new Exception("internal error!"); }
public void CheckCollisionSet(List <I3DObject> objects, Shapes.Ray ray) { foreach (I3DObject candidate in objects) { double distanceCandidate = candidate.GetHitPointDistance(ray); if (distanceCandidate > Constants.EPS && distanceCandidate < Distance) { Obj = candidate; Distance = distanceCandidate; } } }
public static ObjectCategory Create(I3DObject obj) { return(new ObjectCategory { IsVisible = obj.IsVisible, BlendStateId = GetBlendStateId(obj.BlendState), IsVisualObject = obj.IsVisualObject, Alpha = obj.Alpha, IsOpaque = obj.IsOpaque, TextureName = obj.Texture.Name, }); }
/// <summary> /// for a given object return the location where it should be inserted. /// where the object is inserted is determined by its bounding sphere. /// * if the sphere is bigger than the object or does not intersect -> dont insert /// * if it is bigger than half the size -> insert into own list /// * if it is smaller than that -> insert into a child node /// </summary> private ObjectLocation GetLocation(I3DObject obj) { var boundingSphere = obj.GetBoundingSphere(); if (boundingSphere.Radius > _halfWidth || !CubeSphere.IsSphereIntersectingCube(_center, _halfWidth, boundingSphere)) { return(ObjectLocation.None); } if (boundingSphere.Radius < _halfWidth / 2) { return(ObjectLocation.Child); } return(ObjectLocation.Self); }
public override void ApplyPass(I3DObject obj) { if (_encounterAnimationStarted) { if (obj is PlayerCharacter) { BE.DiffuseColor = Vector3.One; } else { BE.DiffuseColor = new Vector3(_encounterAnimationState * ENCOUNTER_WHITE_MULTIPLIER); } } else { BE.DiffuseColor = Vector3.One; } base.ApplyPass(obj); }
public virtual void Render(I3DObject obj) { if (obj.IsVisible && obj.IsVisualObject) { if (obj.BlendState != null) { if (obj.BlendState.Name != GameInstanceProvider.Instance.GraphicsDevice.BlendState.Name) { GameInstanceProvider.Instance.GraphicsDevice.BlendState = obj.BlendState; } } else { if (GameInstanceProvider.Instance.GraphicsDevice.BlendState.Name != BlendState.AlphaBlend.Name) { GameInstanceProvider.Instance.GraphicsDevice.BlendState = BlendState.AlphaBlend; } } World = obj.World; RenderVertices(obj); } }
public virtual void ApplyPass(I3DObject obj) { Effect.CurrentTechnique.Passes[0].Apply(); }
/** * Inserts an object into the subtree. The actual algorithms for building the tree are specified by TreeInsertStrategy. * * @param o the object to be added. * @param s the bounding sphere of the object - precomputed for memory and performance reasons * @return false if the object does not intersect/or is not enclosed by this subtree, true otherwise. */ public bool Insert(I3DObject o, Sphere s) { if (s == null) { //objects without bounding sphere will potentially intersect every ray Content.Add(o); return(true); } switch (Strategy) { case TreeInsertStrategy.LeafOnly: if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s)) { return(false); } if (_child != null) { _child[0].Insert(o, s); _child[1].Insert(o, s); _child[2].Insert(o, s); _child[3].Insert(o, s); _child[4].Insert(o, s); _child[5].Insert(o, s); _child[6].Insert(o, s); _child[7].Insert(o, s); } else { Content.Add(o); } if (_child == null && Content.Count > TreeInsertStrategyConstants.MaxElements && Width > TreeInsertStrategyConstants.MinWidth) { Split(); } return(true); case TreeInsertStrategy.FitIntoBox: if (!o.IsEnclosedByCube(Center, Width / 2)) { return(false); } if (_child != null) { if (_child[0].Insert(o, s) || _child[1].Insert(o, s) || _child[2].Insert(o, s) || _child[3].Insert(o, s) || _child[4].Insert(o, s) || _child[5].Insert(o, s) || _child[6].Insert(o, s) || _child[7].Insert(o, s)) { return(true); } } Content.Add(o); if (_child == null && Content.Count > TreeInsertStrategyConstants.MaxElements && Width > TreeInsertStrategyConstants.MinWidth) { Split(); } return(true); case TreeInsertStrategy.Dynamic: //if sphere is not touching cube -> error if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s)) { return(false); } //if object is enclosed by any child, add it there if (_child != null) { foreach (Node n in _child) { if (o.IsEnclosedByCube(n.Center, n.Width / 2)) { return(n.Insert(o, s)); } } } //if object is very small (in relation to the box) - duplicate it to child nodes //add it to this node otherwise if (_child != null && s.Radius / Width < TreeInsertStrategyConstants.DynamicDuplicateMaxSizeRatio) { _child[0].Insert(o, s); _child[1].Insert(o, s); _child[2].Insert(o, s); _child[3].Insert(o, s); _child[4].Insert(o, s); _child[5].Insert(o, s); _child[6].Insert(o, s); _child[7].Insert(o, s); } else { Content.Add(o); } //if node too full split it if (_child == null && Content.Count > 2 /*&&width>TreeInsertStrategy.DYNAMIC_MIN_WIDTH*/) { Split(); } return(true); case TreeInsertStrategy.DynamicTest: //if sphere is not touching cube -> error if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s)) { return(false); } //if object is enclosed by any child, add it there if (_child != null) { foreach (Node n in _child) { if (o.IsEnclosedByCube(n.Center, n.Width / 2)) { return(n.Insert(o, s)); } } bool i0 = CubeSphere.IsSphereIntersectingCube(_child[0].Center, _child[0].Width / 2, s), i1 = CubeSphere.IsSphereIntersectingCube(_child[1].Center, _child[1].Width / 2, s), i2 = CubeSphere.IsSphereIntersectingCube(_child[2].Center, _child[2].Width / 2, s), i3 = CubeSphere.IsSphereIntersectingCube(_child[3].Center, _child[3].Width / 2, s), i4 = CubeSphere.IsSphereIntersectingCube(_child[4].Center, _child[4].Width / 2, s), i5 = CubeSphere.IsSphereIntersectingCube(_child[5].Center, _child[5].Width / 2, s), i6 = CubeSphere.IsSphereIntersectingCube(_child[6].Center, _child[6].Width / 2, s), i7 = CubeSphere.IsSphereIntersectingCube(_child[7].Center, _child[7].Width / 2, s); int intersectionCount = 0; if (i0) { intersectionCount++; } if (i1) { intersectionCount++; } if (i2) { intersectionCount++; } if (i3) { intersectionCount++; } if (i4) { intersectionCount++; } if (i5) { intersectionCount++; } if (i6) { intersectionCount++; } if (i7) { intersectionCount++; } if (intersectionCount == 1 || intersectionCount * s.Radius / Width < 0.35) { if (i0) { _child[0].Insert(o, s); } if (i1) { _child[1].Insert(o, s); } if (i2) { _child[2].Insert(o, s); } if (i3) { _child[3].Insert(o, s); } if (i4) { _child[4].Insert(o, s); } if (i5) { _child[5].Insert(o, s); } if (i6) { _child[6].Insert(o, s); } if (i7) { _child[7].Insert(o, s); } return(true); } } Content.Add(o); //if node too full split it if (_child == null && Content.Count > 2) { Split(); } return(true); case TreeInsertStrategy.FastBuildTest: //if sphere is not touching cube -> error if (!CubeSphere.IsSphereIntersectingCube(Center, Width / 2, s)) { return(false); } //if object is enclosed by any child, add it there if (_child != null) { bool i0 = CubeSphere.IsSphereIntersectingCube(_child[0].Center, _child[0].Width / 2, s), i1 = CubeSphere.IsSphereIntersectingCube(_child[1].Center, _child[1].Width / 2, s), i2 = CubeSphere.IsSphereIntersectingCube(_child[2].Center, _child[2].Width / 2, s), i3 = CubeSphere.IsSphereIntersectingCube(_child[3].Center, _child[3].Width / 2, s), i4 = CubeSphere.IsSphereIntersectingCube(_child[4].Center, _child[4].Width / 2, s), i5 = CubeSphere.IsSphereIntersectingCube(_child[5].Center, _child[5].Width / 2, s), i6 = CubeSphere.IsSphereIntersectingCube(_child[6].Center, _child[6].Width / 2, s), i7 = CubeSphere.IsSphereIntersectingCube(_child[7].Center, _child[7].Width / 2, s); int intersectionCount = 0; if (i0) { intersectionCount++; } if (i1) { intersectionCount++; } if (i2) { intersectionCount++; } if (i3) { intersectionCount++; } if (i4) { intersectionCount++; } if (i5) { intersectionCount++; } if (i6) { intersectionCount++; } if (i7) { intersectionCount++; } if (intersectionCount == 1 || intersectionCount * s.Radius / Width < 0.5) { if (i0) { _child[0].Insert(o, s); } if (i1) { _child[1].Insert(o, s); } if (i2) { _child[2].Insert(o, s); } if (i3) { _child[3].Insert(o, s); } if (i4) { _child[4].Insert(o, s); } if (i5) { _child[5].Insert(o, s); } if (i6) { _child[6].Insert(o, s); } if (i7) { _child[7].Insert(o, s); } return(true); } } Content.Add(o); //if node too full split it if (_child == null && Content.Count > TreeInsertStrategyConstants.MaxElements && Width > TreeInsertStrategyConstants.DynamicMinWidth) { Split(); } return(true); default: throw new Exception("Mode not implemented: " + Strategy); } }
public static void Assignment7() { Random random = new Random(); int n = 100; I3DObject[] objects = new I3DObject[n]; for (int i = 0; i < n; i++) { switch(random.Next(3)) { case 0: objects[i] = new Box(random.NextDouble(), random.NextDouble(), random.NextDouble()); break; case 1: objects[i] = new Cylinder(random.NextDouble(), random.NextDouble()); break; case 2: objects[i] = new Sphere(random.NextDouble()); break; } } I3DObject largest = objects.OrderByDescending(o => o.Volume).FirstOrDefault(); Console.WriteLine("Largest shape: {0} ({1}m^3)", largest.GetType(), largest.Volume); Console.WriteLine("Total volume of all shapes: {0}", objects.Sum(o => o.Volume)); }