protected override void OnEntityAdded(Entity entity, AssociatedData data) { var shadowMapPermutation = data.LightComponent.Get(LightProcessor.ShadowMapKey); data.CurrentShadowMapPermutation = shadowMapPermutation; if (shadowMapPermutation != null) { data.LightShaftsPlugin = new LightShaftsPlugin("LightShaftsPlugin") { Debug = false, RenderPass = lightShaftsPass, ShadowMap = entity.Get(LightComponent.Key).Get(LightProcessor.ShadowMapKey).ShadowMap, RenderTarget = mainTargetPlugin.RenderTarget, DepthStencil = mainTargetPlugin.DepthStencil, ViewParameters = mainPlugin.ViewParameters, }; data.LightShaftsPlugin.BoundingBoxes.AddRange(data.LightShaftsComponent.LightShaftsBoundingBoxes); renderSystem.RenderPassPlugins.Add(data.LightShaftsPlugin); } }
protected override void OnEntityRemoved(Entity entity, AssociatedData data) { base.OnEntityRemoved(entity, data); // Return AnimationClipEvaluators to pool foreach (var playingAnimation in data.AnimationComponent.PlayingAnimations) { var evaluator = playingAnimation.Evaluator; if (evaluator != null) { data.AnimationComponent.Blender.ReleaseEvaluator(evaluator); playingAnimation.Evaluator = null; } } // Return AnimationClipResult to pool if (data.AnimationClipResult != null) { data.AnimationComponent.Blender.FreeIntermediateResult(data.AnimationClipResult); } }
protected override void OnEntityAdding(Entity entity, AssociatedData data) { base.OnEntityAdding(entity, data); // initialize the AudioEmitter first position data.TransformComponent.UpdateWorldMatrix(); // ensure the worldMatrix is correct data.AudioEmitter = new AudioEmitter { Position = data.TransformComponent.WorldMatrix.TranslationVector }; // valid position is needed at first Update loop to compute velocity. // create a SoundEffectInstance for each listener activated and for each sound controller of the EmitterComponent. foreach (var listener in audioSystem.Listeners.Keys) { foreach (var soundController in data.AudioEmitterComponent.SoundEffectToController.Values) { data.ListenerControllerToSoundInstance[Tuple.Create(listener, soundController)] = soundController.CreateSoundInstance(); } } data.AudioEmitterComponent.ControllerCollectionChanged += OnSoundControllerListChanged; }
private void CheckMeshes(DecalComponent decalComponent, AssociatedData data) { if (data.RenderMesh == null) { var model = data.Model; // Create render mesh var mesh = model.Meshes[0]; var material = data.Material; var renderMesh = new RenderMesh { Source = decalComponent, RenderModel = new RenderModel { Model = model, Meshes = new RenderMesh[1], // Cyclic relationship... renderMesh is assigned in here below. Materials = new[] { new RenderModel.MaterialInfo { Material = material, MeshCount = 1, MeshStartIndex = 0 } } }, Mesh = mesh, }; renderMesh.RenderModel.Meshes[0] = renderMesh; // Update material UpdateMaterial(renderMesh, material.Passes[0], model.Materials.GetItemOrNull(0), decalComponent); data.RenderMesh = renderMesh; // Update before first add so that RenderGroup is properly set UpdateAssociatedData(decalComponent, data); } }
private void UpdateNavigationMesh(AssociatedData data) { var navigationMeshToLoad = data.Component.NavigationMesh; if (navigationMeshToLoad == null && dynamicNavigationMeshSystem != null) { // Load dynamic navigation mesh when no navigation mesh is specified on the component navigationMeshToLoad = dynamicNavigationMeshSystem?.CurrentNavigationMesh; } NavigationMeshGroupData loadedGroup = Load(navigationMeshToLoad, data.Component.GroupId); if (data.LoadedGroup != null) { Unload(data.LoadedGroup); } data.Component.RecastNavigationMesh = loadedGroup?.RecastNavigationMesh; data.LoadedGroup = loadedGroup; UpdateSceneOffset(data); }
private void UpdateNavigationMesh(NavigationComponent component, AssociatedData data) { // Remove old reference RemoveReference(component, data); if (component.NavigationMesh != null) { NavigationMeshInternal navigationMeshInternal; if (!loadedNavigationMeshes.TryGetValue(component.NavigationMesh, out navigationMeshInternal)) { navigationMeshInternal = new NavigationMeshInternal(component.NavigationMesh); loadedNavigationMeshes.Add(component.NavigationMesh, navigationMeshInternal); } data.NavigationMeshInternal = navigationMeshInternal; navigationMeshInternal.AddReference(component); SelectLayer(component, data); // Mark new navigation mesh as loaded data.LoadedNavigationMesh = component.NavigationMesh; } }
protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] NetworkEntityComponent component, [NotNull] AssociatedData associatedData) { return(associatedData.TransformComponent == entity.Transform && associatedData.MovementSnapshotsComponent == entity.Get <MovementSnapshotsComponent>() && associatedData.NetworkEntityComponent == entity.Get <NetworkEntityComponent>() && associatedData.ClientPredictionSnapshotsComponent == entity.Get <ClientPredictionSnapshotsComponent>() && associatedData.CharacterComponent == entity.Get <CharacterComponent>()); }
protected override void OnEntityComponentRemoved(Entity entity, AudioEmitterComponent component, AssociatedData data) { base.OnEntityComponentRemoved(entity, component, data); // dispose and delete all SoundEffectInstances associated to the EmitterComponent. foreach (var soundController in data.AudioEmitterComponent.SoundEffectToController.Values) { soundController.DestroyAllSoundInstances(); } data.AudioEmitterComponent.ControllerCollectionChanged -= OnSoundControllerListChanged; }
void NewElement(PhysicsElement element, AssociatedData data, Entity entity) { if (element.Shape == null) { return; //no shape no purpose } var shape = element.Shape.Shape; element.Data = data; element.BoneIndex = -1; if (!element.Sprite && element.LinkedBoneName != null && data.ModelComponent != null) { //find the linked bone, if can't be found we just skip this element for (var index = 0; index < data.ModelComponent.ModelViewHierarchy.Nodes.Length; index++) { var node = data.ModelComponent.ModelViewHierarchy.Nodes[index]; if (node.Name != element.LinkedBoneName) { continue; } element.BoneIndex = index; break; } if (element.BoneIndex == -1) { throw new Exception("The specified LinkedBoneName doesn't exist in the model hierarchy."); } } //complex hierarchy models not implemented yet if (element.BoneIndex != -1) { throw new NotImplementedException("Physics on complex hierarchy model's bones is not implemented yet."); } var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0; switch (element.Type) { case PhysicsElement.Types.PhantomCollider: { var c = physicsSystem.PhysicsEngine.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.EntityObject = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider c.IsTrigger = true; if (defaultGroups) { physicsSystem.PhysicsEngine.AddCollider(c); } else { physicsSystem.PhysicsEngine.AddCollider(c, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.StaticCollider: { var c = physicsSystem.PhysicsEngine.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.EntityObject = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider c.IsTrigger = false; if (defaultGroups) { physicsSystem.PhysicsEngine.AddCollider(c); } else { physicsSystem.PhysicsEngine.AddCollider(c, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.StaticRigidBody: { var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape); rb.EntityObject = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Static; if (defaultGroups) { physicsSystem.PhysicsEngine.AddRigidBody(rb); } else { physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.DynamicRigidBody: { var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape); rb.EntityObject = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Dynamic; rb.Mass = 1.0f; if (defaultGroups) { physicsSystem.PhysicsEngine.AddRigidBody(rb); } else { physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.KinematicRigidBody: { var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape); rb.EntityObject = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Kinematic; rb.Mass = 0.0f; if (defaultGroups) { physicsSystem.PhysicsEngine.AddRigidBody(rb); } else { physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.CharacterController: { var ch = physicsSystem.PhysicsEngine.CreateCharacter(shape, element.StepHeight); element.Collider = ch; element.Collider.EntityObject = entity; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider if (defaultGroups) { physicsSystem.PhysicsEngine.AddCharacter(ch); } else { physicsSystem.PhysicsEngine.AddCharacter(ch, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith); } characters.Add(element); } break; } elements.Add(element); }
protected override bool IsAssociatedDataValid(Entity entity, PhysicsComponent physicsComponent, AssociatedData associatedData) { return (physicsComponent == associatedData.PhysicsComponent && entity.Transform == associatedData.TransformComponent && entity.Get <ModelComponent>() == associatedData.ModelComponent); }
protected override void OnEntityComponentAdding(Entity entity, PhysicsComponent component, AssociatedData data) { component.Attach(data); var character = component as CharacterComponent; if (character != null) { characters.Add(character); } if (colliderShapesRendering) { component.AddDebugEntity(debugScene, Simulation.ColliderShapesRenderGroup); } elements.Add(component); if (component.BoneIndex != -1) { boneElements.Add((PhysicsSkinnedComponentBase)component); } }
protected override void OnEntityAdding(Entity entity, AssociatedData associatedData) { base.OnEntityAdding(entity, associatedData); associatedData.MeshAnimationUpdater = new MeshAnimationUpdater(); }
protected override void OnEntityComponentRemoved(Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data) { if (data.RenderMesh != null) { // Unregister from render system VisibilityGroup.RenderObjects.Remove(data.RenderMesh); } }
protected override void OnEntityComponentAdding(Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data) { var model = new Model(); // We create the cube via the *ProceduralModel class rather than GeometricPrimitive.*.New // because there are additional vertext data that gets created through this which are required by the Material var procCube = new CubeProceduralModel(); // Set up a new material with our decal shader. var shader = new ComputeShaderClassColor { MixinReference = "DecalShader" // This is referring to our shader at Effects\DecalShader.xksl }; var materialDescription = new MaterialDescriptor { Attributes = { DiffuseModel = new MaterialDiffuseLambertModelFeature(), Diffuse = new MaterialDiffuseMapFeature(shader), Transparency = new MaterialTransparencyBlendFeature(), CullMode = CullMode.Back, } }; procCube.MaterialInstance.IsShadowCaster = false; procCube.Generate(Services, model); var material = Material.New(_graphicsDevice, materialDescription); UpdateMaterialParameters(component, data.TransformComponent, material); data.Material = material; data.Model = model; }
protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data) { return(true); }
protected override void OnEntityComponentRemoved(Entity entity, PhysicsComponent component, AssociatedData data) { component.Detach(); }
protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] MovementSnapshotsComponent component, [NotNull] AssociatedData associatedData) { return(associatedData.TransformComponent == entity.Transform && associatedData.CharacterComponent == entity.Get <CharacterComponent>() && associatedData.InputSnapshotsComponent == entity.Get <InputSnapshotsComponent>()); }
/// <inheritdoc /> protected override bool IsAssociatedDataValid(Entity entity, LightShaftComponent component, AssociatedData associatedData) { return(component == associatedData.Component && entity.Get <LightComponent>() == associatedData.LightComponent); }
private void NewElement(PhysicsElement element, AssociatedData data, Entity entity) { if (element.Shape == null || element.Shape.Descriptions == null || element.Shape.Shape == null) { return; //no shape no purpose } var shape = element.Shape.Shape; element.Data = data; element.BoneIndex = -1; if (!element.LinkedBoneName.IsNullOrEmpty()) { element.BoneIndex = data.ModelComponent.ModelViewHierarchy.Nodes.IndexOf(x => x.Name == element.LinkedBoneName); if (element.BoneIndex == -1) { throw new Exception("The specified LinkedBoneName doesn't exist in the model hierarchy."); } element.BoneWorldMatrixOut = element.BoneWorldMatrix = data.ModelComponent.ModelViewHierarchy.NodeTransformations[element.BoneIndex].WorldMatrix; } var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0; switch (element.Type) { case PhysicsElement.Types.PhantomCollider: { var c = Simulation.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.Entity = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider c.IsTrigger = true; if (defaultGroups) { simulation.AddCollider(c); } else { simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.StaticCollider: { var c = Simulation.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.Entity = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider c.IsTrigger = false; if (defaultGroups) { simulation.AddCollider(c); } else { simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.StaticRigidBody: { var rb = Simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Static; if (defaultGroups) { simulation.AddRigidBody(rb); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.DynamicRigidBody: { var rb = Simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Dynamic; rb.Mass = 1.0f; if (defaultGroups) { simulation.AddRigidBody(rb); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.KinematicRigidBody: { var rb = Simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Kinematic; rb.Mass = 0.0f; if (defaultGroups) { simulation.AddRigidBody(rb); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElement.Types.CharacterController: { var ch = Simulation.CreateCharacter(shape, element.StepHeight); element.Collider = ch; element.Collider.Entity = entity; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider if (defaultGroups) { simulation.AddCharacter(ch); } else { simulation.AddCharacter(ch, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } characters.Add(element); } break; } elements.Add(element); if (element.BoneIndex != -1) { boneElements.Add(element); } }
protected override bool IsAssociatedDataValid(Entity entity, AnimationComponent component, AssociatedData associatedData) { return (component == associatedData.AnimationComponent && entity.Get <ModelComponent>() == associatedData.ModelComponent); }
protected override void OnEntityComponentRemoved(Entity entity, PhysicsComponent component, AssociatedData data) { currentFrameRemovals.Add(component); }
protected override void OnEntityComponentAdding(Entity entity, AnimationComponent component, AssociatedData data) { base.OnEntityComponentAdding(entity, component, data); data.AnimationUpdater = new AnimationUpdater(); }
protected override bool IsAssociatedDataValid(Entity entity, AssociatedData associatedData) { return (entity.Get(AudioEmitterComponent.Key) == associatedData.AudioEmitterComponent && entity.Get(TransformComponent.Key) == associatedData.TransformComponent); }
/// <inheritdoc /> protected override void OnEntityComponentRemoved(Entity entity, VideoComponent component, AssociatedData data) { try { data.Dispose(); } catch (Exception ex) { // FIXME log only certains exceptions, rethrow all the rest Logger.Error($"An error occurred while removing a {nameof(VideoComponent)}", ex); throw; } }
protected override bool IsAssociatedDataValid(Entity entity, AssociatedData associatedData) { return(entity.Get(ScriptComponent.Key) == associatedData.Component); }
/// <inheritdoc /> protected override bool IsAssociatedDataValid(Entity entity, VideoComponent component, AssociatedData associatedData) { return(component == associatedData.VideoComponent); }
protected override bool IsAssociatedDataValid(Entity entity, AudioEmitterComponent component, AssociatedData associatedData) { return (component == associatedData.AudioEmitterComponent && entity.Transform == associatedData.TransformComponent); }
protected override void OnEntityRemoved(Entity entity, AssociatedData data) { base.OnEntityRemoved(entity, data); ((TrackingCollection <LightComponent>)data.LightReceiverComponent.LightComponents).CollectionChanged -= data.LightComponentsChanged; }
internal void Initialize() { var commandGroups = new Dictionary <string, List <ModelNodeCommandWrapper> >(); foreach (var node in combinedNodes) { if (node.IsDestroyed) { throw new InvalidOperationException("One of the combined node is already disposed."); } foreach (var command in node.Commands) { var list = commandGroups.GetOrCreateValue(command.Name); list.Add((ModelNodeCommandWrapper)command); } } foreach (var commandGroup in commandGroups) { var mode = commandGroup.Value.First().CombineMode; if (commandGroup.Value.Any(x => x.CombineMode != mode)) { throw new InvalidOperationException($"Inconsistent combine mode among command {commandGroup.Key}"); } var shouldCombine = mode != CombineMode.DoNotCombine && (mode == CombineMode.AlwaysCombine || commandGroup.Value.Count == combinedNodes.Count); if (shouldCombine) { var command = new CombinedNodeCommandWrapper(ServiceProvider, commandGroup.Key, commandGroup.Value); AddCommand(command); } } if (!HasList || HasDictionary) { var commonChildren = GetCommonChildren(); GenerateChildren(commonChildren); } else { var commonChildren = GetCommonChildrenInList(); if (commonChildren != null) { // TODO: Disable list children for now - they need to be improved a lot (resulting combinaison is very random, especially for list of ints GenerateChildren(commonChildren); } } foreach (var key in AssociatedData.Keys.ToList()) { RemoveAssociatedData(key); } // TODO: we add associatedData added to SingleObservableNode this way, but it's a bit dangerous. Maybe we should check that all combined nodes have this data entry, and all with the same value. foreach (var singleData in CombinedNodes.SelectMany(x => x.AssociatedData).Where(x => !AssociatedData.ContainsKey(x.Key))) { AddAssociatedData(singleData.Key, singleData.Value); } FinalizeChildrenInitialization(); CheckDynamicMemberConsistency(); }
/// <summary> /// Returns the additionnal data with the matching name. /// </summary> /// <param name="name">The name of the additionnal data to look for.</param> /// <returns>The corresponding additionnal data, or <c>null</c> if no data with the given name exists.</returns> public object GetAssociatedData(string name) { return(AssociatedData.FirstOrDefault(x => x.Key == name).Value); }