public static void Create2DElement(String name, String texture, Vector2 TopLeft, Vector2 BottomRight) { MaterialPtr material = MaterialManager.Singleton.Create(name, "General"); material.GetTechnique(0).GetPass(0).CreateTextureUnitState(texture); material.GetTechnique(0).GetPass(0).DepthCheckEnabled = false; material.GetTechnique(0).GetPass(0).DepthWriteEnabled = false; material.GetTechnique(0).GetPass(0).LightingEnabled = false; // Create background rectangle covering the whole screen Rectangle2D rect = new Rectangle2D(true); rect.SetCorners(TopLeft.x * 2 - 1, 1 - TopLeft.y * 2, BottomRight.x * 2 - 1, 1 - BottomRight.y * 2); //rect.SetCorners(-1.0f, 1.0f, 1.0f, -1.0f); rect.SetMaterial(name); // Render the background before everything else rect.RenderQueueGroup = (byte)RenderQueueGroupID.RENDER_QUEUE_OVERLAY; // Use infinite AAB to always stay visible AxisAlignedBox aab = new AxisAlignedBox(); aab.SetInfinite(); rect.BoundingBox = aab; // Attach background to the scene SceneNode node = _OgreEngine.mMgr.RootSceneNode.CreateChildSceneNode("2D__" + name); node.AttachObject(rect); }
/// <summary> /// Checks if an AABB intersects with the frustum /// </summary> /// <param name="aabb">AABB</param> /// <returns>Returns true if the AABB intersects otherwise false</returns> public bool Intersect(AxisAlignedBox aabb) { bool result = true; float s, e; Vector3.Dot(ref aabb.Center, ref _planes[0].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[0], out e); result &= (s - e) < -_planes[0].D; Vector3.Dot(ref aabb.Center, ref _planes[1].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[1], out e); result &= (s - e) < -_planes[1].D; Vector3.Dot(ref aabb.Center, ref _planes[2].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[2], out e); result &= (s - e) < -_planes[2].D; Vector3.Dot(ref aabb.Center, ref _planes[3].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[3], out e); result &= (s - e) < -_planes[3].D; Vector3.Dot(ref aabb.Center, ref _planes[4].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[4], out e); result &= (s - e) < -_planes[4].D; Vector3.Dot(ref aabb.Center, ref _planes[5].Normal, out s); Vector3.Dot(ref aabb.HalfSize, ref _absPlanes[5], out e); result &= (s - e) < -_planes[5].D; return result; }
public void Create(AxisAlignedBox box) { this.wireBox = this.CreateViewportManualObject(vfFlag); SetupBox(box); Draw(false); Engine.Graphics.SceneManager.RootSceneNode.AttachObject(this.wireBox); }
public PhysObj(float radius, string id, float invMass = 1.0f, float restitution = 0.99f, float frictionCoeff = 0.1f) { this.invMass = invMass; this.restitution = restitution; this.id = id; this.radius = radius; this.frictionCoeff = frictionCoeff; this.resForces = new Vector3(); this.velocity = new Vector3(); this.forceList = new List<Force>(); this.sphere = new Sphere(); this.aabb = new AxisAlignedBox(); this.collisionList = new List<Contacts>(); }
public void SetCamera(Camera cam, CameraDirection dir) { AxisAlignedBox boundingBox = displayObject.BoundingBox; // find the size along the largest axis float size = Math.Max(Math.Max(boundingBox.Size.x, boundingBox.Size.y), boundingBox.Size.z); Vector3 dirVec; switch (dir) { default: case CameraDirection.Above: // for some reason axiom messes up the camera matrix when you point // the camera directly down, so this vector is ever so slightly off // from negative Y. dirVec = new Vector3(0.0001f, -1f, 0f); dirVec.Normalize(); break; case CameraDirection.North: dirVec = Vector3.UnitZ; break; case CameraDirection.South: dirVec = Vector3.NegativeUnitZ; break; case CameraDirection.West: dirVec = Vector3.UnitX; break; case CameraDirection.East: dirVec = Vector3.NegativeUnitX; break; } cam.Position = boundingBox.Center + (size * 2 * (-dirVec)); cam.Direction = dirVec; }
// this version checks against extra culling planes public new bool IsObjectVisible(AxisAlignedBox bound, out FrustumPlane culledBy) { culledBy = FrustumPlane.None; // Null boxes always invisible if (bound.IsNull) { return(false); } // infinite boxes always visible if (bound.IsInfinite) { return(true); } // Make any pending updates to the calculated frustum planes UpdateFrustumPlanes(); // check extra culling planes bool extraResults; extraResults = this.extraCullingFrustum.IsObjectVisible(bound); if (!extraResults) { return(false); } // check "regular" camera frustum bool regcamresults = base.IsObjectVisible(bound, out culledBy); if (!regcamresults) { // culled by regular culling planes return(regcamresults); } return(true); }
private void render() { //draw the health bar if (health < maxHealth) { var g = Root.instance.graphics; var p = transform.DerivedPosition; var s = new Vector2(p.X - 50, p.Y); var e = new Vector2(p.X + 50, p.Y); var l = (float)health / (float)maxHealth; var bg = AxisAlignedBox. FromRect(s.X, s.Y - 3, 50, 4); var fg = AxisAlignedBox. FromRect(s.X, s.Y - 3, 50 * l, 4); g.Draw(null, bg, Color.White); g.Draw(null, fg, Color.Red); } gui.label(transform.DerivedPosition, moveState.ToString()); }
//private void init() //{ // _transform = this.gameObject.transform2(); //} private void render() { if (frame >= frames.Count || frame < 0) { return; } var src = AxisAlignedBox.FromRect(frames[frame].point * size, frames[frame].size); Root.instance.graphics.Draw(renderQuere, material, gameObject.transform.DerivedPosition + offset, src, color, gameObject.transform.DerivedOrientation + rotation, Vector2.Zero,//origin, size * gameObject.transform.DerivedScale, spriteEffect, gameObject.transform.DerivedDepth); //var end = ProjectPointFromCenterRotation(100); //Root.instance.graphics.DrawLine(renderQuere, material, _transform.DerivedPosition, end, color); }
public bool buttonold(int renderQueue, float scale, AxisAlignedBox rect, BmFont font, float depth, string text) { rect.SetExtents(rect.minVector + groupOffset, rect.maxVector + groupOffset + buttonPadding + buttonPadding); var mp = Root.instance.input.MousePosition; var gp = screenToGUI(mp); var isOver = rect.Contains(gp); var bg = isOver ? skin.button.hover.texture : skin.button.normal.texture; var border = isOver ? buttonBorderHover : buttonBorder; var color = isOver ? buttonTextColorHover : buttonTextColor; //Root.instance.graphics.beginScissor(rect); Root.instance.graphics.Draw(renderQueue, rect, buttonBackground, depth); Root.instance.graphics.DrawRect(renderQueue, rect, buttonBorder); Root.instance.graphics.DrawText(renderQueue, font, scale, rect.minVector + buttonPadding, text, color, depth); //Root.instance.graphics.endScissor(); return(Root.instance.input.IsLeftMouseDown && isOver); return(false); }
void SearchUnitInBox(List <Unit> targetList) { float extentsX, extentsY, extentsZ; unsafe { fixed(float *ptr = GetTemplate().BoxDatas.Extents) { extentsX = ptr[0]; extentsY = ptr[1]; extentsZ = ptr[2]; } } var check = new AnyUnitInObjectRangeCheck(this, GetTemplate().MaxSearchRadius, false); var searcher = new UnitListSearcher(this, targetList, check); Cell.VisitAllObjects(this, searcher, GetTemplate().MaxSearchRadius); float halfExtentsX = extentsX / 2.0f; float halfExtentsY = extentsY / 2.0f; float halfExtentsZ = extentsZ / 2.0f; float minX = GetPositionX() - halfExtentsX; float maxX = GetPositionX() + halfExtentsX; float minY = GetPositionY() - halfExtentsY; float maxY = GetPositionY() + halfExtentsY; float minZ = GetPositionZ() - halfExtentsZ; float maxZ = GetPositionZ() + halfExtentsZ; AxisAlignedBox box = new AxisAlignedBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)); targetList.RemoveAll(unit => { return(!box.contains(new Vector3(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ()))); }); }
/* Update the octreezone specific data for a node */ public override void update() { this.mOctreeWorldAABB.IsNull = true; // need to use object iterator here. foreach (PCZSceneNode m in mAssociatedNode.Children) { // merge world bounds of object //mOctreeWorldAABB.Merge(m.GetWorldBoundingBox(true)); AxisAlignedBox b = m.WorldAABB; b.Transform(m.Parent.FullTransform); this.mOctreeWorldAABB.Merge(b); } // update the Octant for the node because things might have moved. // if it hasn't been added to the octree, add it, and if has moved // enough to leave it's current node, we'll update it. if (!this.mOctreeWorldAABB.IsNull) { ((OctreeZone)mAssociatedZone).UpdateNodeOctant(this); } }
protected override void onInit() { _terrain = Root.instance.RootObject.getScript <Terrain>(); _shape = new CompoundShape(); var p = _transform.DerivedPosition; var aabb = new AxisAlignedBox(p, p + Settings.TileSizeV); for (var xx = 0; xx < width; xx++) { for (var yy = 0; yy < width; yy++) { var block = _terrain.GetForeground(x + xx, y + yy); if (block > 0) { aabb.Center = new Vector2(xx, yy) * Settings.TileSizeV; var shape = new Shape(aabb); _shape.addShape(shape); } } } }
public void LoadGameObject(IFileGeometry3D geo, FileInfo texture, string fileName) { var em = context.GetEntityManager(); var box = AxisAlignedBox.CreateFrom(geo.Positions); var center = box.Center; var c = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#B3B598"); GraphicEntity en; if (geo.TextureCoors.Any()) { en = EntityBuilders.BuildTextured(context, geo.Positions, geo.Indices, geo.TextureCoors.ToArray(), texture, SharpDX.Direct3D11.CullMode.None); } else { en = EntityBuilders.BuildColored(context, geo.Positions, geo.Indices, geo.Normals, ToVector4(c), SharpDX.Direct3D11.CullMode.Front); en.UpdateComponent(FlatShadingGeometryComponent.Create()); } en.UpdateComponent(TransformComponent.Create(Matrix4x4.CreateTranslation(Vector3.Zero - center))); GameObjects.Add(new SingleVisualObject(en.Tag, fileName)); //var boxlines = PolylineGameObject.Create( // Context, // new ElementTag("poly"), // GeometryBuilder.BuildBox( // new AxisAlignedBox(box.Minimum, box.Maximum)), // V4Colors.Blue // ); //Context.GetEntityManager().GetEntity(boxlines.Tag) // .UpdateComponent(TransformComponent.Create(Matrix4x4.CreateTranslation(Vector3.Zero - center))); //GameObjects.Add(boxlines); }
public Intersection Intersect(AxisAlignedBox box1, AxisAlignedBox box2) { this.intersect++; Vector3[] outside = box1.Corners; Vector3[] inside = box2.Corners; if (inside[4].x <outside[0].x || inside[4].y <outside[0].y || inside[4].z <outside[0].z || inside[0].x> outside[4].x || inside[0].y> outside[4].y || inside[0].z> outside[4].z) { return(Intersection.Outside); } if (inside[0].x > outside[0].x && inside[0].y > outside[0].y && inside[0].z > outside[0].z && inside[4].x < outside[4].x && inside[4].y < outside[4].y && inside[4].z < outside[4].z) { return(Intersection.Inside); } else { return(Intersection.Intersect); } }
public override void doGui() { var mp = input.MousePosition; var wp = mainCamera.screenToWorld(mp); var p = world.worldToIso(wp); var mouse = input.MousePosition; var gp = gui.screenToGUI(mouse); if (ray.hit) { //var wp = world.isoToWorld(mp.X, mp.Y, world.currentMapDepth) + new Vector2(0, world.currentMapDepth * (world.blockSizeOver2 + world.floorSizeOver2)); var content = new GUIContent(string.Format("mx:{4}, my:{5}, x:{0}, y:{1}, z:{2}, type:{3}", ray.iso.x, ray.iso.y, ray.iso.z, ray.objectType, p.X, p.Y)); var size = gui.skin.box.CalcSize(content, 100); gui.box(AxisAlignedBox.FromRect(gp, size), content); } else { var content = new GUIContent(string.Format("mx:{0}, my:{1}", p.X, p.Y)); var size = gui.skin.box.CalcSize(content, 100); gui.box(AxisAlignedBox.FromRect(gp, size), content); } }
/// <summary> /// Allows for merging two boxes together (combining). /// </summary> /// <param name="box">Source box.</param> public void Merge(AxisAlignedBox box) { if (box.IsNull) { // nothing to merge with in this case, just return return; } else if (box.IsInfinite) { this.IsInfinite = true; } else if (this.IsNull) { SetExtents(box.Minimum, box.Maximum); } else if (!this.IsInfinite) { if (box.minVector.X < minVector.X) { minVector.X = box.minVector.X; } if (box.maxVector.X > maxVector.X) { maxVector.X = box.maxVector.X; } if (box.minVector.Y < minVector.Y) { minVector.Y = box.minVector.Y; } if (box.maxVector.Y > maxVector.Y) { maxVector.Y = box.maxVector.Y; } UpdateCorners(); } }
/** Checks the given OctreeNode, and determines if it needs to be moved * to a different octant. */ public void UpdateOctreeNode(OctreeNode node) { AxisAlignedBox box = node.WorldAABB; if (box.IsNull) { return; } if (node.Octant == null) { //if outside the octree, force into the root node. if (!node.IsInBox(this.octree.Box)) { this.octree.AddNode(node); } else { AddOctreeNode(node, this.octree); } return; } if (!node.IsInBox(node.Octant.Box)) { RemoveOctreeNode(node); //if outside the octree, force into the root node. if (!node.IsInBox(this.octree.Box)) { this.octree.AddNode(node); } else { AddOctreeNode(node, this.octree); } } }
internal AnatomyContextWindowLiveThumbHost getThumbnail(AnatomyContextWindow window) { Anatomy anatomy = window.Anatomy; Radian theta = sceneViewController.ActiveWindow.Camera.getFOVy(); //Generate thumbnail AxisAlignedBox boundingBox = anatomy.WorldBoundingBox; Vector3 center = boundingBox.Center; Vector3 translation = center; Vector3 direction = anatomy.PreviewCameraDirection; translation += direction * boundingBox.DiagonalDistance / (float)Math.Tan(theta); LayerState layers = new LayerState(anatomy.TransparencyNames, 1.0f); //Create a new thumb host or update an existing one if (window.ThumbHost == null) { AnatomyContextWindowLiveThumbHost host = new AnatomyContextWindowLiveThumbHost(window) { Layers = layers, Translation = translation, LookAt = center }; liveThumbnailController.addThumbnailHost(host); liveThumbnailController.setVisibility(host, true); return(host); } else { window.ThumbHost.Translation = translation; window.ThumbHost.LookAt = center; window.ThumbHost.Layers = layers; liveThumbnailController.updateCameraAndLayers(window.ThumbHost); return(window.ThumbHost); } }
public static GameObject prefabEnemy(this GameObject parent) { var go = parent.createChild(); go.transform.Depth = 1f; go.transform.Position = new Vector2(12.5f * Map.tileSize, 12.5f * Map.tileSize); var ai = go.createScript <SimpleAI>(); var sprite = go.createScript <JsonAnimation>(); sprite.file = "content/sprites/skeleton.json"; //textureName = "content/textures/stickfigure.png"; //sprite.color = Color.Red; //sprite.size = new Vector2(16, 32) * Game.WORLD_SCALE; //sprite.origin = new Vector2(0.5f, 0.5f); var physics = go.createScript <Physics>(); physics.shape = AxisAlignedBox.FromRect(Vector2.Zero, new Vector2(16f, 32f) * Game.WORLD_SCALE); var stats = go.createScript <Stats>(); stats.maxhp = 10; stats.hp = 10; stats.xp = 10; var collider = go.createScript <Collider>(); collider.flags = Physics.QUERY_ENEMIES; collider.collidesWith = Physics.QUERY_PLAYER; //collider.notifyObject = go; collider.size = new Vector2(16, 32) * Game.WORLD_SCALE; //collider.origin = new Vector2(0.5f, 0.5f); var knockback = go.createScript <Knockback>(); var flash = go.createScript <FlashSpriteOnDamage>(); return(go); }
public void Init(AxisAlignedBox box, int depth) { rootSceneNode = new OctreeNode(this, "SceneRoot"); rootSceneNode.SetAsRootNode(); defaultRootNode = rootSceneNode; this.maxDepth = depth; this.octree = new Octree(null); this.octree.Box = box; Vector3 Min = box.Minimum; Vector3 Max = box.Maximum; this.octree.HalfSize = (Max - Min) / 2; this.numObjects = 0; var scalar = new Vector3(1.5f, 1.5f, 1.5f); this.scaleFactor.Scale = scalar; }
/// <summary> /// /// </summary> /// <param name="ent"></param> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="scale"></param> public virtual void AddEntityToBoundingBox(Entity ent, Vector3 position, Quaternion rotation, Vector3 scale) { #warning Matrix4 accepts no Quaternation in ctor Matrix4 mat = Matrix4.FromMatrix3(rotation.ToRotationMatrix()); mat.Scale = scale; AxisAlignedBox entBounds = ent.BoundingBox; Vector3 relPosition = position - mCenterPoint; if (mTrueBoundsUndefined) { mTrueBounds.Minimum = entBounds.Minimum + relPosition; mTrueBounds.Maximum = entBounds.Maximum + relPosition; mTrueBoundsUndefined = false; } else { Vector3 min = mTrueBounds.Minimum; Vector3 max = mTrueBounds.Maximum; min.Floor(entBounds.Minimum + relPosition); max.Floor(entBounds.Maximum + relPosition); mTrueBounds.Maximum = max; mTrueBounds.Minimum = min; } }
private void Update() { if (this.isCreated) { // recreate the box this.box = new AxisAlignedBox(this.min, this.max); // update the resizable boxes foreach (ResizableBox resizableBox in this.resizableBoxes) { resizableBox.Update(box); } // redraw the perspective view box this.UpdateWireBox(); // update the selected block if (this.selectedObject != null) { this.selectedObject.BoundingBox = this.box; } } }
public override void FindNodes(AxisAlignedBox t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude) { // if this zone has an enclosure, check against the enclosure AABB first if (null != mEnclosureNode) { if (!mEnclosureNode.WorldAABB.Intersects(t)) { // AABB of zone does not intersect t, just return. return; } } // use the Octree to more efficiently find nodes intersecting the aab this.rootOctree._findNodes(t, ref list, exclude, includeVisitors, false); // if asked to, recurse through portals if (recurseThruPortals) { foreach (Portal portal in mPortals) { // check portal versus boundign box if (portal.intersects(t)) { // make sure portal hasn't already been recursed through if (!visitedPortals.Contains(portal)) { // save portal to the visitedPortals list visitedPortals.Add(portal); // recurse into the connected zone portal.getTargetZone().FindNodes(t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude); } } } } }
private void init() { graphics.setSortOrder(WORLD_RENDER_QUEUE, RenderQueueSortMode.PreserverOrder); world = Root.instance.RootObject.getScript <WorldManager>(); tm = rootObject.find("tools").getScript <ToolManager>(); worldObjectRenderers = new WorldObjectRenderer[256]; spriteSheetMaterial = resources.createMaterialFromTexture("content/textures/gnomoria.png"); spriteSheetMaterial.SetSamplerState(SamplerState.PointClamp); #region Load Sprite Sheet spriteSheet.addSprite("dirtfloor", new WorldSprite(AxisAlignedBox.FromRect(0, 52, 32, 20), 32, 20, 0, 0)); spriteSheet.addSprite("dirtwall", new WorldSprite(AxisAlignedBox.FromRect(0, 72, 32, 32), 32, 32, 0, -16)); spriteSheet.addSprite("floorselection", new WorldSprite(AxisAlignedBox.FromRect(0, 0, 32, 20), 32, 20, 0, 0)); spriteSheet.addSprite("wallselection", new WorldSprite(AxisAlignedBox.FromRect(0, 20, 32, 32), 32, 32, 0, -16)); worldObjectRenderers[(int)WorldObjectType.DirtFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0x96, 0x63, 0x30)); worldObjectRenderers[(int)WorldObjectType.LightDirtFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0xB4, 0x81, 0x4E)); worldObjectRenderers[(int)WorldObjectType.DarkDirtFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0x78, 0x45, 0x30)); worldObjectRenderers[(int)WorldObjectType.ClayFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0x66, 0x33, 0x00)); worldObjectRenderers[(int)WorldObjectType.LightClayFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0x84, 0x1e, 0x51)); worldObjectRenderers[(int)WorldObjectType.DarkClayFloor] = new SpriteRenderer(this, "dirtfloor", new Color(0x48, 0x00, 0x15)); worldObjectRenderers[(int)WorldObjectType.DirtWall] = new SpriteRenderer(this, "dirtwall", new Color(0x96, 0x63, 0x30)); //worldObjectRenderers[(int)WorldObjectType.LightDirtWall] = new SpriteRenderer(this, "dirtwall", new Color(0xB4, 0x81, 0x4E)); //worldObjectRenderers[(int)WorldObjectType.DarkDirtWall] = new SpriteRenderer(this, "dirtwall", new Color(0x78, 0x45, 0x30)); //worldObjectRenderers[(int)WorldObjectType.ClayWall] = new SpriteRenderer(this, "dirtwall", new Color(0x66, 0x33, 0x00)); //worldObjectRenderers[(int)WorldObjectType.LightClayWall] = new SpriteRenderer(this, "dirtwall", new Color(0x84, 0x1e, 0x51)); //worldObjectRenderers[(int)WorldObjectType.DarkClayWall] = new SpriteRenderer(this, "dirtwall", new Color(0x48, 0x00, 0x15)); worldObjectRenderers[(int)WorldObjectType.FloorSelection] = new SpriteRenderer(this, "floorselection", new Color(0x0, 0x88, 0x88)); worldObjectRenderers[(int)WorldObjectType.WallSelection] = new SpriteRenderer(this, "wallselection", new Color(0x0, 0x88, 0x88)); #endregion }
static void _Create(IContextState context, IEnumerable <IFileGeometry3D> meshes, FileInfo texture, string name, LoadedVisualObject visual) { List <ElementTag> t = new List <ElementTag>(); var details = new LoadedObjectDetails(); var baseTag = ElementTag.New(); var index = 0; AxisAlignedBox fullBox = AxisAlignedBox.Zero; foreach (var geo in meshes) { var cc = geo.Name.Split(',').Select(x => float.Parse(x.Trim(new[] { ' ', '<', '>' }), System.Globalization.NumberStyles.Float)).ToArray(); var color = new Vector4(cc[0] / 256f, cc[1] / 256f, cc[2] / 256f, 1); var tag = Create(context, baseTag.WithPrefix(geo.Name ?? index.ToString()), new GeometryStructures <IFileGeometry3D>(geo), texture, out var box, color); t.Add(tag); fullBox = fullBox.Merge(box.Bounds); details.VertexCount += geo.Positions.Count; details.TriangleCount += (geo.Indices.Count / 3); index++; } visual.tags.AddRange(t); visual.Details = details; var size = fullBox.Size(); visual.worldX = VisualPolylineObject.Create(context, baseTag.WithPrefix("WorldX"), new[] { Vector3.Zero + Vector3.UnitX * size.X * -2f, Vector3.Zero + Vector3.UnitX * size.X * 2f }, V4Colors.Red, false); visual.worldX.IsVisible = false; visual.worldY = VisualPolylineObject.Create(context, baseTag.WithPrefix("WorldY"), new[] { Vector3.Zero + Vector3.UnitY * size.Y * -2f, Vector3.Zero + Vector3.UnitY * size.Y * 2f }, V4Colors.Green, false); visual.worldY.IsVisible = false; visual.worldZ = VisualPolylineObject.Create(context, baseTag.WithPrefix("WorldZ"), new[] { Vector3.Zero + Vector3.UnitZ * size.Z * -2f, Vector3.Zero + Vector3.UnitZ * size.Z * 2f }, V4Colors.Blue, false); visual.worldZ.IsVisible = false; }
internal void DrawWrappedOnWordText(int renderQueue, Vector2 pos, float scale, string text, Color color, float depth, Vector2 size) { float dx = (float)Math.Floor(pos.X); float dy = (float)Math.Floor(pos.Y); var currentSize = Vector2.Zero; var current = 0; while (current != -1 && current < text.Length) { var start = current; current = FindWordIndexFromBounds(current, size.X, text, out currentSize); if (current > 0) { for (int i = start; i < current; i++) { var c = text[i]; FontChar fc; if (_characterMap.TryGetValue(c, out fc)) { var sourceRectangle = AxisAlignedBox.FromRect(fc.X, fc.Y, fc.Width, fc.Height); var destRectangle = AxisAlignedBox.FromRect(dx + fc.XOffset * scale, dy + fc.YOffset * scale, fc.Width * scale, fc.Height * scale); //var position = new Vector2(dx + fc.XOffset, dy + fc.YOffset); Root.instance.graphics.Draw(renderQueue, _material, destRectangle, sourceRectangle, color, 0f, new Vector2(0f, 0f), SpriteEffects.None, depth); //spriteBatch.Draw(_texture, position, sourceRectangle, Color.White); dx += fc.XAdvance * scale; } } dx = (float)Math.Floor(pos.X); dy += MaxLineHeight; } size.Y += currentSize.Y; } }
/// <summary> /// Returns the appropriate indexes for the child of this octree into which the box will fit. ///@remarks /// This is used by the OCtreeSceneManager to determine which child to traverse next when ///finding the appropriate octree to insert the box. Since it is a loose octree, only the ///center of the box is checked to determine the octant. /// </summary> public void GetChildIndexes(AxisAlignedBox aabox, out int x, out int y, out int z) { Vector3 max = this.box.Maximum; Vector3 min = aabox.Minimum; Vector3 Center = this.box.Maximum.MidPoint(this.box.Minimum); Vector3 CheckCenter = aabox.Maximum.MidPoint(aabox.Minimum); if (CheckCenter.x > Center.x) { x = 1; } else { x = 0; } if (CheckCenter.y > Center.y) { y = 1; } else { y = 0; } if (CheckCenter.z > Center.z) { z = 1; } else { z = 0; } }
public void DrawAABB(AxisAlignedBox aabb, Matrix tranform, Color color) { Vector3 m_Position = new Vector3(tranform.M41, tranform.M42, tranform.M43); Vector3 fld = Multiply(new Vector3(aabb.Min.X, aabb.Min.Y, aabb.Min.Z), tranform) + m_Position; Vector3 brt = Multiply(new Vector3(aabb.Max.X, aabb.Max.Y, aabb.Max.Z), tranform) + m_Position; Vector3 bld = Multiply(new Vector3(aabb.Min.X, aabb.Min.Y, aabb.Max.Z), tranform) + m_Position; Vector3 frt = Multiply(new Vector3(aabb.Max.X, aabb.Max.Y, aabb.Min.Z), tranform) + m_Position; Vector3 frd = Multiply(new Vector3(aabb.Max.X, aabb.Min.Y, aabb.Min.Z), tranform) + m_Position; Vector3 brb = Multiply(new Vector3(aabb.Max.X, aabb.Min.Y, aabb.Max.Z), tranform) + m_Position; Vector3 blt = Multiply(new Vector3(aabb.Min.X, aabb.Max.Y, aabb.Max.Z), tranform) + m_Position; Vector3 flt = Multiply(new Vector3(aabb.Min.X, aabb.Max.Y, aabb.Min.Z), tranform) + m_Position; #region Program.WorldToScreen if (!Program.WorldToScreen(fld, out fld) || !Program.WorldToScreen(brt, out brt) || !Program.WorldToScreen(bld, out bld) || !Program.WorldToScreen(frt, out frt) || !Program.WorldToScreen(frd, out frd) || !Program.WorldToScreen(brb, out brb) || !Program.WorldToScreen(blt, out blt) || !Program.WorldToScreen(flt, out flt)) { return; } #endregion #region DrawLines DrawLine(fld, flt, color); DrawLine(flt, frt, color); DrawLine(frt, frd, color); DrawLine(frd, fld, color); DrawLine(bld, blt, color); DrawLine(blt, brt, color); DrawLine(brt, brb, color); DrawLine(brb, bld, color); DrawLine(fld, bld, color); DrawLine(frd, brb, color); DrawLine(flt, blt, color); DrawLine(frt, brt, color); #endregion }
static void Import(string file, out IEnumerable <IFileGeometry3D> meshes, out FileInfo material, out AxisAlignedBox box) { box = AxisAlignedBox.Zero; material = null; var f = new FileInfo(file); switch (f.Extension.ToLower()) { case ".stl": meshes = G3Readers.ReadStl(f); box = AxisAlignedBox.CreateFrom(meshes.First().Positions); break; case ".obj": var parser = new Utf8ByteOBJParser(); using (var reader = new FileFormats.MemoryMappedFileReader(f)) { parser.Read(reader.ReadSpan()); } try { material = parser.HasMTL ? new FileInfo(parser.GetMaterialFilePath(f.Directory, f.Directory)) : null; } catch { } //var builder = new UnitedGroupsBulder(parser.GeometryCache); var builder = new GroupGeoBuilder(parser.GeometryCache); meshes = builder.Build(); box = AxisAlignedBox.CreateFrom(parser.GeometryCache.PositionsCache.AsReadOnly()); break; default: throw new NotSupportedException($"'{f.Extension}' is not suppported format."); } }
internal void DrawText(int renderQueue, Vector2 pos, float scale, string text, Color color, float depth, float?width) { float dx = (float)Math.Floor(pos.X); float dy = (float)Math.Floor(pos.Y); foreach (char c in text) { FontChar fc; if (_characterMap.TryGetValue(c, out fc)) { if (width.HasValue && dx + fc.XAdvance * scale > width.Value + pos.X) { break; } var sourceRectangle = AxisAlignedBox.FromRect(fc.X, fc.Y, fc.Width, fc.Height); var destRectangle = AxisAlignedBox.FromRect(dx + fc.XOffset * scale, dy + fc.YOffset * scale, fc.Width * scale, fc.Height * scale); //var position = new Vector2(dx + fc.XOffset, dy + fc.YOffset); Root.instance.graphics.Draw(renderQueue, _material, destRectangle, sourceRectangle, color, 0f, new Vector2(0f, 0f), SpriteEffects.None, depth); //spriteBatch.Draw(_texture, position, sourceRectangle, Color.White); dx += fc.XAdvance * scale; } } }
/** It's assumed the the given box has already been proven to fit into * a child. Since it's a loose octree, only the centers need to be * compared to find the appropriate node. */ public void _getChildIndexes(AxisAlignedBox box, ref int x, ref int y, ref int z) { Vector3 max = Box.Maximum; Vector3 min = Box.Minimum; Vector3 center = Box.Maximum.MidPoint(Box.Minimum); Vector3 ncenter = Box.Maximum.MidPoint(Box.Minimum); if (ncenter.x > center.x) { x = 1; } else { x = 0; } if (ncenter.y > center.y) { y = 1; } else { y = 0; } if (ncenter.z > center.z) { z = 1; } else { z = 0; } }
public TerrainZoneRenderable GetTerrainZoneTile(Vector3 pt) { /* Since we don't know if the terrain is square, or has holes, we use a line trace * to find the containing tile... */ TerrainZoneRenderable tile = this.tiles[0][0]; while (null != tile) { AxisAlignedBox b = tile.BoundingBox; if (pt.x < b.Minimum.x) { tile = tile.GetNeighbor(Neighbor.WEST); } else if (pt.x > b.Maximum.x) { tile = tile.GetNeighbor(Neighbor.EAST); } else if (pt.z < b.Minimum.z) { tile = tile.GetNeighbor(Neighbor.NORTH); } else if (pt.z > b.Maximum.z) { tile = tile.GetNeighbor(Neighbor.SOUTH); } else { return(tile); } } return(null); }
public override bool SetOption(string key, object value) { if (key == "Size") { Resize((AxisAlignedBox)value); return(true); } if (key == "Depth") { this.maxDepth = (int)value; // copy the box since resize will delete mOctree and reference won't work AxisAlignedBox box = this.rootOctree.Box; Resize(box); return(true); } /* else if ( key == "ShowOctree" ) * { * mShowBoxes = * static_cast < const bool * > ( val ); * return true; * }*/ return(false); }
/// <summary> /// /// </summary> /// <param name="mgr"></param> /// <param name="rootNode"></param> public BatchedGeometry(SceneManager mgr, SceneNode rootNode) : this("BatchedGeom" + name++.ToString()) { mWithinFarDistance = false; mMinDistanceSquared = 0; mSceneNode = null; mSceneMgr = mgr; mBuild = false; mBounds = new AxisAlignedBox(new Vector3(0, 0, 0), new Vector3(0, 0, 0)); mBoundsUndefinded = true; mParentSceneNode = rootNode; Clear(); }
public bool Intersect(AxisAlignedBox box) { Vector3D v1 = box.Position; Vector3D v2 = box.Position + box.Size; Vector3D v3 = Position; Vector3D v4 = Position + Size; return ((v4.X >= v1.X) && (v3.X <= v2.X) && // x-axis overlap (v4.Y >= v1.Y) && (v3.Y <= v2.Y) && // y-axis overlap (v4.Z >= v1.Z) && (v3.Z <= v2.Z)); // z-axis overlap }
/// Builds an AABB from a list of points public static AxisAlignedBox AABBfromPoints(List<Vector3> points) { AxisAlignedBox aabb = new AxisAlignedBox(); if (points.Count == 0) return aabb; aabb.SetMinimum(points[0]); aabb.SetMaximum(points[0]); //for (List< Vector3>.Enumerator it = points.GetEnumerator(); it.MoveNext(); ++it.) foreach (var it in points) { aabb.SetMinimum(min(aabb.Minimum, it)); aabb.SetMaximum(max(aabb.Maximum, it)); } return aabb; }
// create a 2D hud element: pos = [-1;1] & size = (pixels) public static MovableObject MakeHud(SceneManager mgr, Viewport vp, String materialName, Vector2 pos, Vector2 size) { // Create a manual object for 2D ManualObject manual = mgr.CreateManualObject(); // Use identity view/projection matrices manual.UseIdentityProjection = true; manual.UseIdentityView = true; // convert from pixels to screen coords float s = size.x / vp.ActualWidth; float t = size.y / vp.ActualHeight; manual.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_STRIP); manual.Position(pos.x - s, pos.y - t, 0.0f); manual.TextureCoord(0, 1); manual.Position(pos.x + s, pos.y - t, 0.0f); manual.TextureCoord(1, 1); manual.Position(pos.x + s, pos.y + t, 0.0f); manual.TextureCoord(1, 0); manual.Position(pos.x - s, pos.y + t, 0.0f); manual.TextureCoord(0, 0); manual.Index(0); manual.Index(1); manual.Index(2); manual.Index(3); manual.Index(0); manual.End(); // Use infinite AAB to always stay visible AxisAlignedBox aabInf = new AxisAlignedBox(); aabInf.SetInfinite(); manual.BoundingBox = aabInf; // Render just before overlays manual.RenderQueueGroup = (byte)(RenderQueueGroupID.RENDER_QUEUE_OVERLAY-1); manual.CastShadows = false; // Attach to scene mgr.RootSceneNode.CreateChildSceneNode().AttachObject(manual); return manual; }
private void Create() { if (!isCreated) { this.box = new AxisAlignedBox(Vector3.ZERO, Vector3.ZERO); foreach (ResizableBox resizableBox in this.resizableBoxes) resizableBox.Create(box); UpdateWireBox(); this.isCreated = true; } }
private void Destroy() { if (isCreated) { this.box = null; foreach (ResizableBox resizableBox in this.resizableBoxes) resizableBox.Destroy(); if (this.wireBox != null) { Engine.Graphics.SceneManager.DestroyManualObject(this.wireBox); this.wireBox = null; } this.isCreated = false; } }
public virtual void initialize(EditorDoc parent) { mParent = parent; Vector3F v = new Vector3F(mWidth / 2.0f, mLength / 2.0f, mHeight / 2.0f); mAABB = new AxisAlignedBox(mOrigin - v, mOrigin + v); }
/// <summary> /// /// </summary> /// <param name="group"></param> /// <param name="entity"></param> protected ImpostorTexture(ImpostorPage group, Entity entity) { //Store scene manager and entity mSceneMgr = group.SceneManager; mEntity = entity; //Add self to list of ImpostorTexture's mEntityKey = ImpostorBatch.GenerateEntityKey(entity); mSelfList.Add(mEntityKey, this); //Calculate the entity's bounding box and it's diameter mBoundingBox = entity.BoundingBox; //Note - this radius calculation assumes the object is somewhat rounded (like trees/rocks/etc.) float tmp = 0; mEntityRadius = mBoundingBox.Maximum.x - mBoundingBox.Center.x; tmp = mBoundingBox.Maximum.y - mBoundingBox.Center.y; if (tmp > mEntityRadius) mEntityRadius = tmp; tmp = mBoundingBox.Maximum.z - mBoundingBox.Center.z; if (tmp > mEntityRadius) mEntityRadius = tmp; mEntityDiameter = 2.0f * mEntityRadius; mEntityCenter = mBoundingBox.Center; //Render impostor textures RenderTextures(false); //Set up materials for (int o = 0; o < ImpostorYawAngles; o++) { for (int i = 0; i < ImpostorPitchAngles; i++) { mMaterial[i, o] = (Material)MaterialManager.Instance.Create(GetUniqueID("ImpostorMaterial"), "Impostors"); Material m = mMaterial[i, o]; Pass p = m.GetTechnique(0).GetPass(0); TextureUnitState t = p.CreateTextureUnitState(mTexture.Name); t.TextureScrollU = (float)(o / ImpostorYawAngles); t.TextureScrollV = (float)(i / ImpostorPitchAngles); p.LightingEnabled = false; m.ReceiveShadows = false; if (group.BlendMode == ImpostorBlendMode.AlphaReject) { p.AlphaRejectFunction = CompareFunction.GreaterEqual; p.AlphaRejectValue = 128; } else if (group.BlendMode == ImpostorBlendMode.AlphaBlend) { p.SetSceneBlending(SceneBlendFactor.SourceAlpha, SceneBlendFactor.OneMinusSourceAlpha); } } } }
private void Update() { if (this.isCreated) { // recreate the box this.box = new AxisAlignedBox(this.min, this.max); // update the resizable boxes foreach (ResizableBox resizableBox in this.resizableBoxes) resizableBox.Update(box); // redraw the perspective view box this.UpdateWireBox(); // update the selected block if (this.selectedObject != null) this.selectedObject.BoundingBox = this.box; } }
/// <summary> /// /// </summary> public void Build() { if (mRenderMethod == BillboardMethod.Accelerated) { Clear(); //If there are no billboards to create, exit if (mBillboardBuffer.Count == 0) return; //Create manual mesh to store billboard quads mMesh = MeshManager.Instance.CreateManual(GetUniqueID("SBSMesh"), ResourceGroupManager.DefaultResourceGroupName, null); mSubMesh = mMesh.CreateSubMesh(); mSubMesh.useSharedVertices = false; //Setup vertex format information mSubMesh.vertexData = new VertexData(); mSubMesh.vertexData.vertexStart = 0; mSubMesh.vertexData.vertexCount = 4 * mBillboardBuffer.Count; VertexDeclaration dcl = mSubMesh.vertexData.vertexDeclaration; int offset = 0; dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Diffuse); offset += VertexElement.GetTypeSize(VertexElementType.Color); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.TexCoords); offset += VertexElement.GetTypeSize(VertexElementType.Float2); //Populate a new vertex buffer HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( /*offset*/dcl, mSubMesh.vertexData.vertexCount, BufferUsage.StaticWriteOnly, false); unsafe { float* pReal = (float*)vbuf.Lock(BufferLocking.Discard); float minX = float.PositiveInfinity; float maxX = float.NegativeInfinity; float minY = float.PositiveInfinity; float maxY = float.NegativeInfinity; float minZ = float.PositiveInfinity; float maxZ = float.NegativeInfinity; foreach (StaticBillboard it in mBillboardBuffer) { StaticBillboard bb = it; float halfXScale = bb.XScale * 0.5f; float halfYScale = bb.YScale * 0.5f; // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 0.0f; // color *((uint*)pReal++) = bb.Color; // uv *pReal++ = (float)(bb.TextCoordIndexU * mUFactor); *pReal++ = (float)(bb.TextCoordIndexV * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 1.0f; // color *((uint*)pReal++) = bb.Color; // uv *pReal++ = (float)((bb.TextCoordIndexU + 1)* mUFactor); *pReal++ = (float)(bb.TextCoordIndexV * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 2.0f; // color *((uint*)pReal++) = bb.Color; // uv *pReal++ = (float)(bb.TextCoordIndexU * mUFactor); *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 3.0f; // color *((uint*)pReal++) = bb.Color; // uv *pReal++ = (float)((bb.TextCoordIndexU + 1) * mUFactor); *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor); //Update bounding box if (bb.Position.x - halfXScale < minX) minX = bb.Position.x - halfXScale; if (bb.Position.x + halfXScale > maxX) maxX = bb.Position.x + halfXScale; if (bb.Position.y - halfYScale < minY) minY = bb.Position.y - halfYScale; if (bb.Position.y + halfYScale > maxY) maxY = bb.Position.y + halfYScale; if (bb.Position.z - halfXScale < minZ) minZ = bb.Position.z - halfXScale; if (bb.Position.z + halfXScale > maxZ) maxZ = bb.Position.z + halfXScale; } AxisAlignedBox bounds = new AxisAlignedBox( new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)); vbuf.Unlock(); mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf); //Populate index buffer mSubMesh.indexData.indexStart = 0; mSubMesh.indexData.indexCount = 6 * mBillboardBuffer.Count; mSubMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, mSubMesh.indexData.indexCount, BufferUsage.StaticWriteOnly); ushort* pI = (ushort*)mSubMesh.indexData.indexBuffer.Lock(BufferLocking.Discard); for (ushort i = 0; i < mBillboardBuffer.Count; i++) { ushort ofset = (ushort)(i * 4); *pI++ = (ushort)(0 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(3 + ofset); } mSubMesh.indexData.indexBuffer.Unlock(); //Finish up mesh mMesh.BoundingBox = bounds; Vector3 tmp = bounds.Maximum - bounds.Minimum; mMesh.BoundingSphereRadius = tmp.Length * 0.5f; LoggingLevel lvl = LogManager.Instance.LogDetail; LogManager.Instance.LogDetail = LoggingLevel.Low; mMesh.Load(); LogManager.Instance.LogDetail = lvl; //Empty the billboardBuffer now, because all billboards have been built mBillboardBuffer.Clear(); //Create an entity for the mesh mEntity = mSceneMgr.CreateEntity(mEntityName, mMesh.Name); mEntity.CastShadows = false; //Apply texture if (mFadeEnabled) { Debug.Assert(mFadeMaterial != null); mEntity.MaterialName = mFadeMaterial.Name; } else { Debug.Assert(mMaterial != null); mEntity.MaterialName = mMaterial.Name; } //Add to scene mNode.AttachObject(mEntity); mEntity.IsVisible = mVisible; } } }
public void Update(AxisAlignedBox box) { SetupBox(box); Draw(true); }
/// <summary> /// /// </summary> public virtual void ClearBoundingBox() { mTrueBounds = new AxisAlignedBox(new Vector3(0, 0, 0), new Vector3(0, 0, 0)); mTrueBoundsUndefined = true; }
/// <summary> /// /// </summary> /// <param name="page"></param> /// <param name="layer"></param> /// <param name="grassPostions"></param> /// <param name="grassCount"></param> /// <returns></returns> private Mesh GenerateGrassSprite(PageInfo page, GrassLayer layer, IntPtr grassPostions, int grassCount) { //Calculate the number of quads to be added int quadCount = grassCount; //Create manual mesh to store grass quads Mesh mesh = (Mesh)MeshManager.Instance.CreateManual(GetUniqueID(), ResourceGroupManager.DefaultResourceGroupName, null); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.useSharedVertices = false; //Setup vertex format information subMesh.vertexData = new VertexData(); subMesh.vertexData.vertexStart = 0; subMesh.vertexData.vertexCount = 4 * quadCount; VertexDeclaration dcl = subMesh.vertexData.vertexDeclaration; int offset = 0; dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Float4, VertexElementSemantic.Normal); offset += VertexElement.GetTypeSize(VertexElementType.Float4); dcl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse); offset += VertexElement.GetTypeSize(VertexElementType.Color); dcl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords); offset += VertexElement.GetTypeSize(VertexElementType.Float2); //Populate a new vertex buffer with grass HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( /*offset*/dcl, subMesh.vertexData.vertexCount, BufferUsage.DynamicWriteOnly, false); unsafe { float* pReal = (float*)vbuf.Lock(BufferLocking.Discard); //Calculate size variance float rndWidth = layer.mMaxWidth - layer.mMinWidth; float rndHeight = layer.mMaxHeight - layer.mMinHeight; float minY = float.PositiveInfinity, maxY = float.NegativeInfinity; float* posPtr = (float*)grassPostions; //Position array "iterator" for (int i = 0; i < grassCount; i++) { //Get the x and z positions from the position array float x = *posPtr++; float z = *posPtr++; //Calculate height float y = 0; if (mHeightFunction != null) { y = mHeightFunction.GetHeightAt(x, z, mHeightFunctionUserData); } else { y = 0; } float x1 = (x - page.CenterPoint.x); float z1 = (z - page.CenterPoint.z); //Get the color at the grass position uint color = 0; if (layer.ColorMap != null) color = layer.ColorMap.GetColorAt(x, z); else color = 0xFFFFFFFF; //Calculate size float rnd = MogreLibMath.Utility.UnitRandom();//The same rnd value is used for width and height to maintain aspect ratio float halfXScale = (layer.mMinWidth + rndWidth * rnd) * 0.5f; float scaleY = (layer.mMinWidth + rndHeight * rnd); //Randomly mirror grass textures float uvLeft, uvRight; if (MogreLibMath.Utility.UnitRandom() > 0.5f) { uvLeft = 0; uvRight = 1; } else { uvLeft = 1; uvRight = 0; } //Add vertices *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 1; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 1; //uv //Update bounds if (y < minY) minY = y; if (y + scaleY > maxY) maxY = y + scaleY; } vbuf.Unlock(); subMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf); //Populate index buffer subMesh.indexData.indexStart = 0; subMesh.indexData.indexCount = 6 * quadCount; subMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, subMesh.indexData.indexCount, BufferUsage.DynamicWriteOnly); ushort* pI = (ushort*)subMesh.indexData.indexBuffer.Lock(BufferLocking.Discard); for (ushort i = 0; i < quadCount; i++) { ushort ofset = (ushort)(i * 4); *pI++ = (ushort)(0 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(3 + ofset); } subMesh.indexData.indexBuffer.Unlock(); //Finish up mesh AxisAlignedBox bounds = new AxisAlignedBox( new Vector3(page.Bounds.Left - page.CenterPoint.x, minY, page.Bounds.Top - page.CenterPoint.z), new Vector3(page.Bounds.Right - page.CenterPoint.x, maxY, page.Bounds.Bottom - page.CenterPoint.z)); mesh.BoundingBox = bounds; Vector3 tmp = bounds.Maximum - bounds.Minimum; mesh.BoundingSphereRadius = tmp.Length * 0.5f; mesh.Load(); //Apply grass material to mesh subMesh.MaterialName = layer.Material.Name; //Return the mesh return mesh; } }
/// <summary> /// /// </summary> /// <param name="page"></param> /// <param name="layer"></param> /// <param name="grassPostions"></param> /// <param name="grassCount"></param> /// <returns></returns> private Mesh GenerateGrassCrossQuads(PageInfo page, GrassLayer layer, IntPtr grassPostions, int grassCount) { //Calculate the number of quads to be added int quadCount = grassCount * 2; //Create manual mesh to store grass quads Mesh mesh = (Mesh)MeshManager.Instance.CreateManual(GetUniqueID(), ResourceGroupManager.DefaultResourceGroupName, null); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.useSharedVertices = false; //Setup vertex format information subMesh.vertexData = new VertexData(); subMesh.vertexData.vertexStart = 0; subMesh.vertexData.vertexCount = 4 * quadCount; VertexDeclaration dcl = subMesh.vertexData.vertexDeclaration; int offset = 0; dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse); offset += VertexElement.GetTypeSize(VertexElementType.Color); dcl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords); offset += VertexElement.GetTypeSize(VertexElementType.Float2); //Populate a new vertex buffer with grass HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( /*offset*/dcl, subMesh.vertexData.vertexCount, BufferUsage.DynamicWriteOnly, false); unsafe { float* pReal = (float*)vbuf.Lock(BufferLocking.Discard); //Calculate size variance float rndWidth = layer.mMaxWidth - layer.mMinWidth; float rndHeight = layer.mMaxHeight - layer.mMinHeight; float minY = float.PositiveInfinity, maxY = float.NegativeInfinity; float* posPtr = (float*)grassPostions; //Position array "iterator" for (int i = 0; i < grassCount; i++) { //Get the x and z positions from the position array float x = *posPtr++; float z = *posPtr++; //Get the color at the grass position uint color = 0; if (layer.ColorMap != null) color = layer.ColorMap.GetColorAt(x, z); else color = 0xFFFFFFFF; //Calculate size float rnd = MogreLibMath.Utility.UnitRandom();//The same rnd value is used for width and height to maintain aspect ratio float halfXScale = (layer.mMinWidth + rndWidth * rnd) * 0.5f; float scaleY = (layer.mMinWidth + rndHeight * rnd); //Calculate rotation float angle = MogreLibMath.Utility.RangeRandom(0, MogreLibMath.Utility.TWO_PI); float xTrans = MogreLibMath.Utility.Cos(angle) * halfXScale; float zTrans = MogreLibMath.Utility.Sin(angle) * halfXScale; //Calculate heights and edge positions float x1 = x - xTrans, z1 = z - zTrans; float x2 = x + xTrans, z2 = z + zTrans; float y1, y2; if (mHeightFunction != null) { y1 = mHeightFunction.GetHeightAt(x1, z1, mHeightFunctionUserData); y2 = mHeightFunction.GetHeightAt(x2, z2, mHeightFunctionUserData); } else { y1 = 0; y2 = 0; } //Add vertices *pReal++ = (x1 - page.CenterPoint.x); *pReal++ = (y1 + scaleY); *pReal++ = (z1 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 0; *pReal++ = 0; //uv *pReal++ = (x2 - page.CenterPoint.x); *pReal++ = (y2 + scaleY); *pReal++ = (z2 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 1; *pReal++ = 0; //uv *pReal++ = (x1 - page.CenterPoint.x); *pReal++ = (y1); *pReal++ = (z1 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 0; *pReal++ = 1; //uv *pReal++ = (x2 - page.CenterPoint.x); *pReal++ = (y2); *pReal++ = (z2 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 1; *pReal++ = 1; //uv //Update bounds if (y1 < minY) minY = y1; if (y2 < minY) minY = y2; if (y1 + scaleY > maxY) maxY = y1 + scaleY; if (y2 + scaleY > maxY) maxY = y2 + scaleY; //Calculate heights and edge positions float x3 = x + zTrans, z3 = z - xTrans; float x4 = x - zTrans, z4 = z + xTrans; float y3, y4; if (mHeightFunction != null) { y3 = mHeightFunction.GetHeightAt(x3, z3, mHeightFunctionUserData); y4 = mHeightFunction.GetHeightAt(x4, z4, mHeightFunctionUserData); } else { y3 = 0; y4 = 0; } //Add vertices *pReal++ = (x3 - page.CenterPoint.x); *pReal++ = (y3 + scaleY); *pReal++ = (z3 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 0; *pReal++ = 0; //uv *pReal++ = (x4 - page.CenterPoint.x); *pReal++ = (y4 + scaleY); *pReal++ = (z4 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 1; *pReal++ = 0; //uv *pReal++ = (x3 - page.CenterPoint.x); *pReal++ = (y3); *pReal++ = (z3 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 0; *pReal++ = 1; //uv *pReal++ = (x4 - page.CenterPoint.x); *pReal++ = (y4); *pReal++ = (z4 - page.CenterPoint.z); //pos *((uint*)pReal++) = color; //color *pReal++ = 1; *pReal++ = 1; //uv //Update bounds if (y3 < minY) minY = y1; if (y4 < minY) minY = y2; if (y3 + scaleY > maxY) maxY = y3 + scaleY; if (y4 + scaleY > maxY) maxY = y4 + scaleY; } vbuf.Unlock(); subMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf); //Populate index buffer subMesh.indexData.indexStart = 0; subMesh.indexData.indexCount = 6 * quadCount; subMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, subMesh.indexData.indexCount, BufferUsage.DynamicWriteOnly); ushort* pI = (ushort*)subMesh.indexData.indexBuffer.Lock(BufferLocking.Discard); for (ushort i = 0; i < quadCount; i++) { ushort ofset = (ushort)(i * 4); *pI++ = (ushort)(0 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(3 + ofset); } subMesh.indexData.indexBuffer.Unlock(); //Finish up mesh AxisAlignedBox bounds = new AxisAlignedBox( new Vector3(page.Bounds.Left - page.CenterPoint.x, minY, page.Bounds.Top - page.CenterPoint.z), new Vector3(page.Bounds.Right - page.CenterPoint.x, maxY, page.Bounds.Bottom - page.CenterPoint.z)); mesh.BoundingBox = bounds; Vector3 tmp = bounds.Maximum - bounds.Minimum; mesh.BoundingSphereRadius = tmp.Length * 0.5f; mesh.Load(); //Apply grass material to mesh subMesh.MaterialName = layer.Material.Name; //Return the mesh return mesh; } }
protected override void onInit() { inited = true; _shape = new Shape(AxisAlignedBox.FromDimensions(_offset, _size)); }
private void SetupBox(AxisAlignedBox box) { Vector3 min = Editor.MinOf(box.Minimum, box.Maximum); Vector3 max = Editor.MaxOf(box.Minimum, box.Maximum); this.box = new AxisAlignedBox(min, max); }