static void Traverse(Entity e, Dictionary <Guid, EntityDesign> d) { d.Add(e.Id, new EntityDesign(e)); foreach (var child in e.GetChildren()) { Traverse(child, d); } }
public static Entity FindSubEntity(this Entity entity, Guid subEntityId) { if (entity.Id == subEntityId) { return(entity); } return(entity.GetChildren().DepthFirst(x => x.GetChildren()).FirstOrDefault(x => x.Id == subEntityId)); }
protected override Data GenerateComponentData([NotNull] Entity entity, [NotNull] CharacterMovementComponent component) { return(new Data { Character = entity.Get <CharacterComponent>(), ModelEntityTransform = entity.GetChildren() .First(e => e.Name == "CharacterModel").Get <TransformComponent>(), }); }
private static void ValidateActorEntity(Entity actorEntity) { Assert.True(actorEntity.Has <AttributesComponent>()); Assert.Equal(5, actorEntity.Get <AttributesComponent>().Strength); Assert.Equal(7, actorEntity.Get <AttributesComponent>().Agility); var childEntities = actorEntity.GetChildren().ToArray(); Assert.Equal(2, childEntities.Length); foreach (var childEntity in actorEntity.GetChildren()) { Assert.True(childEntity.Has <WeightComponent>()); Assert.True(childEntity.Has <HealthComponent>()); Assert.True(childEntity.Has <DirtComponent>()); Assert.Equal(0.0, childEntity.Get <DirtComponent>().Value); Assert.Equal(10.0, childEntity.Get <WeightComponent>().Value); Assert.Equal(100.0, childEntity.Get <HealthComponent>().Value); } }
private void CollectComponentIds(Entity entity) { foreach (var component in entity.Components) { componentsIds.Add(RuntimeIdHelper.ToRuntimeId(component)); } foreach (var child in entity.GetChildren()) { CollectComponentIds(child); } }
/// <summary> /// Goes through the entity and children and adds/removes bepu physics objects to the simulation. Only will add/remove if AllowHelperToManage is true (which is set to true by default) /// and if the body isn't added already. /// </summary> /// <param name="rootEntity"></param> public static void SetBodiesInSimulation(Entity rootEntity, bool add = true) { foreach (BepuPhysicsComponent pc in rootEntity.GetAll <BepuPhysicsComponent>()) { if (pc.AutomaticAdd) { pc.AddedToScene = add; } } foreach (Entity e in rootEntity.GetChildren()) { SetBodiesInSimulation(e, add); } }
/// <summary> /// Performs a breadth first search of the entities children for a component of the specified type. /// </summary> /// <typeparam name="T">The type of component.</typeparam> /// <param name="entity">The entity.</param> /// <param name="includeDisabled">Should search include <see cref="ActivableEntityComponent"/> where <see cref="ActivableEntityComponent.Enabled"/> is <c>false</c>.</param> /// <returns>The component or null if does no exist.</returns> /// <exception cref="ArgumentNullException">The entity was <c>null</c>.</exception> public static T GetComponentInChildren <T>(this Entity entity, bool includeDisabled = false) where T : ActivableEntityComponent { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } //breadth first var queue = new Queue <Entity>(); queue.EnqueueRange(entity.GetChildren()); return(GetComponentInChildrenCore <T>(includeDisabled, queue)); }
public void SetAsChildOf_Should_set_created_entity_as_child() { using EntityCommandRecorder recorder = new EntityCommandRecorder(1024); using World world = new World(); Entity parent = world.CreateEntity(); EntityRecord record = recorder.CreateEntity(); record.SetAsChildOf(recorder.Record(parent)); recorder.Execute(world); Check.That(parent.GetChildren()).Contains(world.Skip(1).Single()); }
/// <summary> /// Performs a breadth first search of the entities children for a component of the specified type. /// </summary> /// <typeparam name="T">The type of component.</typeparam> /// <param name="entity">The entity.</param> /// <returns>The component or null if does no exist.</returns> /// <exception cref="ArgumentNullException">The entity was <c>null</c>.</exception> public static T GetComponentInChildren <T>(this Entity entity) where T : EntityComponent { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } //breadth first var queue = new Queue <Entity>(); queue.EnqueueRange(entity.GetChildren()); return(GetComponentInChildrenCore <T>(queue)); }
public void SetAsChildOf_Should_set_recorded_entity_as_child() { using (EntityCommandRecorder recorder = new EntityCommandRecorder(1024)) using (World world = new World()) { Entity parent = world.CreateEntity(); Entity entity = world.CreateEntity(); EntityRecord record = recorder.Record(entity); record.SetAsChildOf(recorder.Record(parent)); recorder.Execute(world); Check.That(parent.GetChildren()).Contains(entity); } }
public void SetAsParentOf_Should_set_recorded_entity_as_parent() { using EntityCommandRecorder recorder = new EntityCommandRecorder(1024); using World world = new World(); Entity child = world.CreateEntity(); Entity entity = world.CreateEntity(); EntityRecord record = recorder.Record(entity); record.SetAsParentOf(recorder.Record(child)); recorder.Execute(world); Check.That(entity.GetChildren()).Contains(child); }
public void RemoveFromChildrenOf_Should_set_created_entity_as_child() { using EntityCommandRecorder recorder = new EntityCommandRecorder(1024); using World world = new World(); Entity parent = world.CreateEntity(); EntityRecord parentRecord = recorder.Record(parent); EntityRecord record = recorder.CreateEntity(); record.SetAsChildOf(parentRecord); record.RemoveFromChildrenOf(parentRecord); recorder.Execute(world); Check.That(parent.GetChildren()).IsEmpty(); }
public void RemoveFromParentsOf_Should_set_recorded_entity_as_parent() { using (EntityCommandRecorder recorder = new EntityCommandRecorder(1024)) using (World world = new World()) { Entity child = world.CreateEntity(); Entity entity = world.CreateEntity(); entity.SetAsParentOf(child); EntityRecord record = recorder.Record(entity); record.RemoveFromParentsOf(recorder.Record(child)); recorder.Execute(world); Check.That(entity.GetChildren()).IsEmpty(); } }
private void AdjustChildEntity(Entity entity, ref bool canRotateEntity) { if (entity.Components.Get <ModelComponent>() != null || entity.Components.Get <ParticleSystemComponent>() != null) { canRotateEntity = true; } var particles = entity.Components.Get <ParticleSystemComponent>(); if (particles?.ParticleSystem?.Settings != null && particles?.Control != null) { particles.ParticleSystem.Settings.WarmupTime = particles.Control.ThumbnailWarmupTime; } foreach (var child in entity.GetChildren()) { AdjustChildEntity(child, ref canRotateEntity); } }
//Called at the beginning to update the navigation points public override void Start() { var streets = Entity.GetChildren().ToList(); var navigationPoints = new List <NavigationPoint>(); foreach (var street in streets) { var temp = street.GetChildren().ToList(); navigationPoints.AddRange(temp.Select(t => new NavigationPoint { Id = t.Id, XPosition = t.Transform.Position.X, YPosition = t.Transform.Position.Y, ZPosition = t.Transform.Position.Z })); } NavigationLogic.UpdateNavigation(navigationPoints); }
/// <summary> /// Recursively approximate the bounding box of the scene represented by the entity. /// </summary> /// <param name="rootEntity">The root entity of the scene</param> /// <returns>The bounding box</returns> public static BoundingSphere CalculateBoundingSpere(Entity rootEntity) { var boundingSphere = new BoundingSphere(); var model = rootEntity.Get <ModelComponent>(); if (model != null && model.Model != null) { var boundingBox = model.Model.BoundingBox; var objectHalfSize = (boundingBox.Maximum - boundingBox.Minimum) / 2f; var scaledHalfSize = objectHalfSize * rootEntity.Transform.Scale; var sphereRadius = Math.Max(scaledHalfSize.X, Math.Max(scaledHalfSize.Y, scaledHalfSize.Z)); var sphereCenter = (boundingBox.Maximum + boundingBox.Minimum) / 2f + rootEntity.Transform.Position; boundingSphere = new BoundingSphere(sphereCenter, sphereRadius); } rootEntity.Transform.UpdateLocalMatrix(); foreach (var child in rootEntity.GetChildren()) { var childSphere = CalculateBoundingSpere(child); if (Math.Abs(childSphere.Radius) < MathUtil.ZeroTolerance) { continue; } var centerInParent = Vector3.TransformCoordinate(childSphere.Center, rootEntity.Transform.LocalMatrix); var radiusInParent = Vector3.TransformNormal(new Vector3(childSphere.Radius, 0, 0), rootEntity.Transform.LocalMatrix).Length(); var sphereInParent = new BoundingSphere(centerInParent, radiusInParent); if (Math.Abs(boundingSphere.Radius) < MathUtil.ZeroTolerance) { boundingSphere = sphereInParent; } else { boundingSphere = BoundingSphere.Merge(boundingSphere, sphereInParent); } } return(boundingSphere); }
private void RecursiveToggle(Entity entity, bool enabled) { var model = entity.Get <ModelComponent>(); if (model != null) { model.Enabled = enabled; } var collider = entity.Get <StaticColliderComponent>(); if (collider != null) { collider.Enabled = enabled; } foreach (var c in entity.GetChildren()) { RecursiveToggle(c, enabled); } }
/// <summary> /// Invalidates the cached identifiers of all the <see cref="EntityComponent"/>s of the specified <see cref="Entity"/>. /// </summary> /// <param name="entity">The entity for which to invalidate the cached identifiers of its components.</param> /// <param name="isRecursive">A value indicating whether to also invalidate the cached identifiers of the components of child entities, recursively.</param> public void UncacheEntity([NotNull] Entity entity, bool isRecursive) { if (entity is null) { throw new ArgumentNullException(nameof(entity)); } foreach (var component in entity.Components) { idToEntity.Remove(RuntimeIdHelper.ToRuntimeId(component)); } if (isRecursive) { foreach (var component in entity.GetChildren().BreadthFirst(x => x.GetChildren()).SelectMany(e => e.Components)) { idToEntity.Remove(RuntimeIdHelper.ToRuntimeId(component)); } } }
/// <summary> /// Cache identifier of all components of the specified <paramref name="entity"/>. /// </summary> /// <param name="entity">The entity which components to cache.</param> /// <param name="isRecursive"><c>true</c> if the components of child entities should also be cached, recursively; otherwise, <c>false</c>.</param> public void CacheEntity([NotNull] Entity entity, bool isRecursive) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } foreach (var component in entity.Components) { idToEntity[RuntimeIdHelper.ToRuntimeId(component)] = component.Entity; } if (!isRecursive) { return; } foreach (var component in entity.GetChildren().BreadthFirst(x => x.GetChildren()).SelectMany(e => e.Components)) { idToEntity[RuntimeIdHelper.ToRuntimeId(component)] = component.Entity; } }
private static GenericStructure WriteEntity(Entity ent) { var ret = new GenericStructure("entity"); ret["id"] = ent.ID.ToString(CultureInfo.InvariantCulture); ret["classname"] = ent.EntityData.Name; WriteEntityData(ret, ent.EntityData); if (!ent.HasChildren) { ret["origin"] = FormatCoordinate(ent.Origin); } var editor = WriteEditor(ent); ret.Children.Add(editor); foreach (var solid in ent.GetChildren().SelectMany(x => x.FindAll()).OfType <Solid>().OrderBy(x => x.ID)) { ret.Children.Add(WriteSolid(solid)); } return(ret); }
public override void Update() { // We store some drawing positions int drawX = 350, drawY = 230, increment = 70; // We print the name of the our entity DebugText.Print(Entity.Name, new Int2(drawX, drawY)); // We loop over all the children of our entity using GetChildren() // NOTE: This does not include any subchildren of those children foreach (var child in Entity.GetChildren()) { // We print the name of the child drawY += increment; DebugText.Print(child.Name, new Int2(drawX + increment, drawY)); // It is possible that this child, also has children. We now loop over these 'subchildren' and print their name too foreach (var subChild in child.GetChildren()) { drawY += increment; DebugText.Print(subChild.Name, new Int2(drawX + (increment * 2), drawY)); } } }
/// <summary> /// Calculate the bounding sphere of the entity's models. /// </summary> /// <param name="entity">The entity to measure</param> /// <param name="isRecursive">Indicate the child entities bounding spheres should be merged</param> /// <param name="meshSelector">Selects which meshes are considered for bounding box calculation.</param> /// <returns>The bounding sphere (world matrix included)</returns> public static BoundingSphere CalculateBoundSphere(this Entity entity, bool isRecursive = true, Func <Model, IEnumerable <Mesh> > meshSelector = null) { entity.Transform.UpdateWorldMatrix(); var worldMatrix = entity.Transform.WorldMatrix; var boundingSphere = BoundingSphere.Empty; // calculate the bounding sphere of the model if any var modelComponent = entity.Get <ModelComponent>(); var hasModel = modelComponent?.Model != null; if (hasModel) { var hierarchy = modelComponent.Skeleton; var nodeTransforms = new Matrix[hierarchy.Nodes.Length]; // Calculate node transforms here, since there might not be a ModelProcessor running for (int i = 0; i < nodeTransforms.Length; i++) { if (hierarchy.Nodes[i].ParentIndex == -1) { nodeTransforms[i] = worldMatrix; } else { Matrix localMatrix; Matrix.Transformation( ref hierarchy.Nodes[i].Transform.Scale, ref hierarchy.Nodes[i].Transform.Rotation, ref hierarchy.Nodes[i].Transform.Position, out localMatrix); Matrix.Multiply(ref localMatrix, ref nodeTransforms[hierarchy.Nodes[i].ParentIndex], out nodeTransforms[i]); } } // calculate the bounding sphere var boundingBox = BoundingBoxExt.Empty; var meshes = modelComponent.Model.Meshes; var filteredMeshes = meshSelector == null ? meshes : meshSelector(modelComponent.Model); // Calculate skinned bounding boxes. // TODO: Cloned from ModelSkinningUpdater. Consolidate. foreach (var mesh in filteredMeshes) { var skinning = mesh.Skinning; if (skinning == null) { // For unskinned meshes, use the original bounding box var boundingBoxExt = (BoundingBoxExt)mesh.BoundingBox; boundingBoxExt.Transform(nodeTransforms[mesh.NodeIndex]); BoundingBoxExt.Merge(ref boundingBox, ref boundingBoxExt, out boundingBox); } else { var bones = skinning.Bones; var bindPoseBoundingBox = new BoundingBoxExt(mesh.BoundingBox); for (var index = 0; index < bones.Length; index++) { var nodeIndex = bones[index].NodeIndex; Matrix boneMatrix; // Compute bone matrix Matrix.Multiply(ref bones[index].LinkToMeshMatrix, ref nodeTransforms[nodeIndex], out boneMatrix); // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ // Compute transformed AABB (by world) var boundingBoxExt = bindPoseBoundingBox; boundingBoxExt.Transform(boneMatrix); BoundingBoxExt.Merge(ref boundingBox, ref boundingBoxExt, out boundingBox); } } } var halfSize = boundingBox.Extent; var maxHalfSize = Math.Max(halfSize.X, Math.Max(halfSize.Y, halfSize.Z)); boundingSphere = BoundingSphere.Merge(boundingSphere, new BoundingSphere(boundingBox.Center, maxHalfSize)); } // Calculate the bounding sphere for the sprite component if any and merge the result var spriteComponent = entity.Get <SpriteComponent>(); var hasSprite = spriteComponent?.CurrentSprite != null; if (hasSprite && !(hasModel && meshSelector != null)) { var spriteSize = spriteComponent.CurrentSprite.Size; var spriteDiagonalSize = (float)Math.Sqrt(spriteSize.X * spriteSize.X + spriteSize.Y * spriteSize.Y); // Note: this is probably wrong, need to unify with SpriteComponentRenderer var center = worldMatrix.TranslationVector; var scales = new Vector3(worldMatrix.Row1.Length(), worldMatrix.Row2.Length(), worldMatrix.Row3.Length()); var maxScale = Math.Max(scales.X, Math.Max(scales.Y, scales.Z)); boundingSphere = BoundingSphere.Merge(boundingSphere, new BoundingSphere(center, maxScale * spriteDiagonalSize / 2f)); } var spriteStudioComponent = entity.Get <SpriteStudioComponent>(); if (spriteStudioComponent != null) { // Make sure nodes are prepared if (!SpriteStudioProcessor.PrepareNodes(spriteStudioComponent)) { return(new BoundingSphere()); } // Update root nodes foreach (var node in spriteStudioComponent.Nodes) { node.UpdateTransformation(); } // Compute bounding sphere for each node foreach (var node in spriteStudioComponent.Nodes.SelectDeep(x => x.ChildrenNodes)) { if (node.Sprite == null || node.Hide != 0) { continue; } var nodeMatrix = node.ModelTransform * worldMatrix; var spriteSize = node.Sprite.Size; var spriteDiagonalSize = (float)Math.Sqrt(spriteSize.X * spriteSize.X + spriteSize.Y * spriteSize.Y); Vector3 pos, scale; nodeMatrix.Decompose(out scale, out pos); var center = pos; var maxScale = Math.Max(scale.X, scale.Y); //2d ignore Z boundingSphere = BoundingSphere.Merge(boundingSphere, new BoundingSphere(center, maxScale * (spriteDiagonalSize / 2f))); } } var particleComponent = entity.Get <ParticleSystemComponent>(); if (particleComponent != null) { var center = worldMatrix.TranslationVector; var sphere = particleComponent.ParticleSystem?.BoundingShape != null?BoundingSphere.FromBox(particleComponent.ParticleSystem.BoundingShape.GetAABB(center, Quaternion.Identity, 1.0f)) : new BoundingSphere(center, 2.0f); boundingSphere = BoundingSphere.Merge(boundingSphere, sphere); } var boundingBoxComponent = entity.Get <NavigationBoundingBoxComponent>(); if (boundingBoxComponent != null) { var center = worldMatrix.TranslationVector; var scales = new Vector3(worldMatrix.Row1.Length(), worldMatrix.Row2.Length(), worldMatrix.Row3.Length()) * boundingBoxComponent.Size; boundingSphere = BoundingSphere.FromBox(new BoundingBox(-scales + center, scales + center)); } // Extend the bounding sphere to include the children if (isRecursive) { foreach (var child in entity.GetChildren()) { boundingSphere = BoundingSphere.Merge(boundingSphere, child.CalculateBoundSphere(true, meshSelector)); } } // If the entity does not contain any components having an impact on the bounding sphere, create an empty bounding sphere centered on the entity position. if (boundingSphere == BoundingSphere.Empty) { boundingSphere = new BoundingSphere(worldMatrix.TranslationVector, 0); } return(boundingSphere); }
private void AddHardpointMarkersToShip(Entity ship) { var shipComponent = ship.GetComponent<ShipComponent>(); const float BaseAlpha = 0.3f; foreach (var hardpointEntity in ship.GetChildren().Where(e=>e.HasComponent<HardpointComponent>())){ var hardpointArc = new HardpointArcDrawingComponent { DrawHardpointIcon = true, Alpha = BaseAlpha }; hardpointEntity.AddComponent(hardpointArc); var entity = World.CreateEntity(); var xform = hardpointEntity.GetComponent<Transform>(); var box = HardpointRendererSystem.GetIconBoundingBox(hardpointEntity.GetComponent<HardpointComponent>().Hardpoint); var newxform = entity.AddComponentFromPool<Transform>(); newxform.Position = xform.Position - box.Size / 2; newxform.Rotation = 0; newxform.Scale = Vector2.One; entity.AddComponent(new BoundingBoxComponent(box)); //entity.AddComponent(new DrawBoundingBoxComponent { Color = Microsoft.Xna.Framework.Color.Red, IsEnabled = true }); var hover = new MouseHoverComponent { UsePositionOnly = true }; hover.HoverChanged += (o, e) => { hardpointArc.Alpha = hover.IsHover ? 1 : BaseAlpha; hardpointArc.Thickness = hover.IsHover ? 2 : 1; if (hover.IsHover) _hoverEntities.Add(hardpointEntity); else _hoverEntities.Remove(hardpointEntity); }; entity.AddComponent(hover); } }
/// <summary> /// Updates the Controllable entity. /// </summary> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { Vector2 direction = _input.LeftDirectional; Vector2 angle = _input.RightDirectional; Weapon weapon = Entity.GetChildren <Weapon>(); //ITEM: 2. Na hora do tiro, permita que o jogador escolha: // 2.1. Inclinação do canhão: Que dá o ângulo da bala; // 2.2. Força: Enquanto pressionar tecla/mouse a força variará de 0 até o máximo do canhão. O jogador não sabe que máximo é esse; // 2.3 Que bala usar (ver abaixo); if ((Entity as Player).Mirrored) { direction.Y *= -1; } if (direction.X != 0f) { (Entity as Player).Mirrored = (direction.X < 0f); Entity.GetBehavior <PhysicsBehavior>().ConstantForces["Accelerator"] = new Vector2(direction.X * 100f, 0f); if (!(Entity as Player).IsFlying) { Entity.Sprite.ChangeAnimation(1); SoundManager.PlaySound("Walk"); } } else { Entity.Sprite.ChangeAnimation(0); Entity.GetBehavior <PhysicsBehavior>().ConstantForces["Accelerator"] = Vector2.Zero; } if (angle.Y != 0f) { if (weapon != null) { weapon.Rotation += (angle.Y / 10f) % 2f; SoundManager.PlaySound("RotateWeapon"); } } if (_input.LeftTrigger > 0.4f && (Entity as Player).Fuel > 0) { (Entity as Player).GetBehavior <PhysicsBehavior>().ConstantForces["Propulsion"] = new Vector2(0f, -200f); (Entity as Player).IsFlying = true; SoundManager.PlaySound("Jetpack"); } else { (Entity as Player).GetBehavior <PhysicsBehavior>().ConstantForces["Propulsion"] = new Vector2(0f, 0f); (Entity as Player).IsFlying = false; } if (_input.RightTrigger > 0.4f) { _ready = true; weapon.ChangeForce(); } else if (_ready) { if (weapon != null) { if (weapon.Shoot()) { (Entity as Player).Level.ChangeState(TurnState.Shooting); SoundManager.PlaySound("Shoot"); } else { SoundManager.PlaySound("NoAmmo"); } } _ready = false; } if (_input.LeftBumper == ButtonState.Pressed) { if (!_onHoldP) { weapon.PrevAmmo(); _onHoldP = true; } } else { _onHoldP = false; } if (_input.RightBumper == ButtonState.Pressed) { if (!_onHoldN) { weapon.NextAmmo(); _onHoldN = true; } } else { _onHoldN = false; } if (_input.DirectionLeft == ButtonState.Pressed) { weapon.SelectAmmo(AmmoType.Light); } if (_input.DirectionUp == ButtonState.Pressed) { weapon.SelectAmmo(AmmoType.Medium); } if (_input.DirectionRight == ButtonState.Pressed) { weapon.SelectAmmo(AmmoType.Heavy); } }
private static GenericStructure WriteEntity(Entity ent) { var ret = new GenericStructure("entity"); ret["id"] = ent.ID.ToString(CultureInfo.InvariantCulture); ret["classname"] = ent.EntityData.Name; WriteEntityData(ret, ent.EntityData); if (!ent.HasChildren) ret["origin"] = FormatCoordinate(ent.Origin); var editor = WriteEditor(ent); ret.Children.Add(editor); foreach (var solid in ent.GetChildren().SelectMany(x => x.FindAll()).OfType<Solid>().OrderBy(x => x.ID)) { ret.Children.Add(WriteSolid(solid)); } return ret; }