public Player() : base() { speedRotate = 90f/60f/2f; //ne praš k neznam razložit XD speedForward = 10f; speedBackward = 10f; //primer: 90 stopinj na sekundo, pa deliš z 60 ker je 60 frameov, nevem kuko sm to dobu ampak dela speedStrafe = 10f; speedUp = 10f; accForward = 1f; accStrafe = 1f; accUp = 1f; forward = new Vector3(0, 0, 1); up = new Vector3(0, 1, 0); left = new Vector3(1, 0, 0); prevX = VesoljskiBoj.Game.game.Mouse.X; prevY = VesoljskiBoj.Game.game.Mouse.Y; model = new ObjMesh("Resources\\Models\\Spaceship\\Spaceship.obj"); //model = new ObjMesh("Resources\\Models\\Endor Battlecruiser\\Endor Battlecruiser.obj"); texture = Game.LoadTexture("Resources\\Models\\Spaceship\\spaceship.png"); //centerOffset = new Vector3(0, -130, 0); centerOffset = new Vector3(0, 0, 0); bb = new BoundingBox(model,1f); }
public override bool Prepare(Vector3I[] marks) { a = marks[0]; c = marks[1]; b = marks[2]; d = new Vector3I(a.X + c.X - b.X, a.Y + c.Y - b.Y, a.Z + c.Z - b.Z); Bounds = new BoundingBox( Math.Min(Math.Min(a.X, b.X), Math.Min(c.X, d.X)), Math.Min(Math.Min(a.Y, b.Y), Math.Min(c.Y, d.Y)), Math.Min(Math.Min(a.Z, b.Z), Math.Min(c.Z, d.Z)), Math.Max(Math.Max(a.X, b.X), Math.Max(c.X, d.X)), Math.Max(Math.Max(a.Y, b.Y), Math.Max(c.Y, d.Y)), Math.Max(Math.Max(a.Z, b.Z), Math.Max(c.Z, d.Z)) ); Coords = Bounds.MinVertex; if (!base.Prepare(marks)) return false; normal = (b - a).Cross(c - a); normalF = normal.Normalize(); BlocksTotalEstimate = GetBlockTotalEstimate(); s1 = normal.Cross(a - b).Normalize(); s2 = normal.Cross(b - c).Normalize(); s3 = normal.Cross(c - d).Normalize(); s4 = normal.Cross(d - a).Normalize(); return true; }
public CopyState( Vector3I mark1, Vector3I mark2 ) { BoundingBox box = new BoundingBox( mark1, mark2 ); Orientation = new Vector3I( mark1.X <= mark2.X ? 1 : -1, mark1.Y <= mark2.Y ? 1 : -1, mark1.Z <= mark2.Z ? 1 : -1 ); Buffer = new Block[box.Width, box.Length, box.Height]; }
public GuidedMissileLauncher(WeaponTargeting weapon) { m_weaponTarget = weapon; FuncBlock = CubeBlock as IMyFunctionalBlock; myLogger = new Logger("GuidedMissileLauncher", CubeBlock); var defn = CubeBlock.GetCubeBlockDefinition(); Vector3[] points = new Vector3[3]; Vector3 forwardAdjust = Vector3.Forward * WeaponDescription.GetFor(CubeBlock).MissileSpawnForward; points[0] = CubeBlock.LocalAABB.Min + forwardAdjust; points[1] = CubeBlock.LocalAABB.Max + forwardAdjust; points[2] = CubeBlock.LocalAABB.Min + Vector3.Up * CubeBlock.GetCubeBlockDefinition().Size.Y * CubeBlock.CubeGrid.GridSize + forwardAdjust; MissileSpawnBox = BoundingBox.CreateFromPoints(points); if (m_weaponTarget.myTurret != null) { myLogger.debugLog("original box: " + MissileSpawnBox, "GuidedMissileLauncher()"); MissileSpawnBox.Inflate(CubeBlock.CubeGrid.GridSize * 2f); } myLogger.debugLog("MissileSpawnBox: " + MissileSpawnBox, "GuidedMissileLauncher()"); myInventory = (CubeBlock as Interfaces.IMyInventoryOwner).GetInventory(0); Registrar.Add(weapon.FuncBlock, this); m_weaponTarget.GuidedLauncher = true; }
public MyModelInstanceData(MyStringHash subtypeId, MyInstanceFlagsEnum flags, float maxViewDistance, BoundingBox modelBox) { SubtypeId = subtypeId; Flags = flags; MaxViewDistance = maxViewDistance; ModelBox = modelBox; }
/// <summary> /// This method returns the query string for 'GetFeature'. /// </summary> /// <param name="featureTypeInfo">A <see cref="WfsFeatureTypeInfo"/> instance providing metadata of the featuretype to query</param> /// <param name="labelProperty"></param> /// <param name="boundingBox">The bounding box of the query</param> /// <param name="filter">An instance implementing <see cref="IFilter"/></param> public string GetFeatureGETRequest(WfsFeatureTypeInfo featureTypeInfo, string labelProperty, BoundingBox boundingBox, IFilter filter) { string qualification = string.IsNullOrEmpty(featureTypeInfo.Prefix) ? string.Empty : featureTypeInfo.Prefix + ":"; string filterString = string.Empty; if (filter != null) { filterString = filter.Encode(); filterString = filterString.Replace("<", "%3C"); filterString = filterString.Replace(">", "%3E"); filterString = filterString.Replace(" ", ""); filterString = filterString.Replace("*", "%2a"); filterString = filterString.Replace("#", "%23"); filterString = filterString.Replace("!", "%21"); } var filterBuilder = new StringBuilder(); filterBuilder.Append("&filter=%3CFilter%20xmlns=%22" + NSOGC + "%22%20xmlns:gml=%22" + NSGML + "%22%3E%3CBBOX%3E%3CPropertyName%3E"); filterBuilder.Append(qualification).Append(featureTypeInfo.Geometry.GeometryName); filterBuilder.Append("%3C/PropertyName%3E%3Cgml:Box%20srsName=%22" + featureTypeInfo.SRID + "%22%3E"); filterBuilder.Append("%3Cgml:coordinates%3E"); filterBuilder.Append(XmlConvert.ToString(boundingBox.Left) + ","); filterBuilder.Append(XmlConvert.ToString(boundingBox.Bottom) + "%20"); filterBuilder.Append(XmlConvert.ToString(boundingBox.Right) + ","); filterBuilder.Append(XmlConvert.ToString(boundingBox.Top)); filterBuilder.Append("%3C/gml:coordinates%3E%3C/gml:Box%3E%3C/BBOX%3E"); filterBuilder.Append(filterString); filterBuilder.Append("%3C/Filter%3E"); return "?SERVICE=WFS&Version=1.0.0&REQUEST=GetFeature&TYPENAME=" + qualification + featureTypeInfo.Name + "&SRS =" + featureTypeInfo.SRID + filterBuilder; }
public DynamicQuadTree(BoundingBox bounds) { _boundaries = bounds; _isLeaf = true; _bucket = new List<IWorldEntity>(); _numEntities = 0; }
public static void Draw(Canvas canvas, IViewport viewport, IStyle style, IFeature feature) { try { if (!feature.RenderedGeometry.ContainsKey(style)) feature.RenderedGeometry[style] = ToAndroidBitmap(feature.Geometry); var bitmap = (AndroidGraphics.Bitmap)feature.RenderedGeometry[style]; var dest = WorldToScreen(viewport, feature.Geometry.GetBoundingBox()); dest = new BoundingBox( dest.MinX, dest.MinY, dest.MaxX, dest.MaxY); var destination = RoundToPixel(dest); using (var paint = new Paint()) { canvas.DrawBitmap(bitmap, new Rect(0, 0, bitmap.Width, bitmap.Height), destination, paint); } DrawOutline(canvas, style, destination); } catch (Exception ex) { Trace.WriteLine(ex.Message); } }
// This method will look if node has all its childs null, and if yes, destroy childs array (saving memory + making traversal faster, because we don't need to traverse whole array) public void OptimizeChilds() { // Current bounding box is real bounding box (calculated as bounding box of children and triangles) m_boundingBox = m_realBoundingBox; for (int i = 0; i < m_childs.Count; i++) { if (m_childs[i] != null) { m_childs[i].OptimizeChilds(); } } // Remove all childs that are null, thus empty for us while (m_childs.Remove(null) == true) { } // When has only one child while (m_childs != null && m_childs.Count == 1) { // Add child triangles to self foreach (var t in m_childs[0].m_triangleIndices) { m_triangleIndices.Add(t); } // Replace current child with children of current child m_childs = m_childs[0].m_childs; } // If all childs are empty, we set this list to null so we save few value if (m_childs != null && m_childs.Count == 0) m_childs = null; }
public IEnumerable<IFeature> FetchTiles(BoundingBox boundingBox, double resolution) { var extent = new Extent(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Max.X, boundingBox.Max.Y); var levelId = BruTile.Utilities.GetNearestLevel(_source.Schema.Resolutions, resolution); var infos = _source.Schema.GetTileInfos(extent, levelId).ToList(); ICollection<WaitHandle> waitHandles = new List<WaitHandle>(); foreach (TileInfo info in infos) { if (_bitmaps.Find(info.Index) != null) continue; if (_queue.Contains(info.Index)) continue; var waitHandle = new AutoResetEvent(false); waitHandles.Add(waitHandle); _queue.Add(info.Index); ThreadPool.QueueUserWorkItem(GetTileOnThread, new object[] { _source, info, _bitmaps, waitHandle }); } WaitHandle.WaitAll(waitHandles.ToArray()); IFeatures features = new Features(); foreach (TileInfo info in infos) { byte[] bitmap = _bitmaps.Find(info.Index); if (bitmap == null) continue; IRaster raster = new Raster(new MemoryStream(bitmap), new BoundingBox(info.Extent.MinX, info.Extent.MinY, info.Extent.MaxX, info.Extent.MaxY)); IFeature feature = features.New(); feature.Geometry = raster; features.Add(feature); } return features; }
public Viewport() { _extent = new BoundingBox(0, 0, 0, 0); _windowExtent = new Quad(); RenderResolutionMultiplier = 1; _center.PropertyChanged += (sender, args) => _modified = true; }
public List<Actor> Intersect(BoundingBox box) { UpdateDirty(); var result = new List<Actor>(); Root.Intersect(ref box, result); return result; }
public void TestVarious() { BoundingBox b1 = new BoundingBox(20, 30, 40, 55); Assert.AreEqual(20, b1.Left); Assert.AreEqual(20, b1.Min.X); Assert.AreEqual(40, b1.Right); Assert.AreEqual(40, b1.Max.X); Assert.AreEqual(30, b1.Bottom); Assert.AreEqual(30, b1.Min.Y); Assert.AreEqual(55, b1.Top); Assert.AreEqual(55, b1.Max.Y); Assert.AreEqual(20, b1.Width); Assert.AreEqual(25, b1.Height); Assert.AreNotSame(b1, b1.Clone()); Assert.IsTrue(b1.Contains(new Point(30, 40))); Assert.IsTrue(b1.Contains(new Point(20, 40))); Assert.IsFalse(b1.Contains(new Point(10, 10))); Assert.IsFalse(b1.Contains(new Point(50, 60))); Assert.IsFalse(b1.Contains(new Point(30, 60))); Assert.IsFalse(b1.Contains(new Point(50, 40))); Assert.IsFalse(b1.Contains(new Point(30, 15))); Assert.IsTrue(b1.Equals(new BoundingBox(20, 30, 40, 55))); Assert.AreEqual(new Point(30, 42.5), b1.GetCentroid()); Assert.AreEqual(1, b1.LongestAxis); Assert.AreEqual(new BoundingBox(19, 29, 41, 56), b1.Grow(1)); Assert.IsFalse(b1.Equals(null)); Assert.IsFalse(b1.Equals(new Polygon())); Assert.AreEqual("20,30 40,55", b1.ToString()); Assert.AreEqual(b1, new BoundingBox(40, 55, 20, 30)); Assert.AreEqual(Math.Sqrt(200), b1.Distance(new BoundingBox(50, 65, 60, 75))); }
private void UpdateLocalVolume() { float maxRadius = Math.Max(Radius1, Radius2); this.LocalVolume = new BoundingSphere(Vector3.Zero, Math.Max(maxRadius, Length / 2)); this.m_localBoundingBox = new BoundingBox(new Vector3(-maxRadius, -Length / 2, -maxRadius), new Vector3(maxRadius, Length / 2, maxRadius)); }
public override bool Prepare( Vector3I[] marks ) { if( !base.Prepare( marks ) ) return false; // center of the torus center = marks[0]; Vector3I radiusVector = (marks[1] - center).Abs(); // tube radius is figured out from Z component of the mark vector tubeR = radiusVector.Z; // torus radius is figured out from length of vector's X-Y components bigR = Math.Sqrt( radiusVector.X * radiusVector.X + radiusVector.Y * radiusVector.Y + .5 ); // tube + torus radius, rounded up. This will be the maximum extend of the torus. int combinedRadius = (int)Math.Ceiling( bigR + tubeR ); // vector from center of torus to the furthest-away point of the bounding box Vector3I combinedRadiusVector = new Vector3I( combinedRadius, combinedRadius, tubeR + 1 ); // adjusted bounding box Bounds = new BoundingBox( center - combinedRadiusVector, center + combinedRadiusVector ); BlocksTotalEstimate = (int)(2 * Math.PI * Math.PI * bigR * (tubeR * tubeR + Bias)); coordEnumerator = BlockEnumerator().GetEnumerator(); return true; }
public SerializedEnvelope(BoundingBox envelope) { MinX = envelope.Left; MinY = envelope.Bottom; MaxX = envelope.Right; MaxY = envelope.Top; }
public void FindContent(Bitmap image, Bitmap foregroundImage, Tree currentNode, List<Tree> foundContent) { Utils.RectData[] found = ConnectedComponents.TwoPass(ccLabelingBitmap, foregroundImage, currentNode, Utils.BACKGROUND); foreach (Utils.RectData rect in found) { if(rect != null){ int hash = 17; for (int row = rect.Top; row <= rect.Bottom; row++) { for (int col = rect.Left; col <= rect.Right; col++) { hash = 31 * hash + image[row, col]; } } BoundingBox bb = new BoundingBox(rect.Left, rect.Top, (rect.Right - rect.Left) + 1, (rect.Bottom - rect.Top) + 1); Dictionary<string,object> tags = new Dictionary<string, object>(); tags.Add("type", "content"); tags.Add("pixel_hash", hash); Tree node = Tree.FromBoundingBox(bb, tags); foundContent.Add(node); } } }
public void DrawBoundingBox(BoundingBox box, DMatrix transform) { var corners = box.GetCorners(); var worldCorners = corners.Select(x => DVector3.TransformCoordinate(new DVector3(x.X, x.Y, x.Z), transform)).ToArray(); //foreach (var corner in worldCorners) //{ // DrawPoint(corner, 0.1f); //} DrawLine(worldCorners[0], worldCorners[1], Color.Green); DrawLine(worldCorners[0], worldCorners[4], Color.Green); DrawLine(worldCorners[0], worldCorners[3], Color.Green); DrawLine(worldCorners[7], worldCorners[6], Color.Red); DrawLine(worldCorners[7], worldCorners[3], Color.Red); DrawLine(worldCorners[7], worldCorners[4], Color.Red); DrawLine(worldCorners[5], worldCorners[1], Color.Yellow); DrawLine(worldCorners[5], worldCorners[4], Color.Yellow); DrawLine(worldCorners[5], worldCorners[6], Color.Yellow); DrawLine(worldCorners[2], worldCorners[1], Color.WhiteSmoke); DrawLine(worldCorners[2], worldCorners[3], Color.WhiteSmoke); DrawLine(worldCorners[2], worldCorners[6], Color.WhiteSmoke); }
static TestCollidable[] GetRandomLeaves(int leafCount, BoundingBox bounds, Vector3 minimumSize, Vector3 maximumSize, float sizePower, VelocityDescription velocityDescription) { var leaves = new TestCollidable[leafCount]; Random random = new Random(5); var range = bounds.Max - bounds.Min; var sizeRange = maximumSize - minimumSize; for (int i = 0; i < leafCount; ++i) { leaves[i] = new TestCollidable(); leaves[i].HalfSize = 0.5f * (minimumSize + new Vector3((float)Math.Pow(random.NextDouble(), sizePower), (float)Math.Pow(random.NextDouble(), sizePower), (float)Math.Pow(random.NextDouble(), sizePower)) * sizeRange); leaves[i].Position = bounds.Min + new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()) * range; } for (int i = 0; i < leaves.Length * velocityDescription.PortionOfMovingLeaves; ++i) { var speed = (float)(velocityDescription.MinVelocity + (velocityDescription.MaxVelocity - velocityDescription.MinVelocity) * Math.Pow(random.NextDouble(), velocityDescription.VelocityDistributionPower)); var direction = new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()) * 2 - Vector3.One; var lengthSquared = direction.LengthSquared(); if (lengthSquared < 1e-9f) { direction = new Vector3(0, 1, 0); } else { direction /= (float)Math.Sqrt(lengthSquared); } leaves[i].Velocity = speed * direction; } return leaves; }
protected override void generateSplitBox() { if (splitDepth == 0) { // special case for splitdepth 0 Vector3 boxCenter = aabb.Minimum + aabb.Maximum; boxCenter *= 0.5f; float halfx = boxCenter.X - aabb.Minimum.X; float halfy = boxCenter.Y - aabb.Minimum.Y; float halfz = boxCenter.Z - aabb.Minimum.Z; float maxHalf = Math.Max(halfx, Math.Max(halfy, halfz)); // adjust bounding box to not be flat aabb = new BoundingBox(boxCenter - new Vector3(maxHalf * 2f), boxCenter + new Vector3(maxHalf * 2f)); Vector3 newMin = boxCenter - new Vector3(maxHalf * 2f * (float)splitFactor); Vector3 newMax = boxCenter + new Vector3(maxHalf * 2f * (float)splitFactor); splitBox = new BoundingBox(newMin, newMax); } else { base.generateSplitBox(); } }
public AABB(IEnumerable<VertexPositionNormalColored> vertices) { var minX = float.MinValue; var minY = float.MinValue; var minZ = float.MinValue; var maxX = float.MaxValue; var maxY = float.MaxValue; var maxZ = float.MaxValue; foreach (var vertex in vertices) { var x = vertex.Position.X; var y = vertex.Position.Y; var z = vertex.Position.Z; minX = Math.Min(minX, x); minY = Math.Min(minY, y); minZ = Math.Min(minZ, z); maxX = Math.Max(maxX, x); maxY = Math.Max(maxY, y); maxZ = Math.Max(maxZ, z); } var min = new Vector3(minX, minY, minZ); var max = new Vector3(maxX, maxY, maxZ); Bounds = new BoundingBox(min, max); }
internal void Intersect(ref BoundingBox box, List<Actor> result) { if (Box.Intersects(ref box)) { if (Children != null) { Children[LEFT_TOP_FRONT].Intersect(ref box, result); Children[RIGHT_TOP_FRONT].Intersect(ref box, result); Children[LEFT_TOP_BACK].Intersect(ref box, result); Children[RIGHT_TOP_BACK].Intersect(ref box, result); Children[LEFT_BOTTOM_FRONT].Intersect(ref box, result); Children[RIGHT_BOTTOM_FRONT].Intersect(ref box, result); Children[LEFT_BOTTOM_BACK].Intersect(ref box, result); Children[RIGHT_BOTTOM_BACK].Intersect(ref box, result); } if (Objects.Count > 0) { for (var i = 0; i < Objects.Count; ++i) { if (Objects[i].Box.Intersects(ref box)) { ActorPool.Verify(Objects[i].Actor); result.Add(Objects[i].Actor); } } } } }
public unsafe void BuildVolumeHeuristic(int[] leafIds, BoundingBox[] leafBounds, int start = 0, int length = -1) { if (leafIds.Length != leafBounds.Length) throw new ArgumentException("leafIds and leafBounds lengths must be equal."); if (start + length > leafIds.Length) throw new ArgumentException("Start + length must be smaller than the leaves array length."); if (start < 0) throw new ArgumentException("Start must be nonnegative."); if (length == 0) throw new ArgumentException("Length must be positive."); if (length < 0) length = leafIds.Length; if (nodes[0].ChildCount != 0) throw new InvalidOperationException("Cannot build a tree that already contains nodes."); //The tree is built with an empty node at the root to make insertion work more easily. //As long as that is the case (and as long as this is not a constructor), //we must clear it out. nodeCount = 0; //Guarantee that no resizes will occur during the build. if (LeafCapacity < leafBounds.Length) { LeafCapacity = leafBounds.Length; } var preallocatedNodeCount = leafBounds.Length * 2 - 1; if (NodeCapacity < preallocatedNodeCount) { NodeCapacity = preallocatedNodeCount; } int nodeIndex; BoundingBox boundingBox; VolumeHeuristicAddNode(-1, -1, leafIds, leafBounds, start, length, out boundingBox, out nodeIndex); }
public QuadTree(BoundingBox bounds, int depthThreshold = DefaultDepthThreshold) : base(bounds) { Contract.Requires(depthThreshold > 0); Partition(depthThreshold, 0); }
public static void Draw(CALayer target, IViewport viewport, IStyle style, IFeature feature) { const string styleKey = "laag"; if(feature[styleKey] == null) feature[styleKey] = ToiOSBitmap(feature.Geometry); var bitmap = (UIImage)feature [styleKey]; var dest = WorldToScreen(viewport, feature.Geometry.GetBoundingBox()); dest = new BoundingBox( dest.MinX, dest.MinY, dest.MaxX, dest.MaxY); var destination = RoundToPixel(dest); var tile = new CALayer { Frame = destination, Contents = bitmap.CGImage, }; target.AddSublayer(tile); }
public RenderObjectUnity(AnimatorEditor editor, HashSet<string> meshNames) { HighlightSubmesh = new HashSet<int>(); highlightMaterial = new SlimDX.Direct3D9.Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; this.tweeningVertDec = new VertexDeclaration(this.device, TweeningWithoutNormalsVertexBufferFormat.ThreeStreams); Textures = new Texture[editor.Textures.Count]; Materials = new SlimDX.Direct3D9.Material[editor.Materials.Count]; rootFrame = CreateHierarchy(editor, meshNames, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); if (meshFrames.Count > 0) { Bounds = meshFrames[0].Bounds; for (int i = 1; i < meshFrames.Count; i++) { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } } else { Bounds = new BoundingBox(); } }
private static IEnumerable<GeoJSON> QueryData(BoundingBox bbox, ICanQueryLayer layer) { if (layer == null) throw new ArgumentNullException("layer"); // Query for data FeatureDataSet ds = new FeatureDataSet(); layer.ExecuteIntersectionQuery(bbox, ds); IEnumerable<GeoJSON> data = GeoJSONHelper.GetData(ds); // Reproject geometries if needed IMathTransform transform = null; if (layer is VectorLayer) { ICoordinateTransformation transformation = (layer as VectorLayer).CoordinateTransformation; transform = transformation == null ? null : transformation.MathTransform; } if (transform != null) { GeometryFactory gf = new GeometryFactory(); data = data.Select(d => { Geometry converted = GeometryTransform.TransformGeometry(d.Geometry, transform, gf); d.SetGeometry(converted); return d; }); } return data; }
public override bool Prepare(Vector3I[] marks) { a = marks[0]; b = marks[1]; c = marks[2]; if (a == b || b == c || c == a) { if (a != c) b = c; isLine = true; } Bounds = new BoundingBox( Math.Min(Math.Min(a.X, b.X), c.X), Math.Min(Math.Min(a.Y, b.Y), c.Y), Math.Min(Math.Min(a.Z, b.Z), c.Z), Math.Max(Math.Max(a.X, b.X), c.X), Math.Max(Math.Max(a.Y, b.Y), c.Y), Math.Max(Math.Max(a.Z, b.Z), c.Z) ); Coords = Bounds.MinVertex; if (!base.Prepare(marks)) return false; normal = (b - a).Cross(c - a); normalF = normal.Normalize(); BlocksTotalEstimate = GetBlockTotalEstimate(); s1 = normal.Cross(a - b).Normalize(); s2 = normal.Cross(b - c).Normalize(); s3 = normal.Cross(c - a).Normalize(); return true; }
internal unsafe void MoveAndWallSlide() { if( entity.Velocity == Vector3.Zero ) return; int* minY = stackalloc int[4096]; int* maxY = stackalloc int[4096]; int* minX = stackalloc int[4096]; int* maxX = stackalloc int[4096]; for( int i = 0; i < 4096; i++ ) { minX[i] = int.MaxValue; minY[i] = int.MaxValue; maxX[i] = int.MinValue; maxY[i] = int.MinValue; } bb = entity.CollisionBounds; int count = 0; // First raytrace out from the origin to find approximate blocks CalcRayDirection(); while( true ) { UpdateCoords( tracerP1Y1, minX, maxX, minY, maxY ); UpdateCoords( tracerP1Y2, minX, maxX, minY, maxY ); UpdateCoords( tracerP2Y1, minX, maxX, minY, maxY ); UpdateCoords( tracerP2Y2, minX, maxX, minY, maxY ); } // Now precisely which blocks we really intersect with // .. then perform collision }
public void AdjustVertices() { Matrix camWorld = Matrix.Invert(GraphicOptions.CurrentCamera.View); Vector3 right = camWorld.Right; Vector3 down = camWorld.Down; right.Normalize(); down.Normalize(); right = right * width; down = down * height; Vector3 tl = position - right / 2; Vector3 tr = position + right / 2; Vector3 bl = tl + down; Vector3 br = tr + down; vertices.Clear(); Vector3 normal = Vector3.Cross(down, right); vertices.Add(new VertexPositionNormalTexture(bl, normal, Vector2.UnitY)); vertices.Add(new VertexPositionNormalTexture(tl, normal, Vector2.Zero)); vertices.Add(new VertexPositionNormalTexture(tr, normal, Vector2.UnitX)); vertices.Add(new VertexPositionNormalTexture(br, normal, Vector2.One)); vertices.Add(new VertexPositionNormalTexture(bl, normal, Vector2.UnitY)); vertices.Add(new VertexPositionNormalTexture(tr, normal, Vector2.UnitX)); boundingBox = new BoundingBox(tl, br); Ready(); }
public async Task <List <DocumentText> > ReadImage(string filename) { try { using (var fileStream = File.OpenRead(filename)) { var streamHeaders = await ComputerVisionClient.ReadInStreamAsync(fileStream, "en"); var operationLocation = streamHeaders.OperationLocation; const int numberOfCharsInOperationId = 36; string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId); await Task.Delay(1500); ReadOperationResult readOperationResult; do { readOperationResult = await ComputerVisionClient.GetReadResultAsync(Guid.Parse(operationId)); } while (readOperationResult.Status == OperationStatusCodes.Running || readOperationResult.Status == OperationStatusCodes.NotStarted); var listOfDocumentText = new List <DocumentText>(); var arrayOfReadResults = readOperationResult.AnalyzeResult.ReadResults; foreach (var page in arrayOfReadResults) { foreach (var line in page.Lines) { var boundBox = new BoundingBox() { x1 = line.BoundingBox[0], y1 = line.BoundingBox[1], x2 = line.BoundingBox[2], y2 = line.BoundingBox[3] }; var documentText = new DocumentText() { BoundingBox = boundBox, Text = line.Text }; listOfDocumentText.Add(documentText); } } return(listOfDocumentText); } } catch (FileNotFoundException e) { Logger.LogInformation($"file not found: {filename}"); throw e; } catch (Exception e) { Logger.LogError(e, $"failed to analyze file: {filename}"); return(null); } }
private void ViewModel_RequestZoomToFit(BoundingBox bounds) { watch_view.ZoomExtents(bounds.ToRect3D()); }
public static MultiObjectLocalizationAndLabelingAggregatedResult getAggregatedResult(List <MultiObjectLocalizationAndLabelingResult> results, int MinResults = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MIN_RESULTS_TO_AGGREGATE, int MaxResults = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MAX_RESULTS_TO_AGGREGATE, double CategoryMajorityThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MAJORITY_CATEGORY_THRESHOLD, double ObjectsCoverageThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_AGGREGATION_TERMINATION, double DeviationPixelThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_DEVIATION_THRESHOLD ) { if (results.Count < MinResults) { return(null); } //if the image was scaled down during display, errors get scaled up //so we need to scale our deviation thresholds double minboxdimension_threshold_x = MIN_BOX_DIMENSION_FOR_CONSIDERATION * results[0].displayScaleReductionX; double minboxdimension_threshold_y = MIN_BOX_DIMENSION_FOR_CONSIDERATION * results[0].displayScaleReductionY; //first use multipartitie wieghted matching to associated the boxes disregarding the labels since //people might make mistake with lables but boxes are usually right List <List <BoundingBox> > allboxes = new List <List <BoundingBox> >(); List <int> noBoxesPerResult = new List <int>(); //how many boxes did each person draw? List <List <bool> > largeBoxes = new List <List <bool> >(); //was this box was bigger than MIN_BOX_DIMENSION_FOR_CONSIDERATION? foreach (MultiObjectLocalizationAndLabelingResult res in results) { allboxes.Add(new List <BoundingBox>()); largeBoxes.Add(new List <bool>()); if (res == null) { noBoxesPerResult.Add(0); continue; } List <BoundingBox> boxList = allboxes[allboxes.Count - 1]; List <bool> largeBoxList = largeBoxes[largeBoxes.Count - 1]; foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in res.objects) { boxList.Add(entry.boundingBox); if (entry.boundingBox.getWidth() < minboxdimension_threshold_x && entry.boundingBox.getHeight() < minboxdimension_threshold_y) { largeBoxList.Add(false); } else { largeBoxList.Add(true); } } noBoxesPerResult.Add(boxList.Count); } //now associate boxes across the various results List <MultipartiteWeightedMatch> boxAssociation = BoundingBoxAssociation.computeBoundingBoxAssociations(allboxes); int noBoxes = boxAssociation.Count; int noAssociatedBoxes = 0; int noIgnorable = 0; //how many of the drawn boxes for each result were actually associated by two or more people for each user? SortedDictionary <int, int> noMultipleAssociatedBoxesPerResult = new SortedDictionary <int, int>(); SortedDictionary <int, int> noSmallIgnorableBoxesPerResult = new SortedDictionary <int, int>(); for (int i = 0; i < results.Count; i++) { noMultipleAssociatedBoxesPerResult.Add(i, 0); noSmallIgnorableBoxesPerResult.Add(i, 0); } foreach (MultipartiteWeightedMatch match in boxAssociation) { if (match.elementList.Count > 1) //this has been corroborated by two people { noAssociatedBoxes++; foreach (KeyValuePair <int, int> entry in match.elementList) { noMultipleAssociatedBoxesPerResult[entry.Key]++; } } else { List <int> keys = match.elementList.Keys.ToList(); if (largeBoxes[keys[0]][match.elementList[keys[0]]] == false) //the box was a small box can be ignored { noIgnorable++; noSmallIgnorableBoxesPerResult[keys[0]]++; } } } //count how many people have a high association ratio int noHighAssociationRatio = 0; for (int i = 0; i < results.Count; i++) { if (noBoxesPerResult[i] == 0) { continue; } double ratio = ((double)noMultipleAssociatedBoxesPerResult[i] + (double)noSmallIgnorableBoxesPerResult[i]) / (double)noBoxesPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noHighAssociationRatio++; } } if (noHighAssociationRatio < MinResults) //at least three people should have all their boxes highly corroborated by one other person { return(null); } //now we have to find out if the boxes were drawn well and only take the boxes that are within //a reasonable deviation of each other. //if the image was scaled down during display, errors get scaled up //so we need to scale our deviation thresholds double deviation_threshold_x = DeviationPixelThreshold * results[0].displayScaleReductionX; double deviation_threshold_y = DeviationPixelThreshold * results[0].displayScaleReductionY; int noAcceptedBoxes = 0; int noSmallIgnore = 0; List <List <BoundingBoxGroup> > allBoxGroups = new List <List <BoundingBoxGroup> >(); List <BoundingBox> finalBoxes = new List <BoundingBox>(); //stores the aggregated boxes SortedDictionary <int, List <int> > HighQualityAssociatedBoxPerResult = new SortedDictionary <int, List <int> >(); foreach (MultipartiteWeightedMatch match in boxAssociation) { List <BoundingBox> boxList = new List <BoundingBox>(); List <string> identifiers = new List <string>(); foreach (KeyValuePair <int, int> entry in match.elementList) { boxList.Add(allboxes[entry.Key][entry.Value]); identifiers.Add(entry.Key + "_" + entry.Value); } //List<BoundingBoxGroup> boxGroups = MergeAndGroupBoundingBoxes.GreedyMeanHierarchicalMergeByPixelDeviation(boxList, identifiers, DEVIATION_THRESHOLD); List <BoundingBoxGroup> boxGroups = MergeAndGroupBoundingBoxes.GreedyMeanHierarchicalMergeByPixelDeviation(boxList, identifiers, deviation_threshold_x, deviation_threshold_y); allBoxGroups.Add(boxGroups); int maxCount = 0; int index = -1; getMaxCountGroup(boxGroups, out maxCount, out index); ////find the boxgroup with the maxCount //int maxCount = 0; //int index = -1; //for(int i=0;i<boxGroups.Count;i++) //{ // if(boxGroups[i].boundingBoxList.Count > maxCount) // there are two boxes within acceptance range // { // maxCount = boxGroups[i].boundingBoxList.Count; // index = i; // } //} if (maxCount > 1) { noAcceptedBoxes++; finalBoxes.Add(boxGroups[index].mergedBoundingBox); // count the majority group high associations foreach (string id in boxGroups[index].identifiers) { string[] fields = id.Split('_'); int partId = Convert.ToInt32(fields[0]); int boxId = Convert.ToInt32(fields[1]); if (!HighQualityAssociatedBoxPerResult.ContainsKey(partId)) { HighQualityAssociatedBoxPerResult.Add(partId, new List <int>()); } HighQualityAssociatedBoxPerResult[partId].Add(boxId); } } else { finalBoxes.Add(BoundingBox.NullBoundingBox); //were all the boxes drawn too small? bool small = true; for (int i = 0; i < boxGroups.Count; i++) { string[] parts = boxGroups[i].identifiers[0].Split('_'); int resultNo = Convert.ToInt32(parts[0]); int boxNo = Convert.ToInt32(parts[1]); if (largeBoxes[resultNo][boxNo] == true) { small = false; break; } } if (small) { noSmallIgnore++; } } } if (((double)noAcceptedBoxes + (double)noSmallIgnore) / (double)noAssociatedBoxes < ObjectsCoverageThreshold && results.Count < MaxResults) //this is acceptable { return(null); } //count how many people have a high "quality" association ratio int noResultsWithHighQualityObjectCoverage = 0; for (int i = 0; i < results.Count; i++) { if (noBoxesPerResult[i] == 0) { continue; } if (!HighQualityAssociatedBoxPerResult.ContainsKey(i)) { continue; } double ratio = ((double)HighQualityAssociatedBoxPerResult[i].Count) / (double)noBoxesPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noResultsWithHighQualityObjectCoverage++; } } if (noResultsWithHighQualityObjectCoverage < MinResults && results.Count < MaxResults) //at least three people should have most of their boxes highly corroborated by one other person { return(null); } //now we need to see if the categores have a supermajority List <string> finalCategories = new List <string>(); //stores the aggregated categories int cntr = -1; foreach (MultipartiteWeightedMatch match in boxAssociation) { cntr++; if (BoundingBox.IsNullBoundingBox(finalBoxes[cntr])) //this is not an acceptable box { finalCategories.Add(""); continue; } Dictionary <string, int> categoryNames = new Dictionary <string, int>(); int totalCount = match.elementList.Count; int maxCount = 0; string maxCategory = ""; foreach (KeyValuePair <int, int> entry in match.elementList) { string category = results[entry.Key].objects[entry.Value].Category; if (!categoryNames.ContainsKey(category)) { categoryNames.Add(category, 0); } categoryNames[category]++; if (maxCount < categoryNames[category]) { maxCount = categoryNames[category]; maxCategory = category; } } double probability = ((double)maxCount + 1) / ((double)totalCount + 2); if (probability < CategoryMajorityThreshold && results.Count < MaxResults) //this is not a valid category need more work { return(null); } else { finalCategories.Add(maxCategory); } } //now we have enough information to create the aggregate results MultiObjectLocalizationAndLabelingAggregatedResult aggResult = new MultiObjectLocalizationAndLabelingAggregatedResult(); aggResult.metaData = new MultiObjectLocalizationAndLabelingAggregatedResultMetaData(); aggResult.metaData.TotalCount = results.Count; aggResult.boxesAndCategories = new MultiObjectLocalizationAndLabelingResult(); aggResult.boxesAndCategories.objects = new List <MultiObjectLocalizationAndLabelingResultSingleEntry>(); cntr = -1; foreach (MultipartiteWeightedMatch match in boxAssociation) { cntr++; if (BoundingBox.IsNullBoundingBox(finalBoxes[cntr])) { continue; } MultiObjectLocalizationAndLabelingResultSingleEntry entry = new MultiObjectLocalizationAndLabelingResultSingleEntry(); entry.boundingBox = finalBoxes[cntr]; entry.Category = finalCategories[cntr]; aggResult.boxesAndCategories.objects.Add(entry); } aggResult.boxesAndCategories.displayScaleReductionX = results[0].displayScaleReductionX; aggResult.boxesAndCategories.displayScaleReductionY = results[0].displayScaleReductionY; aggResult.boxesAndCategories.imageHeight = results[0].imageHeight; aggResult.boxesAndCategories.imageWidth = results[0].imageWidth; return(aggResult); }
public static double ACCEPTANCE_NUMBER_OF_BOXES_THRESHOLD = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_PAYMENT; //the person must have made at least 80% of the boxes public static bool IsAcceptable(SatyamAggregatedResultsTableEntry aggResultEntry, SatyamResultsTableEntry resultEntry, double DeviationPixelThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_DEVIATION_THRESHOLD_FOR_PAYMENT) { //most boxes should be within limits //most categories should be right SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResultEntry.ResultString); MultiObjectLocalizationAndLabelingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingAggregatedResult>(satyamAggResult.AggregatedResultString); SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(resultEntry.ResultString); MultiObjectLocalizationAndLabelingResult result = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingResult>(satyamResult.TaskResult); if (result == null) { return(false); } //first check if the number of boxes are within limit int boxLimit = (int)Math.Ceiling((double)aggresult.boxesAndCategories.objects.Count * ACCEPTANCE_NUMBER_OF_BOXES_THRESHOLD); if (result.objects.Count < boxLimit) { return(false); } double minboxdimension_threshold_x = MIN_BOX_DIMENSION_FOR_CONSIDERATION * result.displayScaleReductionX; double minboxdimension_threshold_y = MIN_BOX_DIMENSION_FOR_CONSIDERATION * result.displayScaleReductionY; //We fist do a bipartitte matching to find the best assocaition for the boxes List <List <BoundingBox> > allboxes = new List <List <BoundingBox> >(); allboxes.Add(new List <BoundingBox>()); foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in result.objects) { allboxes[0].Add(entry.boundingBox); } allboxes.Add(new List <BoundingBox>()); List <bool> tooSmallToIgnore = new List <bool>(); foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in aggresult.boxesAndCategories.objects) { allboxes[1].Add(entry.boundingBox); if (entry.boundingBox.getWidth() < minboxdimension_threshold_x && entry.boundingBox.getHeight() < minboxdimension_threshold_y) { tooSmallToIgnore.Add(true); } else { tooSmallToIgnore.Add(false); } } List <MultipartiteWeightedMatch> boxAssociation = BoundingBoxAssociation.computeBoundingBoxAssociations(allboxes); //now find how many of the results match aggregated results int noAccepted = 0; double deviation_threshold_x = DeviationPixelThreshold * result.displayScaleReductionX; double deviation_threshold_y = DeviationPixelThreshold * result.displayScaleReductionY; int noIgnorable = 0; foreach (MultipartiteWeightedMatch match in boxAssociation) { if (match.elementList.ContainsKey(1)) // this contains an aggregated box { if (match.elementList.ContainsKey(0)) // a result box has been associated { BoundingBox aggregatedBoundingBox = allboxes[1][match.elementList[1]]; BoundingBox resultBoundingBox = allboxes[0][match.elementList[0]]; //double deviation = aggregatedBoundingBox.ComputeMaxDeviationMetric(resultBoundingBox); double deviation = aggregatedBoundingBox.ComputeNormalizedMaxDeviationMetric(resultBoundingBox, deviation_threshold_x, deviation_threshold_y); if (deviation <= 1) //deviation test passed { //now check category if (result.objects[match.elementList[0]].Category == aggresult.boxesAndCategories.objects[match.elementList[1]].Category) { //both category and bounding box tests have passed noAccepted++; } } else { if (tooSmallToIgnore[match.elementList[1]]) { noIgnorable++; } } } } } if (noAccepted >= boxLimit - noIgnorable) { return(true); } return(false); }
private void CreateMorphedMesh() { if (_simpleMesh == null) { return; } var meshPositions = _meshGeometry3D.Positions; var meshNormals = _meshGeometry3D.Normals; var positionsCount = meshPositions.Count; // First store original positions into _originalMesh // This array will provide much faster access to morphed positions then if we would access the data from MeshGeometry3D object. var originalMesh = new PositionNormal[positionsCount]; for (int i = 0; i < positionsCount; i++) { originalMesh[i].Position = meshPositions[i].ToVector3(); originalMesh[i].Normal = meshNormals[i].ToVector3(); } _originalMesh = originalMesh; // Now create a copy of the original MeshGeometry3D (this is needed because after adjusting positions we also need to re-calculate normals) var morphedMeshGeometry3D = new MeshGeometry3D(); // Copy positions from original MeshGeometry3D - we also adjust the y position of all positions that are above the center of the mesh double yOffset = _originalMeshSizeY; double yMiddle = _meshGeometry3D.Bounds.Y + _originalMeshSizeY / 2.0f; // get mesh center y value morphedMeshGeometry3D.Positions = null; // Disconnect positions before changing (to prevent change notifications from slowing things down) for (int i = 0; i < positionsCount; i++) { var onePosition = meshPositions[i]; if (onePosition.Y > yMiddle) { onePosition.Y += yOffset; } meshPositions[i] = onePosition; } morphedMeshGeometry3D.Positions = meshPositions; // Because we have changed the positions, this also changed the normal vectors. // We need to calculate normals again meshNormals = Ab3d.Utilities.MeshUtils.CalculateNormals(morphedMeshGeometry3D); morphedMeshGeometry3D.Normals = meshNormals; // After we have a morphed MeshGeometry, we can prepared an optimized list of positions and normals. _morphedMesh = new PositionNormal[positionsCount]; for (int i = 0; i < positionsCount; i++) { _morphedMesh[i] = new PositionNormal(meshPositions[i].ToVector3(), meshNormals[i].ToVector3()); } // We also need to store original and morphed bounding box (bounds) _originalBoundingBox = _meshGeometry3D.Bounds.ToBoundingBox(); _morphedBoundingBox = new BoundingBox(_originalBoundingBox.Minimum, new Vector3(_originalBoundingBox.Maximum.X, _originalBoundingBox.Maximum.Y + (float)yOffset, _originalBoundingBox.Maximum.Z)); }
private void CreateCatesianGridVisual3D(object sender, EventArgs e) { try { int nx = System.Convert.ToInt32(tbNX.Text); int ny = System.Convert.ToInt32(tbNY.Text); int nz = System.Convert.ToInt32(tbNZ.Text); float step = System.Convert.ToSingle(tbColorIndicatorStep.Text); //float radius = System.Convert.ToSingle(this.tbRadius.Text); float propMin = System.Convert.ToSingle(this.tbxPropertyMinValue.Text, CultureInfo.InvariantCulture); float propMax = System.Convert.ToSingle(this.tbxPropertyMaxValue.Text, CultureInfo.InvariantCulture); int dimenSize = nx * ny * nz; float dx = System.Convert.ToSingle(this.tbDX.Text); float dy = System.Convert.ToSingle(this.gbDY.Text); float dz = System.Convert.ToSingle(this.tbDZ.Text); float[] dxArray = initArray(dimenSize, dx); float[] dyArray = initArray(dimenSize, dy); float[] dzArray = initArray(dimenSize, dz); // use CatesianGridderSource to fill HexahedronGridderElement's content. DateTime t0 = DateTime.Now; CatesianGridderSource source = new CatesianGridderSource() { NX = nx, NY = ny, NZ = nz, DX = dxArray, DY = dyArray, DZ = dzArray, }; source.IBlocks = GridBlockHelper.CreateBlockCoords(nx); source.JBlocks = GridBlockHelper.CreateBlockCoords(ny); source.KBlocks = GridBlockHelper.CreateBlockCoords(nz); source.Init(); DateTime t1 = DateTime.Now; InitSlice(lbxNI, source.IBlocks); InitSlice(lbxNJ, source.JBlocks); InitSlice(lbxNZ, source.KBlocks); InitPropertiesAndSelectDefault(dimenSize, propMin, propMax); DateTime t2 = DateTime.Now; ///模拟获得网格属性 ///获得当前选中的属性 float minValue = this.CurrentProperty.MinValue; float maxValue = this.CurrentProperty.MaxValue; step = (maxValue * 1.0f - minValue * 1.0f) / 10; int[] gridIndexes = this.CurrentProperty.GridIndexes; float[] gridValues = this.CurrentProperty.Values; //设置色标的范围 this.sim3D.SetColorIndicator(minValue, maxValue, step); // use HexahedronGridderElement DateTime t3 = DateTime.Now; HexahedronMeshGeometry3D geometry = (HexahedronMeshGeometry3D)source.CreateMesh(); DateTime t4 = DateTime.Now; TexCoordBuffer textureCoodinates = source.CreateTextureCoordinates(gridIndexes, gridValues, minValue, maxValue); DateTime t5 = DateTime.Now; Bitmap texture = this.sim3D.uiColorIndicator.CreateTextureImage(); HexahedronGrid gridder = new HexahedronGrid(this.sim3D.OpenGL, this.sim3D.Scene.CurrentCamera); gridder.Init(geometry); gridder.RenderGrid = true; gridder.RenderGridWireframe = this.IsShowWireframe; gridder.SetTexture(texture); gridder.SetTextureCoods(textureCoodinates); texture.Dispose(); //textureCoodinates.Dump(); DateTime t6 = DateTime.Now; //gridderElement.SetBoundingBox(mesh.Min, mesh.Max); this.sim3D.Tag = source; // update ModelContainer's BoundingBox. BoundingBox boundingBox = this.sim3D.ModelContainer.BoundingBox; boundingBox.SetBounds(geometry.Min, geometry.Max); // update ViewType to UserView. this.sim3D.ViewType = ViewTypes.UserView; this.sim3D.AddModelElement(gridder); StringBuilder msgBuilder = new StringBuilder(); msgBuilder.AppendLine(String.Format("Init Grid DataSource in {0} secs", (t1 - t0).TotalSeconds)); msgBuilder.AppendLine(String.Format("init ControlValues in {0} secs", (t2 - t1).TotalSeconds)); msgBuilder.AppendLine(String.Format("prepare other params in {0} secs", (t3 - t2).TotalSeconds)); msgBuilder.AppendLine(String.Format("CreateMesh in {0} secs", (t4 - t3).TotalSeconds)); msgBuilder.AppendLine(String.Format("CreateTextures in {0} secs", (t5 - t4).TotalSeconds)); msgBuilder.AppendLine(String.Format("Init SimLabGrid in {0} secs", (t6 - t5).TotalSeconds)); msgBuilder.AppendLine(String.Format("Total, Create 3D Grid in {0} secs", (t6 - t0).TotalSeconds)); String msg = msgBuilder.ToString(); MessageBox.Show(msg, "Summary", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception error) { MessageBox.Show(error.ToString()); } }
private object ExportModel(ICommandContext commandContext, ContentManager contentManager) { // Read from model file var modelSkeleton = LoadSkeleton(commandContext, contentManager); // we get model skeleton to compare it to real skeleton we need to map to AdjustSkeleton(modelSkeleton); var model = LoadModel(commandContext, contentManager); // Apply materials foreach (var modelMaterial in Materials) { if (modelMaterial.MaterialInstance?.Material == null) { commandContext.Logger.Verbose($"The material [{modelMaterial.Name}] is null in the list of materials."); } model.Materials.Add(modelMaterial.MaterialInstance); } model.BoundingBox = BoundingBox.Empty; foreach (var mesh in model.Meshes) { if (TessellationAEN) { // TODO: Generate AEN model view commandContext.Logger.Error("TessellationAEN is not supported in {0}", ContextAsString); } } SkeletonMapping skeletonMapping; Skeleton skeleton; if (SkeletonUrl != null) { // Load skeleton and process it skeleton = contentManager.Load <Skeleton>(SkeletonUrl); // Assign skeleton to model model.Skeleton = AttachedReferenceManager.CreateProxyObject <Skeleton>(AssetId.Empty, SkeletonUrl); } else { skeleton = null; } skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton); // Refresh skeleton updater with model skeleton var hierarchyUpdater = new SkeletonUpdater(modelSkeleton); hierarchyUpdater.UpdateMatrices(); // Move meshes in the new nodes foreach (var mesh in model.Meshes) { // Apply scale import on meshes if (!MathUtil.NearEqual(ScaleImport, 1.0f)) { var transformationMatrix = Matrix.Scaling(ScaleImport); mesh.Draw.VertexBuffers[0].TransformBuffer(ref transformationMatrix); } var skinning = mesh.Skinning; if (skinning != null) { // Update node mapping // Note: we only remap skinning matrices, but we could directly remap skinning bones instead for (int i = 0; i < skinning.Bones.Length; ++i) { var linkNodeIndex = skinning.Bones[i].NodeIndex; var newLinkNodeIndex = skeletonMapping.SourceToSource[linkNodeIndex]; var nodeIndex = mesh.NodeIndex; var newNodeIndex = skeletonMapping.SourceToSource[mesh.NodeIndex]; skinning.Bones[i].NodeIndex = skeletonMapping.SourceToTarget[linkNodeIndex]; // Adjust scale import if (!MathUtil.NearEqual(ScaleImport, 1.0f)) { skinning.Bones[i].LinkToMeshMatrix.TranslationVector = skinning.Bones[i].LinkToMeshMatrix.TranslationVector * ScaleImport; } // If it was remapped, we also need to update matrix if (nodeIndex != newNodeIndex) { // Update mesh part var transformMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newNodeIndex, nodeIndex); transformMatrix.Invert(); skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(transformMatrix, skinning.Bones[i].LinkToMeshMatrix); } if (newLinkNodeIndex != linkNodeIndex) { // Update link part var transformLinkMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, newLinkNodeIndex, linkNodeIndex); skinning.Bones[i].LinkToMeshMatrix = Matrix.Multiply(skinning.Bones[i].LinkToMeshMatrix, transformLinkMatrix); } } } // Check if there was a remap using model skeleton if (skeletonMapping.SourceToSource[mesh.NodeIndex] != mesh.NodeIndex) { // Transform vertices var transformationMatrix = CombineMatricesFromNodeIndices(hierarchyUpdater.NodeTransformations, skeletonMapping.SourceToSource[mesh.NodeIndex], mesh.NodeIndex); mesh.Draw.VertexBuffers[0].TransformBuffer(ref transformationMatrix); // Check if geometry is inverted, to know if we need to reverse winding order // TODO: What to do if there is no index buffer? We should create one... (not happening yet) if (mesh.Draw.IndexBuffer == null) { throw new InvalidOperationException(); } Matrix rotation; Vector3 scale, translation; if (transformationMatrix.Decompose(out scale, out rotation, out translation) && scale.X * scale.Y * scale.Z < 0) { mesh.Draw.ReverseWindingOrder(); } } // Update new node index using real asset skeleton mesh.NodeIndex = skeletonMapping.SourceToTarget[mesh.NodeIndex]; } // Merge meshes with same parent nodes, material and skinning var meshesByNodes = model.Meshes.GroupBy(x => x.NodeIndex).ToList(); foreach (var meshesByNode in meshesByNodes) { // This logic to detect similar material is kept from old code; this should be reviewed/improved at some point foreach (var meshesPerDrawCall in meshesByNode.GroupBy(x => x, new AnonymousEqualityComparer <Mesh>((x, y) => x.MaterialIndex == y.MaterialIndex && // Same material ArrayExtensions.ArraysEqual(x.Skinning?.Bones, y.Skinning?.Bones) && // Same bones CompareParameters(model, x, y) && // Same parameters CompareShadowOptions(model, x, y), // Same shadow parameters x => 0)).ToList()) { if (meshesPerDrawCall.Count() == 1) { // Nothing to group, skip to next entry continue; } // Remove old meshes foreach (var mesh in meshesPerDrawCall) { model.Meshes.Remove(mesh); } // Add new combined mesh(es) var baseMesh = meshesPerDrawCall.First(); var newMeshList = meshesPerDrawCall.Select(x => x.Draw).ToList().GroupDrawData(Allow32BitIndex); foreach (var generatedMesh in newMeshList) { model.Meshes.Add(new Mesh(generatedMesh, baseMesh.Parameters) { MaterialIndex = baseMesh.MaterialIndex, Name = baseMesh.Name, Draw = generatedMesh, NodeIndex = baseMesh.NodeIndex, Skinning = baseMesh.Skinning, }); } } } // split the meshes if necessary model.Meshes = SplitExtensions.SplitMeshes(model.Meshes, Allow32BitIndex); // Refresh skeleton updater with asset skeleton hierarchyUpdater = new SkeletonUpdater(skeleton); hierarchyUpdater.UpdateMatrices(); // bounding boxes var modelBoundingBox = model.BoundingBox; var modelBoundingSphere = model.BoundingSphere; foreach (var mesh in model.Meshes) { var vertexBuffers = mesh.Draw.VertexBuffers; if (vertexBuffers.Length > 0) { // Compute local mesh bounding box (no node transformation) Matrix matrix = Matrix.Identity; mesh.BoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out mesh.BoundingSphere); // Compute model bounding box (includes node transformation) hierarchyUpdater.GetWorldMatrix(mesh.NodeIndex, out matrix); BoundingSphere meshBoundingSphere; var meshBoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out meshBoundingSphere); BoundingBox.Merge(ref modelBoundingBox, ref meshBoundingBox, out modelBoundingBox); BoundingSphere.Merge(ref modelBoundingSphere, ref meshBoundingSphere, out modelBoundingSphere); } // TODO: temporary Always try to compact mesh.Draw.CompactIndexBuffer(); } model.BoundingBox = modelBoundingBox; model.BoundingSphere = modelBoundingSphere; // merges all the Draw VB and IB together to produce one final VB and IB by entity. var sizeVertexBuffer = model.Meshes.SelectMany(x => x.Draw.VertexBuffers).Select(x => x.Buffer.GetSerializationData().Content.Length).Sum(); var sizeIndexBuffer = 0; foreach (var x in model.Meshes) { // Let's be aligned (if there was 16bit indices before, we might be off) if (x.Draw.IndexBuffer.Is32Bit && sizeIndexBuffer % 4 != 0) { sizeIndexBuffer += 2; } sizeIndexBuffer += x.Draw.IndexBuffer.Buffer.GetSerializationData().Content.Length; } var vertexBuffer = new BufferData(BufferFlags.VertexBuffer, new byte[sizeVertexBuffer]); var indexBuffer = new BufferData(BufferFlags.IndexBuffer, new byte[sizeIndexBuffer]); // Note: reusing same instance, to avoid having many VB with same hash but different URL var vertexBufferSerializable = vertexBuffer.ToSerializableVersion(); var indexBufferSerializable = indexBuffer.ToSerializableVersion(); var vertexBufferNextIndex = 0; var indexBufferNextIndex = 0; foreach (var drawMesh in model.Meshes.Select(x => x.Draw)) { // the index buffer var oldIndexBuffer = drawMesh.IndexBuffer.Buffer.GetSerializationData().Content; // Let's be aligned (if there was 16bit indices before, we might be off) if (drawMesh.IndexBuffer.Is32Bit && indexBufferNextIndex % 4 != 0) { indexBufferNextIndex += 2; } Array.Copy(oldIndexBuffer, 0, indexBuffer.Content, indexBufferNextIndex, oldIndexBuffer.Length); drawMesh.IndexBuffer = new IndexBufferBinding(indexBufferSerializable, drawMesh.IndexBuffer.Is32Bit, drawMesh.IndexBuffer.Count, indexBufferNextIndex); indexBufferNextIndex += oldIndexBuffer.Length; // the vertex buffers for (int index = 0; index < drawMesh.VertexBuffers.Length; index++) { var vertexBufferBinding = drawMesh.VertexBuffers[index]; var oldVertexBuffer = vertexBufferBinding.Buffer.GetSerializationData().Content; Array.Copy(oldVertexBuffer, 0, vertexBuffer.Content, vertexBufferNextIndex, oldVertexBuffer.Length); drawMesh.VertexBuffers[index] = new VertexBufferBinding(vertexBufferSerializable, vertexBufferBinding.Declaration, vertexBufferBinding.Count, vertexBufferBinding.Stride, vertexBufferNextIndex); vertexBufferNextIndex += oldVertexBuffer.Length; } } // Convert to Entity return(model); }
/***************************************************/ public static bool IsContaining(this PolyCurve curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { // Todo: // - to be replaced with a general method for a nurbs curve? // - this is very problematic for edge cases (cutting line going through a sharp corner, to be superseded? BoundingBox box = curve.Bounds(); if (points.Any(x => !box.IsContaining(x, true, tolerance))) { return(false); } if (!curve.IsClosed(tolerance)) { return(false); } if (curve.Curves.Count == 1 && curve.Curves[0] is Circle) { return(IsContaining(curve.Curves[0] as Circle, points, acceptOnEdge, tolerance)); } Plane p = curve.FitPlane(tolerance); double sqTol = tolerance * tolerance; if (p == null) { if (acceptOnEdge) { foreach (Point pt in points) { if (curve.ClosestPoint(pt).SquareDistance(pt) > sqTol) { return(false); } } return(true); } else { return(false); } } List <ICurve> subParts = curve.SubParts(); List <Vector> edgeDirections = subParts.Where(s => s is Line).Select(c => (c as Line).Direction()).ToList(); foreach (Point pt in points) { Point pPt = pt.Project(p); if (pPt.SquareDistance(pt) > sqTol) // not on the same plane { return(false); } Point end = p.Origin; // Avrage of control points Vector direction = (end - pPt).Normalise(); // Gets a line cutting through the curves and the point while (direction.SquareLength() <= 0.5 || edgeDirections.Any(e => 1 - Math.Abs(e.DotProduct(direction)) <= Tolerance.Angle)) // not zeroa or parallel to edges { end = end.Translate(Create.RandomVectorInPlane(p, true)); direction = (end - pPt).Normalise(); } Line ray = new Line { Start = pPt, End = end }; ray.Infinite = true; List <Point> intersects = new List <Point>(); List <Point> extraIntersects = new List <Point>(); foreach (ICurve subPart in subParts) { List <Point> iPts = subPart.ILineIntersections(ray, false, tolerance); // LineIntersection ignores the `false` foreach (Point iPt in iPts) { double signedAngle = direction.SignedAngle(subPart.ITangentAtPoint(iPt, tolerance), p.Normal); if ((subPart.IStartPoint().SquareDistance(iPt) <= sqTol)) // Keep intersections from beeing counted twice? { if (signedAngle >= -Tolerance.Angle) // tangent is to the left of the direction { intersects.Add(iPt); } else { extraIntersects.Add(iPt); } } else if ((subPart.IEndPoint().SquareDistance(iPt) <= sqTol)) { if (signedAngle <= Tolerance.Angle) // tangent is to the rigth of the direction { intersects.Add(iPt); } else { extraIntersects.Add(iPt); } } else if (Math.Abs(signedAngle) <= Tolerance.Angle) // They are parallel { extraIntersects.Add(iPt); } else { intersects.Add(iPt); } } } if (intersects.Count == 0) // did not intersect the curve (strange) { return(false); } if ((pPt.ClosestPoint(intersects.Union(extraIntersects)).SquareDistance(pPt) <= sqTol)) // if any intersection point is the point { if (acceptOnEdge) { continue; } else { return(false); } } intersects.Add(pPt); intersects = intersects.SortCollinear(tolerance); for (int j = 0; j < intersects.Count; j++) // Even indecies on a colinerar sort is outside the region { if (j % 2 == 0 && intersects[j] == pPt) { return(false); } } } return(true); }
// From Eric Jordan's convex decomposition library /// <summary> /// Merges all parallel edges in the list of vertices /// </summary> /// <param name="tolerance"></param> public void MergeParallelEdges(double tolerance) { if (Count <= 3) { // Can't do anything useful here to a triangle return; } bool[] mergeMe = new bool[Count]; int newNVertices = Count; //Gather points to process for (int i = 0; i < Count; ++i) { int lower = (i == 0) ? (Count - 1) : (i - 1); int middle = i; int upper = (i == Count - 1) ? (0) : (i + 1); double dx0 = this[middle].X - this[lower].X; double dy0 = this[middle].Y - this[lower].Y; double dx1 = this[upper].Y - this[middle].X; double dy1 = this[upper].Y - this[middle].Y; double norm0 = Math.Sqrt(dx0 * dx0 + dy0 * dy0); double norm1 = Math.Sqrt(dx1 * dx1 + dy1 * dy1); if (!(norm0 > 0.0 && norm1 > 0.0) && newNVertices > 3) { //Merge identical points mergeMe[i] = true; --newNVertices; } dx0 /= norm0; dy0 /= norm0; dx1 /= norm1; dy1 /= norm1; double cross = dx0 * dy1 - dx1 * dy0; double dot = dx0 * dx1 + dy0 * dy1; if (Math.Abs(cross) < tolerance && dot > 0 && newNVertices > 3) { mergeMe[i] = true; --newNVertices; } else { mergeMe[i] = false; } } if (newNVertices == Count || newNVertices == 0) { return; } int currIndex = 0; // Copy the vertices to a new list and clear the old Point2DList oldVertices = new Point2DList(this); Clear(); for (int i = 0; i < oldVertices.Count; ++i) { if (mergeMe[i] || newNVertices == 0 || currIndex == newNVertices) { continue; } if (currIndex >= newNVertices) { throw new Exception("Point2DList::MergeParallelEdges - currIndex[ " + currIndex + "] >= newNVertices[" + newNVertices + "]"); } MPoints.Add(oldVertices[i]); BoundingBox = BoundingBox.AddPoint(oldVertices[i]); ++currIndex; } _windingOrder = CalculateWindingOrder(); Epsilon = CalculateEpsilon(); }
public static Vector3 GetCenter(this BoundingBox bb) { return((bb.Min + bb.Max) / 2); }
/// <summary> /// Génère un modèle 3D en forme de planète à partir de plusieurs bruits. /// </summary> /// <param name="aabb">Bounding box du morceau de planète généré.</param> /// <param name="gridLevelScale">Echelle du morceau de grille à générer. L'échelle est divisée par 2 /// à chaque étage du quadtree</param> /// <param name="gridSize">Taille de la grille à générer.</param> /// <param name="highNoise">Bruit "high"</param> /// <param name="iBuffer">Index buffer en du mesh créé en sortie.</param> /// <param name="initialGridPos">Position du coin supérieur gauche de la grille à générer dans la grille initiale de range [0, 1]</param> /// <param name="lowNoise">Bruit "low"</param> /// <param name="repNoise">Bruit de répartition</param> /// <param name="vBuffer">Vertex buffer en du mesh créé en sortie.</param> /// <param name="chunkGeography">Informations de sortie concernant la géographie du morceau généré.</param> /// <param name="planetPosition">Position de la planète.</param> /// <param name="radius">Rayon de la planète.</param> /// <returns></returns> public static void GeneratePlanet(Vector3 planetPosition, float radius, int gridSize, Vector2 initialGridPos, float gridLevelScale, Noise.NoiseBase lowNoise, Noise.NoiseBase highNoise, Noise.NoiseBase repNoise, out SlimDX.Direct3D11.Buffer vBuffer, out BoundingBox aabb, out ChunkAltitude geo) { // Geography geo = new ChunkAltitude(); // Taille du buffer. int size = gridSize * gridSize; const bool computeNormals = true; Vector3 min = new Vector3(float.MaxValue); Vector3 max = new Vector3(float.MinValue); // Création du vertex buffer contenant tous les vertex à dessiner. VWrapper[] vertexBuffer = new VWrapper[size]; // Texture noise Noise.NoiseMapGenerator.NoiseParameters p = new Noise.NoiseMapGenerator.NoiseParameters() { Frequency = 128.0f, Lacunarity = 2.5f, NoiseEnd = new Vector2(initialGridPos.X + gridLevelScale, initialGridPos.Y + gridLevelScale), NoiseStart = new Vector2(initialGridPos.X, initialGridPos.Y), NoiseType = Noise.NoiseMapGenerator.NoiseParameters.RIDGED_ID, Persistence = 0.94f, Seed = 456464560 }; Noise.NoiseBase texNoise = p.CreateNoise(); float theta, phi; Vector3 transformedPos; for (int y = 0; y < gridSize; y++) { for (int x = 0; x < gridSize; x++) { // Cette section a pour but de calculer la normale par rapport au "sol" de la planète, pour cela // Elle calcule les positions des verte Vector2 pos2D = new Vector2(x / ((float)gridSize - 1), (y / ((float)gridSize - 1))); // Transformation en sphère. float noisePosX = initialGridPos.X + pos2D.X * gridLevelScale; float noisePosY = initialGridPos.Y + pos2D.Y * gridLevelScale; phi = (noisePosX) * (float)Math.PI * 2; theta = (noisePosY) * (float)Math.PI; // TODO : optimiser pour éviter les calculs redondants. transformedPos = Util.SphericalCoords.ToCartesian(theta, phi, radius);//new Vector3(xSph, ySph, zSph); // Création de la normale au sol. Vector3 normal = Vector3.Normalize(transformedPos); // Valeur du bruit float noiseValue = Noise.NoiseMapGenerator.GetMultiNoiseValue(repNoise, highNoise, lowNoise, transformedPos.X / radius, transformedPos.Y / radius, transformedPos.Z / radius); float tNoiseValue = texNoise.GetValue(transformedPos.X / radius, transformedPos.Y / radius, transformedPos.Z / radius); // Création de la position finale Vector3 finalPos = transformedPos + normal * noiseValue; Vector4 pos = new Vector4(finalPos, 1.0f); // Informations de géométrie. min = Util.MathHelper.Min(finalPos, min); max = Util.MathHelper.Max(finalPos, max); geo.MinAltitude = Math.Min(noiseValue, geo.MinAltitude); geo.MaxAltitude = Math.Max(noiseValue, geo.MaxAltitude); // Ajout des données dans le VBuffer. int index = (x + y * gridSize); vertexBuffer[index] = new VWrapper(); vertexBuffer[index].SphereNormal = normal; // Position 3D du point avec displacement. vertexBuffer[index].Vertex.Position = pos; // Position 3D du point sans displacement. vertexBuffer[index].Vertex.SpherePosition = new Vector4(transformedPos, 1.0f); vertexBuffer[index].Vertex.SphereNormal = new Vector4(normal, 1.0f); // Coordonnées de texture. vertexBuffer[index].Vertex.Texture = new Vector2(noisePosX, noisePosY); vertexBuffer[index].Vertex.Normal = new Vector4(0); vertexBuffer[index].Vertex.Altitude = noiseValue; // Valeurs additionnelles. vertexBuffer[index].Vertex.TextureId = tNoiseValue; } } // Index buffer contenant l'ordre dans lequel dessiner les vertex. (sous forme de carrés). int iBufferSize = (gridSize - 1) * (gridSize - 1) * 6; int[] indexBuffer = GetIndexBufferCpu(gridSize); if (computeNormals) { //Thread.Sleep(1); for (int i = 0; i < indexBuffer.Length / 3; i++) { Vector4 firstvec = vertexBuffer[indexBuffer[i * 3 + 1]].Vertex.Position - vertexBuffer[indexBuffer[i * 3]].Vertex.Position; Vector4 secondvec = vertexBuffer[indexBuffer[i * 3]].Vertex.Position - vertexBuffer[indexBuffer[i * 3 + 2]].Vertex.Position; Vector4 normal = new Vector4(Vector3.Cross( new Vector3(firstvec.X, firstvec.Y, firstvec.Z), new Vector3(secondvec.X, secondvec.Y, secondvec.Z)), 1.0f); normal.Normalize(); vertexBuffer[indexBuffer[(i * 3)]].Vertex.Normal += normal; vertexBuffer[indexBuffer[(i * 3 + 1)]].Vertex.Normal += normal; vertexBuffer[indexBuffer[(i * 3 + 2)]].Vertex.Normal += normal; } for (int i = 0; i < vertexBuffer.Length; i++) { var v = Util.MathHelper.ReduceXYZ(vertexBuffer[i].Vertex.Normal); v.Normalize(); vertexBuffer[i].Vertex.Normal = new Vector4(v, 1.0f); vertexBuffer[i].Vertex.SphereNormal = new Vector4(Util.MathHelper.ReduceXYZ(vertexBuffer[i].Vertex.Normal) - vertexBuffer[i].SphereNormal, 1.0f); } } // Création des buffers. DataStream vBuffStream = new DataStream(size * Vertex.Stride, true, true); for (int i = 0; i < size; i++) { vBuffStream.Write <Vertex>(vertexBuffer[i].Vertex); } vBuffStream.Position = 0; vBuffer = new SlimDX.Direct3D11.Buffer(Scene.GetGraphicsDevice(), vBuffStream, new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = (int)vBuffStream.Length, Usage = ResourceUsage.Default }); vBuffStream.Dispose(); aabb = new BoundingBox(min, max); }
/***************************************************/ public static bool IsContaining(this BoundingBox box, IGeometry geometry, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { return(box.IsContaining(geometry.IBounds(), acceptOnEdge, tolerance)); }
protected override void OnPreDraw(GameTime gameTime) { if (ControlTexture == null) { ControlTexture = new RenderTarget2D(Manager.GraphicsDevice, ActualClientArea.Width, ActualClientArea.Height); } float octoDaysPerEarthDay = 360f; float inclinationVariance = MathHelper.Pi / 3f; float playerPosX = ((float)player.ActorHost.Player.Position.GlobalBlockIndex.X / (planet.Size.X * Chunk.CHUNKSIZE_X)) * MathHelper.TwoPi; float playerPosY = ((float)player.ActorHost.Player.Position.GlobalBlockIndex.Y / (planet.Size.Y * Chunk.CHUNKSIZE_Y)) * MathHelper.TwoPi; TimeSpan diff = DateTime.UtcNow - new DateTime(1888, 8, 8); float inclination = ((float)Math.Sin(playerPosY) * inclinationVariance) + MathHelper.Pi / 6f; Console.WriteLine("Stand: " + (MathHelper.Pi + playerPosX) + " Neigung: " + inclination); Matrix sunMovement = Matrix.CreateRotationX(inclination) * //Matrix.CreateRotationY((((float)gameTime.TotalGameTime.TotalMinutes * MathHelper.TwoPi) + playerPosX) * -1); Matrix.CreateRotationY((float)(MathHelper.TwoPi - ((diff.TotalDays * octoDaysPerEarthDay * MathHelper.TwoPi) % MathHelper.TwoPi))); Vector3 sunDirection = Vector3.Transform(new Vector3(0, 0, 1), sunMovement); simpleShader.Parameters["DiffuseColor"].SetValue(new Microsoft.Xna.Framework.Color(190, 190, 190).ToVector4()); simpleShader.Parameters["DiffuseIntensity"].SetValue(0.6f); simpleShader.Parameters["DiffuseDirection"].SetValue(sunDirection); // Console.WriteLine(sunDirection); // Index3 chunkOffset = player.ActorHost.Position.ChunkIndex; Index3 chunkOffset = camera.CameraChunk; Microsoft.Xna.Framework.Color background = new Microsoft.Xna.Framework.Color(181, 224, 255); Manager.GraphicsDevice.SetRenderTarget(MiniMapTexture); Manager.GraphicsDevice.Clear(background); foreach (var renderer in chunkRenderer) { if (!renderer.ChunkPosition.HasValue) { continue; } Index3 shift = chunkOffset.ShortestDistanceXY( renderer.ChunkPosition.Value, new Index2( planet.Size.X, planet.Size.Y)); BoundingBox chunkBox = new BoundingBox( new Vector3( shift.X * Chunk.CHUNKSIZE_X, shift.Y * Chunk.CHUNKSIZE_Y, shift.Z * Chunk.CHUNKSIZE_Z), new Vector3( (shift.X + 1) * Chunk.CHUNKSIZE_X, (shift.Y + 1) * Chunk.CHUNKSIZE_Y, (shift.Z + 1) * Chunk.CHUNKSIZE_Z)); int range = 3; if (shift.X >= -range && shift.X <= range && shift.Y >= -range && shift.Y <= range) { renderer.Draw(camera.MinimapView, miniMapProjectionMatrix, shift); } } Manager.GraphicsDevice.SetRenderTarget(ControlTexture); Manager.GraphicsDevice.Clear(background); Manager.GraphicsDevice.BlendState = BlendState.AlphaBlend; Manager.GraphicsDevice.DepthStencilState = DepthStencilState.None; // Draw Sun // GraphicsDevice.RasterizerState = RasterizerState.CullNone; sunEffect.Texture = sunTexture; Matrix billboard = Matrix.Invert(camera.View); billboard.Translation = player.ActorHost.Position.LocalPosition + (sunDirection * -10); sunEffect.World = billboard; sunEffect.View = camera.View; sunEffect.Projection = camera.Projection; sunEffect.CurrentTechnique.Passes[0].Apply(); Manager.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, billboardVertices, 0, 2); Manager.GraphicsDevice.DepthStencilState = DepthStencilState.Default; foreach (var renderer in chunkRenderer) { if (!renderer.ChunkPosition.HasValue) { continue; } Index3 shift = chunkOffset.ShortestDistanceXY( renderer.ChunkPosition.Value, new Index2( planet.Size.X, planet.Size.Y)); BoundingBox chunkBox = new BoundingBox( new Vector3( shift.X * Chunk.CHUNKSIZE_X, shift.Y * Chunk.CHUNKSIZE_Y, shift.Z * Chunk.CHUNKSIZE_Z), new Vector3( (shift.X + 1) * Chunk.CHUNKSIZE_X, (shift.Y + 1) * Chunk.CHUNKSIZE_Y, (shift.Z + 1) * Chunk.CHUNKSIZE_Z)); if (camera.Frustum.Intersects(chunkBox)) { renderer.Draw(camera.View, camera.Projection, shift); } } if (player.SelectedBox.HasValue) { // Index3 offset = player.ActorHost.Position.ChunkIndex * Chunk.CHUNKSIZE; Index3 offset = camera.CameraChunk * Chunk.CHUNKSIZE; Index3 planetSize = planet.Size * Chunk.CHUNKSIZE; Index3 relativePosition = new Index3( Index2.ShortestDistanceOnAxis(offset.X, player.SelectedBox.Value.X, planetSize.X), Index2.ShortestDistanceOnAxis(offset.Y, player.SelectedBox.Value.Y, planetSize.Y), player.SelectedBox.Value.Z - offset.Z); Vector3 selectedBoxPosition = new Vector3( player.SelectedBox.Value.X - (chunkOffset.X * Chunk.CHUNKSIZE_X), player.SelectedBox.Value.Y - (chunkOffset.Y * Chunk.CHUNKSIZE_Y), player.SelectedBox.Value.Z - (chunkOffset.Z * Chunk.CHUNKSIZE_Z)); // selectionEffect.World = Matrix.CreateTranslation(selectedBoxPosition); selectionEffect.World = Matrix.CreateTranslation(relativePosition); selectionEffect.View = camera.View; selectionEffect.Projection = camera.Projection; foreach (var pass in selectionEffect.CurrentTechnique.Passes) { pass.Apply(); Manager.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, selectionLines, 0, 8, selectionIndeces, 0, 12); } } Manager.GraphicsDevice.SetRenderTarget(null); }
public static MemoryProvider CreateMemoryProviderWithDiverseSymbols(BoundingBox envelope, int count = 100) { return(new MemoryProvider(CreateDiverseFeatures(PointsSample.GenerateRandomPoints(envelope, count, 3)))); }
internal static Transform[] GetTransformsAndBounds(List <SceneGraphNode> nodes, out BoundingBox bounds) { var transforms = new Transform[nodes.Count]; bounds = BoundingBox.Empty; for (int i = 0; i < nodes.Count; i++) { transforms[i] = nodes[i].Transform; if (nodes[i] is ActorNode actorNode) { bounds = BoundingBox.Merge(bounds, actorNode.Actor.BoxWithChildren); } } return(transforms); }
public bool Perform(Creature performer, GameComponent other, DwarfTime time, float bonus, Vector3 pos, string faction) { if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame) { HasTriggered = false; return(false); } if (HasTriggered) { return(true); } HasTriggered = true; switch (Weapon.Mode) { case Weapon.AttackMode.Melee: case Weapon.AttackMode.Dogfight: { DoDamage(performer, other, bonus); break; } case Weapon.AttackMode.Area: { var box = new BoundingBox(performer.AI.Position - Vector3.One * Weapon.Range, performer.AI.Position + Vector3.One * Weapon.Range); foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both).Where(b => b.IsRoot())) { if (body.GetRoot().GetComponent <CreatureAI>().HasValue(out var creature)) { if (creature.Faction == performer.Faction) { continue; } if (performer.World.Overworld.GetPolitics(creature.Faction.ParentFaction, performer.Faction.ParentFaction).GetCurrentRelationship() != Relationship.Hateful) { continue; } DoDamage(performer, body, bonus); } else { if (body.GetRoot().GetComponent <Health>().HasValue(out var health)) { DoDamage(performer, body, bonus); } continue; } } break; } case Weapon.AttackMode.Ranged: { PlayNoise(other.GlobalTransform.Translation); LaunchProjectile(pos, other.Position, other); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature)) { creature.Stats.AcquireDisease(injury); } } break; } } return(true); }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks) { // Don't attempt any camera control if the user is trying to type intoa focus item. if (World.Gui.FocusItem != null && !World.Gui.FocusItem.IsAnyParentTransparent() && !World.Gui.FocusItem.IsAnyParentHidden()) { return; } float diffPhi = 0; float diffTheta = 0; float diffRadius = 0; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); var bounds = new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20); if (ZoomTargets.Count > 0) { Vector3 currTarget = MathFunctions.Clamp(ProjectToSurface(ZoomTargets.First()), bounds); if (Vector3.DistanceSquared(Target, currTarget) > 5) { Vector3 newTarget = 0.8f * Target + 0.2f * currTarget; Vector3 d = newTarget - Target; if (bounds.Contains(Target + d) != ContainmentType.Contains) { ZoomTargets.RemoveAt(0); } else { Target += d; Position += d; } } else { ZoomTargets.RemoveAt(0); } } Target = MathFunctions.Clamp(Target, bounds); int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled(this)) { World.Gui.MouseVisible = false; if (!shiftPressed) { shiftPressed = true; mouseOnRotate = new Point(mouse.X, mouse.Y); mousePrerotate = new Point(mouse.X, mouse.Y); } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } Mouse.SetPosition(mouseOnRotate.X, mouseOnRotate.Y); diffX = mouse.X - mouseOnRotate.X; diffY = mouse.Y - mouseOnRotate.Y; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } KeyManager.TrueMousePos = mousePrerotate; } else { if (shiftPressed) { Mouse.SetPosition(mousePrerotate.X, mousePrerotate.Y); KeyManager.TrueMousePos = new Point(mousePrerotate.X, mousePrerotate.Y); } else { KeyManager.TrueMousePos = new Point(mouse.X, mouse.Y); } shiftPressed = false; World.Gui.MouseVisible = true; } Vector3 velocityToSet = Vector3.Zero; if (EnableControl) { if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } } else if (FollowAutoTarget) { Vector3 prevTarget = Target; float damper = MathFunctions.Clamp((Target - AutoTarget).Length() - 5, 0, 1); float smooth = 0.1f * damper; Target = AutoTarget * (smooth) + Target * (1.0f - smooth); Position += (Target - prevTarget); } if (velocityToSet.LengthSquared() > 0) { World.Tutorial("camera"); Velocity = velocityToSet; } if (!KeyManager.RotationEnabled(this)) { if (!World.IsMouseOverGui) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.01f; Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.01f; Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } } int scroll = mouse.ScrollWheelValue; if (isRightPressed && KeyManager.RotationEnabled(this)) { scroll = (int)(diffY * 10) + LastWheel; } if (scroll != LastWheel && !World.IsMouseOverGui) { int change = scroll - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { var delta = change * -1; if (GameSettings.Default.InvertZoom) { delta *= -1; } diffRadius = delta * CameraZoomSpeed * dt; if (diffRadius < 0 && !FollowAutoTarget && GameSettings.Default.ZoomCameraTowardMouse && !shiftPressed) { float diffxy = (new Vector3(Target.X, 0, Target.Z) - new Vector3(World.CursorLightPos.X, 0, World.CursorLightPos.Z)).Length(); if (diffxy > 5) { Vector3 slewTarget = Target * 0.9f + World.CursorLightPos * 0.1f; Vector3 slewDiff = slewTarget - Target; Target += slewDiff; Position += slewDiff; } } } else { World.Master.SetMaxViewingLevel(World.Master.MaxViewingLevel + (int)((float)change * 0.01f)); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(World.ChunkManager, Position + Velocity, false, false, 0.5f, 1.0f)) { MoveTarget(Velocity); PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.1f; Position += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); Vector3 projectedTarget = GameSettings.Default.CameraFollowSurface ? ProjectToSurface(Target) : Target; if (!GameSettings.Default.CameraFollowSurface && (keys.IsKeyDown(Keys.LeftControl) || keys.IsKeyDown(Keys.RightControl))) { projectedTarget = ProjectToSurface(Target); } Vector3 diffTarget = projectedTarget - Target; Position = (Position + diffTarget) * 0.05f + Position * 0.95f; Target = projectedTarget * 0.05f + Target * 0.95f; float currRadius = (Position - Target).Length(); float newRadius = Math.Max(currRadius + diffRadius, 3.0f); Position = MathFunctions.ProjectOutOfHalfPlane(MathFunctions.ProjectOutOfCylinder(MathFunctions.ProjectToSphere(Position - right * diffTheta * 2 - up * diffPhi * 2, newRadius, Target), Target, 3.0f), Target, 2.0f); UpdateViewMatrix(); }
internal static void ReadCommonValue(this BinaryReader stream, ref object value) { byte type = stream.ReadByte(); switch (type) { case 0: // CommonType::Bool: value = stream.ReadByte() != 0; break; case 1: // CommonType::Integer: { value = stream.ReadInt32(); } break; case 2: // CommonType::Float: { value = stream.ReadSingle(); } break; case 3: // CommonType::Vector2: { value = stream.ReadVector2(); } break; case 4: // CommonType::Vector3: { value = stream.ReadVector3(); } break; case 5: // CommonType::Vector4: { value = stream.ReadVector4(); } break; case 6: // CommonType::Color: { value = stream.ReadColor(); } break; case 7: // CommonType::Guid: { value = stream.ReadGuid(); } break; case 8: // CommonType::String: { int length = stream.ReadInt32(); if (length <= 0) { value = string.Empty; } else { var data = new char[length]; for (int i = 0; i < length; i++) { var c = stream.ReadUInt16(); data[i] = (char)(c ^ 953); } value = new string(data); } break; } case 9: // CommonType::Box: { value = new BoundingBox(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()), new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle())); } break; case 10: // CommonType::Rotation: { value = stream.ReadQuaternion(); } break; case 11: // CommonType::Transform: { value = new Transform(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()), new Quaternion(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()), new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle())); } break; case 12: // CommonType::Sphere: { value = new BoundingSphere(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()), stream.ReadSingle()); } break; case 13: // CommonType::Rect: { value = new Rectangle(new Vector2(stream.ReadSingle(), stream.ReadSingle()), new Vector2(stream.ReadSingle(), stream.ReadSingle())); } break; case 15: // CommonType::Matrix { value = new Matrix(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); break; } case 16: // CommonType::Blob { int length = stream.ReadInt32(); value = stream.ReadBytes(length); break; } case 18: // CommonType::Ray { value = new Ray(new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()), new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle())); break; } case 19: // CommonType::Int2 { value = stream.ReadInt2(); break; } case 20: // CommonType::Int3 { value = stream.ReadInt3(); break; } case 21: // CommonType::Int4 { value = stream.ReadInt4(); break; } default: throw new SystemException(); } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList(0, boundary); int zoom = -1; DA.GetData(1, ref zoom); string fileloc = ""; DA.GetData(2, ref fileloc); if (!fileloc.EndsWith(@"\")) { fileloc = fileloc + @"\"; } string prefix = ""; DA.GetData(3, ref prefix); if (prefix == "") { prefix = slippySource; } string URL = slippyURL; //DA.GetData<string>(4, ref URL); string userAgent = ""; DA.GetData(4, ref userAgent); bool run = false; DA.GetData <bool>("Run", ref run); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); GH_Structure <GH_String> tCount = new GH_Structure <GH_String>(); for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); int tileTotalCount = 0; int tileDownloadedCount = 0; ///Get image frame for given boundary and make sure it's valid if (!boundary[i].GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary[i].GetBoundingBox(true); ///TODO: look into scaling boundary to get buffer tiles ///file path for final image string imgPath = fileloc + prefix + "_" + i + ".jpg"; ///location of final image file mapList.Append(new GH_String(imgPath), path); ///create cache folder for images string cacheLoc = fileloc + @"HeronCache\"; List <string> cacheFileLocs = new List <string>(); if (!Directory.Exists(cacheLoc)) { Directory.CreateDirectory(cacheLoc); } ///tile bounding box array List <Point3d> boxPtList = new List <Point3d>(); ///get the tile coordinates for all tiles within boundary var ranges = Convert.GetTileRange(boundaryBox, zoom); List <List <int> > tileList = new List <List <int> >(); var x_range = ranges.XRange; var y_range = ranges.YRange; if (x_range.Length > 100 || y_range.Length > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This tile range is too big (more than 100 tiles in the x or y direction). Check your units."); return; } ///cycle through tiles to get bounding box for (int y = (int)y_range.Min; y <= y_range.Max; y++) { for (int x = (int)x_range.Min; x <= x_range.Max; x++) { ///add bounding box of tile to list boxPtList.AddRange(Convert.GetTileAsPolygon(zoom, y, x).ToList()); cacheFileLocs.Add(cacheLoc + slippySource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".jpg"); tileTotalCount = tileTotalCount + 1; } } tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); ///bounding box of tile boundaries BoundingBox bbox = new BoundingBox(boxPtList); var rect = BBoxToRect(bbox); imgFrame.Append(new GH_Rectangle(rect), path); AddPreviewItem(imgPath, boundary[i], rect); ///tile range as string for (de)serialization of TileCacheMeta string tileRangeString = zoom.ToString() + x_range[0].ToString() + y_range[0].ToString() + x_range[1].ToString() + y_range[1].ToString(); ///check if the existing final image already covers the boundary. ///if so, no need to download more or reassemble the cached tiles. if ((TileCacheMeta == tileRangeString) && Convert.CheckCacheImagesExist(cacheFileLocs)) { if (File.Exists(imgPath)) { using (Bitmap imageT = new Bitmap(imgPath)) { ///getting commments currently only working for JPG ///TODO: get this to work for any image type or ///find another way to check if the cached image covers the boundary. string imgComment = imageT.GetCommentsFromJPG(); imageT.Dispose(); ///check to see if tilerange in comments matches current tilerange if (imgComment == (slippySource.Replace(" ", "") + tileRangeString)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using existing image."); continue; } } } } ///Query Slippy URL ///download all tiles within boundary ///merge tiles into one bitmap ///API to query ///Do the work of assembling image ///setup final image container bitmap int fImageW = ((int)x_range.Length + 1) * 256; int fImageH = ((int)y_range.Length + 1) * 256; Bitmap finalImage = new Bitmap(fImageW, fImageH); int imgPosW = 0; int imgPosH = 0; if (run == true) { using (Graphics g = Graphics.FromImage(finalImage)) { g.Clear(Color.Black); for (int y = (int)y_range.Min; y <= (int)y_range.Max; y++) { for (int x = (int)x_range.Min; x <= (int)x_range.Max; x++) { //create tileCache name string tileCache = slippySource.Replace(" ", "") + zoom + x + y + ".jpg"; string tileCacheLoc = cacheLoc + tileCache; //check cache folder to see if tile image exists locally if (File.Exists(tileCacheLoc)) { Bitmap tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); ///add tmp image to final g.DrawImage(tmpImage, imgPosW * 256, imgPosH * 256); tmpImage.Dispose(); } else { tileList.Add(new List <int> { zoom, y, x }); string urlAuth = Convert.GetZoomURL(x, y, zoom, slippyURL); System.Net.WebClient client = new System.Net.WebClient(); ///insert header if required client.Headers.Add("user-agent", userAgent); client.DownloadFile(urlAuth, tileCacheLoc); Bitmap tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); client.Dispose(); //add tmp image to final g.DrawImage(tmpImage, imgPosW * 256, imgPosH * 256); tmpImage.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } //increment x insert position, goes left to right imgPosW++; } //increment y insert position, goes top to bottom imgPosH++; imgPosW = 0; } //garbage collection g.Dispose(); //add tile range meta data to image comments finalImage.AddCommentsToJPG(slippySource.Replace(" ", "") + tileRangeString); //save the image finalImage.Save(imgPath, System.Drawing.Imaging.ImageFormat.Jpeg); } } //garbage collection finalImage.Dispose(); //add to tile count total tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, tCount); DA.SetDataList(3, "copyright Slippy"); }
public void Run(DEMDataSet dataset, bool withTexture = true) { try { int TEXTURE_TILES = 4; // 4: med, 8: high //_rasterService.GenerateDirectoryMetadata(dataset, false); Stopwatch sw = Stopwatch.StartNew(); string modelName = $"MontBlanc_{dataset.Name}"; string outputDir = Directory.GetCurrentDirectory(); ImageryProvider provider = ImageryProvider.EsriWorldImagery;// new TileDebugProvider(new GeoPoint(43.5,5.5)); //// You can get your boox from https://geojson.net/ (save as WKT) //string bboxWKT = "POLYGON((5.54888 43.519525, 5.61209 43.519525, 5.61209 43.565225, 5.54888 43.565225, 5.54888 43.519525))"; //// string bboxWKT = //// "POLYGON((5.594457381483949 43.545276557046044,5.652135604140199 43.545276557046044,5.652135604140199 43.52038635099936,5.594457381483949 43.52038635099936,5.594457381483949 43.545276557046044))"; //// _logger.LogInformation($"Processing model {modelName}..."); //// //// //// _logger.LogInformation($"Getting bounding box geometry..."); //var bbox = GeometryService.GetBoundingBox(bboxWKT); // DjebelMarra var bbox = new BoundingBox(24.098067346557492, 24.42468219234563, 12.7769822830208, 13.087504129660111); // MontBlanc //var bbox = GeometryService.GetBoundingBox("POLYGON((6.618804355541963 45.9658287141746,7.052764316479463 45.9658287141746,7.052764316479463 45.72379929776474,6.618804355541963 45.72379929776474,6.618804355541963 45.9658287141746))"); //var bbox = new BoundingBox(5.5613898348431485,5.597185285307553,43.49372969433046,43.50939068558466); _logger.LogInformation($"Getting height map data..."); var heightMap = _elevationService.GetHeightMap(ref bbox, dataset); ModelGenerationTransform transform = new ModelGenerationTransform(bbox, 3857, true, 1.5f, true); _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)..."); heightMap = transform.TransformHeightMap(heightMap); //======================= // Textures // PBRTexture pbrTexture = null; if (withTexture) { Console.WriteLine("Download image tiles..."); TileRange tiles = _imageryService.DownloadTiles(bbox, provider, TEXTURE_TILES); string fileName = Path.Combine(outputDir, "Texture.jpg"); Console.WriteLine("Construct texture..."); TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg); // //======================= //======================= // Normal map Console.WriteLine("Height map..."); //float Z_FACTOR = 0.00002f; //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR); var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir); pbrTexture = PBRTexture.Create(texInfo, normalMap); //hMap = hMap.CenterOnOrigin(Z_FACTOR); // //======================= } // Triangulate height map // and add base and sides _logger.LogInformation($"Triangulating height map and generating 3D mesh..."); var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture); model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".glb")); model.SaveAsWavefront(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".obj")); model = _sharpGltfService.CreateTerrainMesh(heightMap, GenOptions.Normals | GenOptions.BoxedBaseElevationMin); model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + "_normalsBox.glb")); model.SaveAsWavefront(Path.Combine(Directory.GetCurrentDirectory(), modelName + "_normalsBox.obj")); _logger.LogInformation($"Model exported as {Path.Combine(Directory.GetCurrentDirectory(), modelName + ".gltf")} and .glb"); _logger.LogInformation($"Done in {sw.Elapsed:g}"); } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }
public ParkingObject(string _VehicleType, BoundingBox _Box) { VehicleType = _VehicleType; Box = _Box; }
public void WalkUpdate(DwarfTime time, ChunkManager chunks) { // Don't attempt any camera control if the user is trying to type intoa focus item. if (World.Gui.FocusItem != null && !World.Gui.FocusItem.IsAnyParentTransparent() && !World.Gui.FocusItem.IsAnyParentHidden()) { return; } float diffPhi = 0; float diffTheta = 0; float diffRadius = 0; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); var bounds = new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20); ZoomTargets.Clear(); Target = MathFunctions.Clamp(Target, bounds); int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled(this)) { World.Gui.MouseVisible = false; if (!shiftPressed) { shiftPressed = true; mouseOnRotate = new Point(mouse.X, mouse.Y); mousePrerotate = new Point(mouse.X, mouse.Y); } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } Mouse.SetPosition(mouseOnRotate.X, mouseOnRotate.Y); diffX = mouse.X - mouseOnRotate.X; diffY = mouse.Y - mouseOnRotate.Y; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } KeyManager.TrueMousePos = mousePrerotate; } else { if (shiftPressed) { Mouse.SetPosition(mousePrerotate.X, mousePrerotate.Y); KeyManager.TrueMousePos = new Point(mousePrerotate.X, mousePrerotate.Y); } else { KeyManager.TrueMousePos = new Point(mouse.X, mouse.Y); } shiftPressed = false; World.Gui.MouseVisible = true; } Vector3 velocityToSet = Vector3.Zero; if (EnableControl) { if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 mov = forward; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed; } } if (keys.IsKeyDown(ControlSettings.Mappings.Fly)) { flyKeyPressed = true; } else { if (flyKeyPressed) { flying = !flying; } flyKeyPressed = false; } if (velocityToSet.LengthSquared() > 0) { if (!flying) { float y = Velocity.Y; Velocity = Velocity * 0.5f + 0.5f * velocityToSet; Velocity = new Vector3(Velocity.X, y, Velocity.Z); } else { Velocity = Velocity * 0.5f + 0.5f * velocityToSet; } } LastWheel = mouse.ScrollWheelValue; float ymult = flying ? 0.9f : 1.0f; Velocity = new Vector3(Velocity.X * 0.9f, Velocity.Y * ymult, Velocity.Z * 0.9f); float subSteps = 10.0f; float subStepLength = 1.0f / subSteps; crouched = false; for (int i = 0; i < subSteps; i++) { VoxelHandle currentVoxel = new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(Position)); var below = VoxelHelpers.GetNeighbor(currentVoxel, new GlobalVoxelOffset(0, -1, 0)); var above = VoxelHelpers.GetNeighbor(currentVoxel, new GlobalVoxelOffset(0, 1, 0)); if (above.IsValid && !above.IsEmpty) { crouched = true; } if (!flying) { if (!below.IsValid || below.IsEmpty) { Velocity += dt * Gravity * subStepLength; } else if (keys.IsKeyDown(ControlSettings.Mappings.Jump)) { Velocity += -dt * Gravity * subStepLength * 4; } if (currentVoxel.IsValid && currentVoxel.LiquidLevel > 0) { Velocity += -dt * Gravity * subStepLength * 0.999f; if (keys.IsKeyDown(ControlSettings.Mappings.Jump)) { Velocity += -dt * Gravity * subStepLength * 0.5f; } Velocity *= 0.99f; } } if (!CollidesWithChunks(World.ChunkManager, Position, true, true, 0.4f, 0.9f)) { MoveTarget(Velocity * dt * subStepLength); PushVelocity = Vector3.Zero; } else { MoveTarget(Velocity * dt * subStepLength); } } Target += right * diffTheta * 0.1f; Target += up * diffPhi * 0.1f; var diffTarget = Target - Position; diffTarget.Normalize(); Target = Position + diffTarget * 1.0f; UpdateBasisVectors(); UpdateViewMatrix(); }
/// <summary> /// /// </summary> /// <param name="bounds"></param> /// <param name="threshold"></param> /// <param name="maxDepth"></param> public Octree(BoundingBox bounds, int threshold, int maxDepth) : base(bounds, threshold, maxDepth) { }
public bool Intersects(BoundingBox box) { return(boundingBox.Intersects(box)); }
/// <summary> /// Query the QuadTree, returning the items that are in the given area /// </summary> /// <param name="area"></param> /// <returns></returns> public List <T> Query(BoundingBox area) { return(m_root.Query(area)); }
public void build(PrimitiveList primitives) { Timer t = new Timer(); t.start(); this.primitives = primitives; int n = primitives.getNumPrimitives(); // compute bounds bounds = primitives.getWorldBounds(null); // create grid from number of objects bounds.enlargeUlps(); Vector3 w = bounds.getExtents(); double s = Math.Pow((w.x * w.y * w.z) / n, 1 / 3.0); nx = MathUtils.clamp((int)((w.x / s) + 0.5), 1, 128); ny = MathUtils.clamp((int)((w.y / s) + 0.5), 1, 128); nz = MathUtils.clamp((int)((w.z / s) + 0.5), 1, 128); voxelwx = w.x / nx; voxelwy = w.y / ny; voxelwz = w.z / nz; invVoxelwx = 1 / voxelwx; invVoxelwy = 1 / voxelwy; invVoxelwz = 1 / voxelwz; UI.printDetailed(UI.Module.ACCEL, "Creating grid: {0}x{1}x{3} ...", nx, ny, nz); List <int>[] buildCells = new List <int> [nx * ny * nz]; // add all objects into the grid cells they overlap int[] imin = new int[3]; int[] imax = new int[3]; int numCellsPerObject = 0; for (int i = 0; i < n; i++) { getGridIndex(primitives.getPrimitiveBound(i, 0), primitives.getPrimitiveBound(i, 2), primitives.getPrimitiveBound(i, 4), imin); getGridIndex(primitives.getPrimitiveBound(i, 1), primitives.getPrimitiveBound(i, 3), primitives.getPrimitiveBound(i, 5), imax); for (int ix = imin[0]; ix <= imax[0]; ix++) { for (int iy = imin[1]; iy <= imax[1]; iy++) { for (int iz = imin[2]; iz <= imax[2]; iz++) { int idx = ix + (nx * iy) + (nx * ny * iz); if (buildCells[idx] == null) { buildCells[idx] = new List <int>(); } buildCells[idx].Add(i); numCellsPerObject++; } } } } UI.printDetailed(UI.Module.ACCEL, "Building cells ..."); int numEmpty = 0; int numInFull = 0; cells = new int[nx * ny * nz][]; //int i = 0; //foreach (List<int> cell in buildCells) for (int i = 0; i < buildCells.Length; i++) { if (buildCells[i] != null) { if (buildCells[i].Count == 0) { numEmpty++; buildCells[i] = null; } else { cells[i] = buildCells[i].ToArray(); numInFull += buildCells[i].Count; } } else { numEmpty++; } //i++; } t.end(); UI.printDetailed(UI.Module.ACCEL, "Uniform grid statistics:"); UI.printDetailed(UI.Module.ACCEL, " * Grid cells: {0}", cells.Length); UI.printDetailed(UI.Module.ACCEL, " * Used cells: {0}", cells.Length - numEmpty); UI.printDetailed(UI.Module.ACCEL, " * Empty cells: {0}", numEmpty); UI.printDetailed(UI.Module.ACCEL, " * Occupancy: {0}", 100.0 * (cells.Length - numEmpty) / cells.Length); UI.printDetailed(UI.Module.ACCEL, " * Objects/Cell: {0}", (double)numInFull / (double)cells.Length); UI.printDetailed(UI.Module.ACCEL, " * Objects/Used Cell: {0}", (double)numInFull / (double)(cells.Length - numEmpty)); UI.printDetailed(UI.Module.ACCEL, " * Cells/Object: {0}", (double)numCellsPerObject / (double)n); UI.printDetailed(UI.Module.ACCEL, " * Build time: {0}", t.ToString()); }
private IList <IFeature> GetFeaturesInTile(TileInfo tileInfo) { if (TileSource == null) { return(null); } var features = _cache?.Find(tileInfo.Index); // Is tile in cache? if (features == null) { // No, tile not in cache, so get tile data new // Calc tile offset relative to upper left corner double factor = (tileInfo.Extent.MaxX - tileInfo.Extent.MinX) / 4096.0; var tileData = TileSource.GetTile(tileInfo); if (tileData == null) { // Tile isn't in this source, so construct one from lower zoom level var maxZoom = int.Parse(BruTile.Utilities.GetNearestLevel(TileSource.Schema.Resolutions, TileSource.Schema.Resolutions[(TileSource.Schema.Resolutions.Count - 1).ToString()].UnitsPerPixel)); // Get bounds of this tile var bounds = new BoundingBox(new Point(tileInfo.Extent.MinX, tileInfo.Extent.MinY), new Point(tileInfo.Extent.MaxX, tileInfo.Extent.MaxY)); // Calc new TileInfo var zoom = int.Parse(tileInfo.Index.Level); // If zoom is ok, than there are no tile informations for this tile if (zoom <= maxZoom) { return(null); } var tileX = tileInfo.Index.Col; var tileY = tileInfo.Index.Row; while (zoom > maxZoom) { zoom--; tileX = tileX >> 1; tileY = tileY >> 1; } var newTileInfo = new TileInfo { Index = new TileIndex(tileX, tileY, zoom.ToString()) }; // Now get features for this overview tile var newFeatures = GetFeaturesInTile(newTileInfo); // Extract all features, which belong to small tile features = new List <IFeature>(); foreach (var feature in newFeatures) { if (feature is VectorTileFeature vft) { if (vft.Bounds.Intersects(bounds)) { features.Add(vft); } } } // Save for later use if (_cache != null) { _cache.Add(tileInfo.Index, features); } } if (features == null && tileData != null) { // Parse tile and convert it to a feature list Stream stream = new MemoryStream(tileData); if (IsGZipped(stream)) { stream = new GZipStream(stream, CompressionMode.Decompress); } features = VectorTileParser.Parse(tileInfo, stream); // Save for later use if (_cache != null && features.Count > 0) { _cache.Add(tileInfo.Index, features); } stream = null; } } System.Diagnostics.Debug.WriteLine($"Cached Tile Level={tileInfo.Index.Level}, Col={tileInfo.Index.Col}, Row={tileInfo.Index.Row}"); return(features); }
/// <summary> /// Construct a quadtree node with the given bounds /// </summary> public zzQuadTreeNode(BoundingBox bounds) { Bounds = bounds; }
public VectorTileProvider(ITileSource tileSource, BoundingBox bounds, ITileCache <IList <IFeature> > cache = null) { TileSource = tileSource; Bounds = bounds; _cache = cache; }
public zzQuadTree(BoundingBox rectangle) { m_rectangle = rectangle; m_root = new zzQuadTreeNode <T>(m_rectangle); }