public void Build() { this.depth = 0; BoundingBox box = new BoundingBox(new Vector3(float.MaxValue), new Vector3(float.MinValue)); this.root = new CubeNode(); root.id = 0; root.containingObjects = new List<Triangle>(this.objects); root.parent = null; root.children = null; for (int i = 0; i < this.objects.Count; i++) { // Kanske en metod i objekten som tar in en boundingb box och utökar den för att säkerställa att allt får plats. // "ExpandBoundingBox" "EnsureSpace" Vector3.Min(ref box.Min, ref this.objects[i].v1, out box.Min); Vector3.Min(ref box.Min, ref this.objects[i].v2, out box.Min); Vector3.Min(ref box.Min, ref this.objects[i].v3, out box.Min); Vector3.Max(ref box.Max, ref this.objects[i].v1, out box.Max); Vector3.Max(ref box.Max, ref this.objects[i].v2, out box.Max); Vector3.Max(ref box.Max, ref this.objects[i].v3, out box.Max); } root.bounds = box; this.BuildTree(ref root); }
public override void TouchesEnded(NSSet touches, UIEvent evt) { base.TouchesEnded(touches, evt); if (touches.AnyObject is UITouch touch) { var point = touch.LocationInView(this.sceneView); var hits = this.sceneView.HitTest(point, ARHitTestResultType.ExistingPlaneUsingExtent); var hit = hits.FirstOrDefault(); if (hit == null) { return; } var cubeNode = new CubeNode(0.05f, UIColor.White) { Position = new SCNVector3( hit.WorldTransform.Column3.X, hit.WorldTransform.Column3.Y + 0.1f, hit.WorldTransform.Column3.Z ) }; this.sceneView.Scene.RootNode.AddChildNode(cubeNode); } }
public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); sceneView.Session.Run(new ARWorldTrackingConfiguration { AutoFocusEnabled = true, LightEstimationEnabled = true, PlaneDetection = ARPlaneDetection.Horizontal, WorldAlignment = ARWorldAlignment.Gravity }, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors); CubeNode cubeNode = new CubeNode(size, UIColor.Blue); cubeNode.Position = new SCNVector3(0, 0, zPosition); sceneView.Scene.RootNode.AddChildNode(cubeNode); UITapGestureRecognizer tapGestureRecognizer = new UITapGestureRecognizer(HandleTapGesture); sceneView.AddGestureRecognizer(tapGestureRecognizer); UIPinchGestureRecognizer pinchGestureRecognizer = new UIPinchGestureRecognizer(HandlePinchGesture); sceneView.AddGestureRecognizer(pinchGestureRecognizer); }
public void AddTriangle( int cubeIndex, CubeNode n1, int axis1, CubeNode n2, int axis2, CubeNode n3, int axis3) { if (n1.Nb(axis1).Index() < n1.Index()) { n1 = n1.Nb(axis1); } if (n2.Nb(axis2).Index() < n2.Index()) { n2 = n2.Nb(axis2); } if (n3.Nb(axis3).Index() < n3.Index()) { n3 = n3.Nb(axis3); } IndexBuffer.Add(GetIndex(cubeIndex, n1, axis1)); IndexBuffer.Add(GetIndex(cubeIndex, n2, axis2)); IndexBuffer.Add(GetIndex(cubeIndex, n3, axis3)); IndexBuffer.Add(GetIndex(cubeIndex, n3, axis3)); IndexBuffer.Add(GetIndex(cubeIndex, n2, axis2)); IndexBuffer.Add(GetIndex(cubeIndex, n1, axis1)); }
//private SceneNodeBase GetRootNode() //{ // var group = new GroupNode(); // { // Texture texture = this.GetTexture(); // var node = FixedSizeQuadNode.Create(200, 100, texture); // group.Children.Add(node); // this.triangleNode = node; // } // return group; //} private SceneNodeBase GetTree() { const float length = 6; var group = new GroupNode(); { var floor = CubeNode.Create(); floor.Scale = new vec3(length, 0.1f, length); floor.Color = Color.Brown.ToVec4(); group.Children.Add(floor); } Texture texture = this.GetTexture(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { float x = -length / 2 + length / 2 * i; float y = 0.25f; float z = -length / 2 + length / 2 * j; var stick = CubeNode.Create(); stick.Scale = new vec3(0.1f, y * 2, 0.1f); stick.WorldPosition = new vec3(x, y, z); stick.Color = Color.Green.ToVec4(); group.Children.Add(stick); { var node = FixedSizeQuadNode.Create(200, 70, texture); node.WorldPosition = new vec3(0, y * 4, 0); stick.Children.Add(node); } } } return(group); }
private void FormMain_Load(object sender, EventArgs e) { var position = new vec3(5, 3, 4) * 1.6f; var center = new vec3(0, 0, 0); var up = new vec3(0, 1, 0); var camera = new Camera(position, center, up, CameraType.Perspecitive, this.winGLCanvas1.Width, this.winGLCanvas1.Height); this.scene = new Scene(camera); this.scene.ClearColor = Color.Black.ToVec4(); { var particlesNode = ParticlesNode.Create(10000); this.particleNode = particlesNode; var attractorsNode = AttractorsNode.Create(particlesNode); this.attractorsNode = attractorsNode; var cubeNode = CubeNode.Create(); cubeNode.RenderUnit.Methods[0].SwitchList.Add(new PolygonModeSwitch(PolygonMode.Line)); var groupNode = new GroupNode(particlesNode, attractorsNode);//, cubeNode); this.scene.RootNode = groupNode; } var list = new ActionList(); var transformAction = new TransformAction(scene); list.Add(transformAction); var renderAction = new RenderAction(scene); list.Add(renderAction); this.actionList = list; var manipulater = new FirstPerspectiveManipulater(); manipulater.Bind(camera, this.winGLCanvas1); }
public void Build() { this.depth = 0; BoundingBox box = new BoundingBox(Vector3.Zero, Vector3.Zero); this.root = new CubeNode(); root.id = 0; root.containingObjects = new List<ISpatialBody>(this.objects); root.parent = null; root.children = null; for (int i = 0; i < this.objects.Count; i++) { //BoundingBox worldBox = this.objects[i].WorldBoundingBox; BoundingBox transformedBox = this.objects[i].BoundingBox; Matrix world = (this.objects[i] as SceneObject).World; Vector3.Transform(ref transformedBox.Min, ref world, out transformedBox.Min); Vector3.Transform(ref transformedBox.Max, ref world, out transformedBox.Max); BoundingBox objectBox = new BoundingBox( Vector3.Min(transformedBox.Min, transformedBox.Max), Vector3.Max(transformedBox.Min, transformedBox.Max)); if (i == 0) { box = objectBox; } else { BoundingBox.CreateMerged(ref box, ref objectBox, out box); } } root.bounds = box; this.BuildTree(ref root); }
void drawMesh(CubeNode cnode, bool isChild) { GameObject gameObject; if (isChild) { gameObject = new GameObject(cnode.objectName); } else { gameObject = rootobj; gameObject.name = cnode.objectName; } gameObject.AddComponent <Rigidbody>(); gameObject.GetComponent <Rigidbody>().isKinematic = true; //GameObject gameObject = new GameObject (cnode.objectName); if (isChild) { gameObject.transform.SetParent(GameObject.Find(cnode.father.objectName).transform); gameObject.transform.localPosition = new Vector3(cnode.offset[0], cnode.offset[1], cnode.offset[2]); float rotx = Mathf.Clamp(cnode.pose[0] * Mathf.Rad2Deg, cnode.rxlimit[0] * Mathf.Rad2Deg, cnode.rxlimit[1] * Mathf.Rad2Deg); float roty = Mathf.Clamp(cnode.pose[1] * Mathf.Rad2Deg, cnode.rylimit[0] * Mathf.Rad2Deg, cnode.rylimit[1] * Mathf.Rad2Deg); float rotz = Mathf.Clamp(cnode.pose[2] * Mathf.Rad2Deg, cnode.rzlimit[0] * Mathf.Rad2Deg, cnode.rzlimit[1] * Mathf.Rad2Deg); gameObject.transform.localRotation = Quaternion.AngleAxis(rotz, Vector3.forward) * Quaternion.AngleAxis(roty, Vector3.up) * Quaternion.AngleAxis(rotx, Vector3.right); } }
public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); sceneView.Session.Run(new ARWorldTrackingConfiguration { AutoFocusEnabled = true, LightEstimationEnabled = true, PlaneDetection = ARPlaneDetection.Horizontal, WorldAlignment = ARWorldAlignment.Gravity }, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors); CubeNode cubeNode = new CubeNode(size, UIColor.Red); cubeNode.Position = new SCNVector3(0, 0, zPosition); SphereNode sphereNode = new SphereNode(size, UIColor.Yellow); sphereNode.Position = new SCNVector3(0.3f, 0, zPosition); TorusNode torusNode = new TorusNode(size / 2, size / 4, UIColor.Blue); torusNode.Position = new SCNVector3(0.6f, 0, zPosition); TubeNode tubeNode = new TubeNode(size / 2, size / 2, size * 2, UIColor.Orange); tubeNode.Position = new SCNVector3(0.9f, 0, zPosition); ConeNode coneNode = new ConeNode(0.0001f, size / 2, size * 2, UIColor.Green); coneNode.Position = new SCNVector3(0, -0.3f, zPosition); CylinderNode cylinderNode = new CylinderNode(size, size * 2, UIColor.Cyan); cylinderNode.Position = new SCNVector3(0.3f, -0.3f, zPosition); PyramidNode pyramidNode = new PyramidNode(size * 2, size * 2, size * 2, UIColor.Brown); pyramidNode.Position = new SCNVector3(0.6f, -0.3f, zPosition); PlaneNode planeNode = new PlaneNode(size, size, UIColor.Purple); planeNode.Position = new SCNVector3(0.9f, -0.3f, zPosition); TextNode textNode = new TextNode("Hello from ARKit", 0.01f, UIColor.Orange); textNode.Position = new SCNVector3(0, -0.85f, zPosition); sceneView.Scene.RootNode.AddChildNode(cubeNode); sceneView.Scene.RootNode.AddChildNode(sphereNode); sceneView.Scene.RootNode.AddChildNode(torusNode); sceneView.Scene.RootNode.AddChildNode(tubeNode); sceneView.Scene.RootNode.AddChildNode(coneNode); sceneView.Scene.RootNode.AddChildNode(cylinderNode); sceneView.Scene.RootNode.AddChildNode(pyramidNode); sceneView.Scene.RootNode.AddChildNode(planeNode); sceneView.Scene.RootNode.AddChildNode(textNode); }
public Vector3 Intermediate(CubeNode other) { float val = Mathf.Abs(Eval()); float nbVal = Mathf.Abs(other.Eval()); Vector3 p = Coords(); Vector3 nbP = other.Coords(); return(p + (nbP - p) * (val / (val + nbVal))); }
public int WhichAxis(CubeNode nb) { for (int i = 0; i < 3; i++) { if (Nb(i).Index() == nb.Index()) { return(i); } } return(-1); }
public IEnumerable <CubeNode> Nbs() { for (int i = 0; i < 3; i++) { CubeNode nb = Nb(i); if (nb.IsIn() == IsIn()) { yield return(nb); } } }
private int GetIndex(int cubeIndex, CubeNode node, int axis) { int key = cubeIndex * 8 + node.Index(); key = key * 4 + axis; if (BufferIndex.ContainsKey(key)) { return(BufferIndex[key]); } int index = VertexBuffer.Count; Vector3 position = node.Intermediate(axis); VertexBuffer.Add(position); NormalBuffer.Add(node.Normal(position)); BufferIndex.Add(key, index); return(index); }
private SceneNodeBase GetTree() { const float length = 6; var group = new GroupNode(); { var floor = CubeNode.Create(); floor.Scale = new vec3(length, 0.1f, length); floor.Color = Color.Brown.ToVec4(); group.Children.Add(floor); } { var textureSource = new BitmapTextureSource("Lenna.png"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { float x = -length / 2 + length / 2 * i; float y = 0.25f; float z = -length / 2 + length / 2 * j; var stick = CubeNode.Create(); stick.Scale = new vec3(0.1f, y * 2, 0.1f); stick.WorldPosition = new vec3(x, y, z); stick.Color = Color.Green.ToVec4(); group.Children.Add(stick); { //var billboard = TextBillboardNodeBackup.Create(textureSource, 200, 40); var billboard = TextBillboardNode.Create(200, 40, 100); billboard.Text = string.Format("Hello Billboard[{0}]!", i * 3 + j); billboard.Color = Color.White.ToVec3(); billboard.EnableRendering = ThreeFlags.None;// we don't render it in RenderAction. we render it in BillboardRenderAction. billboard.WorldPosition = new vec3(0, y * 4, 0); stick.Children.Add(billboard); } } } } return(group); }
private void SplitCuboid(CubeNode parent) { Vector3 cubePosition; Vector3 cubeSize = (parent.bounds.Max - parent.bounds.Min) / 2f; parent.children = new CubeNode[8]; uint index = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { CubeNode child = new CubeNode(); cubePosition = parent.bounds.Min + new Vector3(cubeSize.X * i, cubeSize.Y * j, cubeSize.Z * k); child.bounds = new BoundingBox(cubePosition, cubePosition + cubeSize); child.parent = parent; child.id = parent.id + index + 2; child.containingObjects = new List<Triangle>(); parent.children[index++] = child; for (int objectIndex = 0; objectIndex < parent.containingObjects.Count; objectIndex++) { if(child.bounds.Contains(parent.containingObjects[objectIndex].v1) != ContainmentType.Disjoint || child.bounds.Contains(parent.containingObjects[objectIndex].v2) != ContainmentType.Disjoint || child.bounds.Contains(parent.containingObjects[objectIndex].v3) != ContainmentType.Disjoint) { child.containingObjects.Add(parent.containingObjects[objectIndex]); } } } } } }
//SortedDictionary<float, CubeNode> private void GetRayCubeNodeIntersections(ref Ray ray, CubeNode current, SortedList<float, List<CubeNode>> cuboids) { float? result; current.bounds.Intersects(ref ray, out result); if (result.HasValue) { if (current.children != null) { for (int i = 0; i < 8; i++) { GetRayCubeNodeIntersections(ref ray, current.children[i], cuboids); } } else { if (cuboids.ContainsKey(result.Value)) { cuboids[result.Value].Add(current); } else { cuboids.Add(result.Value, new List<CubeNode>() { current }); } } } }
private void AddBody(ISpatialBody body, CubeNode node) { if (node.bounds.Intersects(body.WorldBoundingBox)) { node.containingObjects.Add(body); if (node.children != null) { for (int i = 0; i < 8; i++) { AddBody(body, node.children[i]); } } } }
public Vector3 Intermediate(int axis) { CubeNode other = Nb(axis); return(Intermediate(other)); }
private void DrawNode(Camera camera, ref Matrix view, ref Matrix proj, CubeNode node, GraphicsDevice device, GameTime gameTime) { #if DEBUG if (node.box == null) { node.box = new DrawableBox(device, node.bounds); } Matrix identity = Matrix.Identity; node.box.Draw(device, ref view, ref proj, ref identity); #endif //this.objects.Sort(new Comparison<ISpatialBody>(fo)); //for (int i = 0; i < this.objects.Count; i++) // (this.objects[i] as GameObject3D).Draw(ref view, ref proj, gameTime); //return; if (camera.BoundingFrustum.Intersects(node.bounds)) { for (int i = 0; i < node.containingObjects.Count; i++) { if (camera.BoundingFrustum.Intersects(node.containingObjects[i].BoundingBox)) { (node.containingObjects[i] as SceneObject).Draw(ref view, ref proj, device, gameTime); //node.containingObjects[i].BoundingBox.Draw(device); } } if (node.children != null) { for (int i = 0; i < 8; i++) { DrawNode(camera, ref view, ref proj, node.children[i], device, gameTime); } } } }
private void BuildTree(ref CubeNode parent) { if (parent.containingObjects.Count > this.itemTreshold) { this.depth++; this.SplitCuboid(parent); for (int i = 0; i < 8; i++) { BuildTree(ref parent.children[i]); } } }
private CubeNode FindCommonParent(CubeNode current, CubeNode nodeA, CubeNode nodeB) { if (current == null) return null; while (nodeA.depth > nodeB.depth) { nodeA = nodeA.parent; } while (nodeB.depth > nodeA.depth) { nodeB = nodeB.parent; } while (nodeA.id != nodeB.id) { nodeA = nodeA.parent; nodeB = nodeB.parent; } return nodeA; }
void parseSkel() { Stack <CubeNode> stackCube = new Stack <CubeNode>(); List <string> lines = new List <string> (File.ReadAllLines(skelPath)); string childName = ""; CubeNode root = null; string[] childSplit; float[] nowOffset = { 0, 0, 0 }; float[] nowBoxmin = { -0.1f, -0.1f, -0.1f }; float[] nowBoxmax = { 0.1f, 0.1f, 0.1f }; float[] nowPose = { 0, 0, 0 }; float[] nowRotxlimit = { -100000, 100000 }; float[] nowRotylimit = { -100000, 100000 }; float[] nowRotzlimit = { -100000, 100000 }; for (int i = 0; i < lines.Count; i = i + 1) { lines[i] = lines[i].Replace(" ", " "); lines[i] = lines[i].Replace(" ", " "); lines[i] = lines[i].Replace(" ", " "); lines[i] = lines[i].Replace(" ", " "); lines[i] = lines[i].Replace(" ", " "); if (lines[i][0] == ' ') { lines[i] = lines[i].Substring(1); } } for (int i = 0; i < lines.Count; i = i + 1) { if (lines[i].Contains("{")) { childSplit = lines [i].Split(' '); childName = childSplit [1]; i = i + 1; print(childName); while (!lines[i].Contains("{") && !lines[i].Contains("}")) { if (lines[i].Contains("offset")) { childSplit = lines [i].Split(' '); nowOffset[0] = float.Parse(childSplit[1]); nowOffset[1] = float.Parse(childSplit[2]); nowOffset[2] = float.Parse(childSplit[3]); } if (lines[i].Contains("boxmin")) { childSplit = lines [i].Split(' '); nowBoxmin[0] = float.Parse(childSplit[1]); nowBoxmin[1] = float.Parse(childSplit[2]); nowBoxmin[2] = float.Parse(childSplit[3]); } if (lines[i].Contains("boxmax")) { childSplit = lines [i].Split(' '); nowBoxmax[0] = float.Parse(childSplit[1]); nowBoxmax[1] = float.Parse(childSplit[2]); nowBoxmax[2] = float.Parse(childSplit[3]); } if (lines[i].Contains("pose")) { childSplit = lines [i].Split(' '); nowPose[0] = float.Parse(childSplit[1]); nowPose[1] = float.Parse(childSplit[2]); nowPose[2] = float.Parse(childSplit[3]); } if (lines[i].Contains("rotxlimit")) { childSplit = lines [i].Split(' '); nowRotxlimit[0] = float.Parse(childSplit[1]); nowRotxlimit[1] = float.Parse(childSplit[2]); } if (lines[i].Contains("rotylimit")) { childSplit = lines [i].Split(' '); nowRotylimit[0] = float.Parse(childSplit[1]); nowRotylimit[1] = float.Parse(childSplit[2]); } if (lines[i].Contains("rotzlimit")) { childSplit = lines [i].Split(' '); nowRotzlimit[0] = float.Parse(childSplit[1]); nowRotzlimit[1] = float.Parse(childSplit[2]); } i = i + 1; } CubeNode childNode = null; if (root == null) { childNode = new CubeNode(childName, null, nowOffset, nowBoxmin, nowBoxmax, nowPose, nowRotxlimit, nowRotylimit, nowRotzlimit); root = childNode; drawMesh(childNode, false); } else { childNode = new CubeNode(childName, stackCube.Peek(), nowOffset, nowBoxmin, nowBoxmax, nowPose, nowRotxlimit, nowRotylimit, nowRotzlimit); drawMesh(childNode, true); } stackCube.Push(childNode); i = i - 1; } if (lines[i].Contains("}") && stackCube.Count != 0) { stackCube.Pop(); } } }
private void button1_Click(object sender, EventArgs e) { switch (listBox1.SelectedItem) { case "SkyboxNode": string sn_skybox = "Content/skybox.png"; InputBoxes.ShowInputDialog(ref sn_skybox, "Skybox"); SkyboxNode node = SkyboxNode.Create(new Bitmap(Image.FromFile(sn_skybox))); node.Name = "NewSkybox"; node.Parent = nodebase; break; case "TextBillboardNode": string sn_billboard = "Hello World!"; TextBillboardNode textBillboardNode = TextBillboardNode.Create(200, 40, 65535); textBillboardNode.Name = "NewBillboard"; textBillboardNode.Parent = nodebase; textBillboardNode.Text = sn_billboard; textBillboardNode.EnableRendering = ThreeFlags.None; break; case "CubeNode": CubeNode cube = CubeNode.Create(); cube.Name = "NewCube"; cube.Parent = nodebase; break; case "ShadowVolumeNode": CubeModel model = new CubeModel(); string sv_pos = CubeModel.strPosition; string sv_normal = "0 0 0"; InputBoxes.ShowInputDialog(ref sv_pos, "Volume Position"); InputBoxes.ShowInputDialog(ref sv_pos, "Volume Normal"); ShadowVolumeNode shadow = ShadowVolumeNode.Create(model, sv_pos, sv_normal, new vec3(1, 1, 1)); shadow.Name = "NewLight"; shadow.Parent = nodebase; break; case "TerrainNode": TerrainNode terrain = TerrainNode.Create(); terrain.Parent = nodebase; terrain.Name = "NewTerrain"; break; case "SpotLightNode": CubeModel sp_model = new CubeModel(); string sp_pos = "0 0 0"; string sp_target = "0 0 0"; InputBoxes.ShowInputDialog(ref sp_pos, "Volume Position"); InputBoxes.ShowInputDialog(ref sp_target, "Volume Target"); string[] sppositions_STR = sp_pos.Split(' '); vec3 sp_posv = new vec3(float.Parse(sppositions_STR[0]), float.Parse(sppositions_STR[1]), float.Parse(sppositions_STR[2])); string[] sptarget_STR = sp_target.Split(' '); vec3 sp_tarv = new vec3(float.Parse(sptarget_STR[0]), float.Parse(sptarget_STR[1]), float.Parse(sptarget_STR[2])); SpotLight spotlight = new SpotLight(sp_posv, sp_tarv, 45); SpotLightNode spotlightnode = SpotLightNode.Create(spotlight, sp_model, sp_pos, sp_pos, new vec3(1, 1, 1)); spotlightnode.Parent = nodebase; spotlightnode.Name = "NewSpotlight"; lastspotlight = spotlight; break; case "CubeLightTestNode": CubeLightTestNode cubeLightTest = CubeLightTestNode.Create(); cubeLightTest.Parent = nodebase; cubeLightTest.Name = "NewCubeLightTest"; cubeLightTest.SetLight(lastspotlight); break; } src_form.Match(src_form.treeView, nodebase); AudioSystem.PlayAudio("GameSounds/clickfast.wav"); Close(); }
private void AddBody(Triangle body, CubeNode node) { // En metod för där en "body" rapporterar om den är innuti en cuboid eller ej. if (node.bounds.Contains(body.v1) != ContainmentType.Disjoint || node.bounds.Contains(body.v2) != ContainmentType.Disjoint || node.bounds.Contains(body.v3) != ContainmentType.Disjoint) { node.containingObjects.Add(body); if (node.children != null) { for (int i = 0; i < 8; i++) { AddBody(body, node.children[i]); } } } }
private void SplitCuboid(CubeNode parent) { Vector3 cubePosition; Vector3 cubeSize = (parent.bounds.Max - parent.bounds.Min) / 2f; parent.children = new CubeNode[8]; uint index = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { CubeNode child = new CubeNode(); cubePosition = parent.bounds.Min + new Vector3(cubeSize.X * i, cubeSize.Y * j, cubeSize.Z * k); child.bounds = new BoundingBox(cubePosition, cubePosition + cubeSize); child.parent = parent; child.id = parent.id + index + 2; child.containingObjects = new List<ISpatialBody>(); parent.children[index++] = child; for (int objectIndex = 0; objectIndex < parent.containingObjects.Count; objectIndex++) { if (parent.containingObjects[objectIndex].WorldBoundingBox.Intersects(child.bounds)) { child.containingObjects.Add(parent.containingObjects[objectIndex]); } } } } } }
public void Draw() { bool[] processed = new bool[8]; foreach (CubeNode nd in Vertices()) { if (debug) { GD.Print(nd.x, " ", nd.y, " ", nd.z, " ", nd.IsIn()); } if (processed[nd.Index()]) { continue; } HashSet <CubeNode> connected = nd.AllConnected(); if (debug) { GD.Print(connected.Count); } if (connected.Count == 1) { if (debug) { GD.Print("Single"); } meshBuilder.AddTriangle(cubeIndex, nd, 0, nd, 1, nd, 2); processed[nd.Index()] = true; continue; } if (connected.Count == 2) { IEnumerator <CubeNode> e = connected.GetEnumerator(); e.MoveNext(); CubeNode n1 = e.Current; e.MoveNext(); CubeNode n2 = e.Current; int nbAxis = n1.WhichAxis(n2); meshBuilder.AddTriangle(cubeIndex, n1, (nbAxis + 1) % 3, n2, (nbAxis + 1) % 3, n2, (nbAxis + 2) % 3); meshBuilder.AddTriangle(cubeIndex, n2, (nbAxis + 2) % 3, n1, (nbAxis + 2) % 3, n1, (nbAxis + 1) % 3); if (debug) { GD.Print("Double"); } processed[n1.Index()] = true; processed[n2.Index()] = true; continue; } if (connected.Count == 3) { // find middle elem CubeNode md = nd; foreach (CubeNode n in connected) { if (n.CountNbs() == 2) { md = n; } } int axis = 0; for (int i = 0; i < 3; i++) { if (md.Nb(i).IsIn() != md.IsIn()) { axis = i; } } CubeNode nb1 = md.Nb((axis + 1) % 3); CubeNode nb2 = md.Nb((axis + 2) % 3); Vector3 intermediate1 = nb1.Intermediate(axis); Vector3 intermediate2 = nb2.Intermediate(axis); // parallel meshBuilder.AddTriangle(cubeIndex, md, axis, nb1, axis, nb2, axis); // part 1 meshBuilder.AddTriangle(cubeIndex, nb1, axis, nb2, axis, nb1, (axis + 2) % 3); // part 2 meshBuilder.AddTriangle(cubeIndex, nb1, (axis + 2) % 3, nb2, (axis + 1) % 3, nb2, axis); if (debug) { GD.Print("Trio"); } processed[md.Index()] = true; processed[nb1.Index()] = true; processed[nb2.Index()] = true; continue; } if (connected.Count > 4) { foreach (CubeNode c in connected) { processed[c.Index()] = true; } continue; } if (!nd.IsIn()) { foreach (CubeNode c in connected) { processed[c.Index()] = true; } continue; } // connected.Count is 4 // square, tetra or line CubeNode mid = nd; bool tetra = false; foreach (CubeNode c in connected) { if (c.CountNbs() == 3) { // tetra mid = c; tetra = true; } } if (tetra) { CubeNode n0 = mid.Nb(0); CubeNode n1 = mid.Nb(1); CubeNode n2 = mid.Nb(2); meshBuilder.AddTriangle(cubeIndex, n0, 1, n1, 0, n1, 2); meshBuilder.AddTriangle(cubeIndex, n0, 1, n1, 2, n0, 2); meshBuilder.AddTriangle(cubeIndex, n1, 2, n0, 2, n2, 1); meshBuilder.AddTriangle(cubeIndex, n0, 2, n2, 1, n2, 0); if (debug) { GD.Print("Tetra"); } processed[mid.Index()] = true; processed[n0.Index()] = true; processed[n1.Index()] = true; processed[n2.Index()] = true; continue; } bool sameX = true, sameY = true, sameZ = true; foreach (CubeNode n in connected) { if (n.x != nd.x) { sameX = false; } if (n.y != nd.y) { sameY = false; } if (n.z != nd.z) { sameZ = false; } } if (sameX || sameY || sameZ) { int axis = 0; if (sameY) { axis = 1; } if (sameZ) { axis = 2; } // plane meshBuilder.AddTriangle(cubeIndex, nd, axis, nd.Nb((axis + 1) % 3), axis, nd.Nb((axis + 2) % 3), axis); meshBuilder.AddTriangle(cubeIndex, nd.Nb((axis + 1) % 3), axis, nd.Nb((axis + 2) % 3), axis, nd.Nb((axis + 1) % 3).Nb((axis + 2) % 3), axis); if (debug) { GD.Print("Plane"); } foreach (CubeNode c in connected) { processed[c.Index()] = true; } continue; } // line CubeNode l1 = nd, l2 = nd, l3 = nd, l4 = nd; foreach (CubeNode n in connected) { if (n.CountNbs() == 1) { l1 = n; } } foreach (CubeNode n in connected) { if (l1.WhichAxis(n) != -1) { l2 = n; } } foreach (CubeNode n in connected) { if (n.Index() != l1.Index() && l2.WhichAxis(n) != -1) { l3 = n; } } foreach (CubeNode n in connected) { if (n.Index() != l2.Index() && l3.WhichAxis(n) != -1) { l4 = n; } } int axis1 = l1.WhichAxis(l2); int axis2 = l2.WhichAxis(l3); int axis3 = l3.WhichAxis(l4); meshBuilder.AddTriangle(cubeIndex, l1, axis3, l2, axis3, l1, axis2); meshBuilder.AddTriangle(cubeIndex, l1, axis2, l3, axis1, l4, axis1); meshBuilder.AddTriangle(cubeIndex, l2, axis3, l1, axis2, l4, axis1); meshBuilder.AddTriangle(cubeIndex, l2, axis3, l4, axis1, l4, axis2); if (debug) { GD.Print("Line"); } foreach (CubeNode c in connected) { processed[c.Index()] = true; } continue; } // geometry.End(); }
private CubeNode InsertLeaf(CubeNode node, ref Vector3 point) { if (node.children == null) { return node; } bool greaterX = point.X > (node.bounds.Min.X + node.bounds.Max.X) / 2f; bool greaterY = point.Y > (node.bounds.Min.Y + node.bounds.Max.Y) / 2f; bool greaterZ = point.Z > (node.bounds.Min.Z + node.bounds.Max.Z) / 2f; if (greaterX) { if (greaterY) { if (greaterZ) { return InsertLeaf(node.children[7], ref point); // 7: Max X, Max Y, Max Z } else { return InsertLeaf(node.children[6], ref point); // 6: Max X, Max Y, Min Z } } else { if (greaterZ) { return InsertLeaf(node.children[5], ref point); // 5: Max X, Min Y, Max Z } else { return InsertLeaf(node.children[4], ref point); // 4: Max X, Min Y, Min Z } } } else { if (greaterY) { if (greaterZ) { return InsertLeaf(node.children[3], ref point); // 3: Min X, Max Y, Max Z } else { return InsertLeaf(node.children[2], ref point); // 2: Min X, Max Y, Min Z } } else { if (greaterZ) { return InsertLeaf(node.children[1], ref point); // 1: Min X, Min Y, Max Z } else { return InsertLeaf(node.children[0], ref point); // 0: Min X, Min Y, Min Z } } } }