/// <summary> /// Updates the collision data debug model. /// </summary> private void UpdateWiresModel() { // Don't update on a importer/worker thread if (!Platform.IsInMainThread) { _updateWireMesh = true; return; } if (_collisionWiresModel == null) { _collisionWiresModel = FlaxEngine.Content.CreateVirtualAsset <Model>(); _collisionWiresModel.SetupLODs(1); } Editor.Internal_GetCollisionWires(Asset.unmanagedPtr, out var triangles, out var indices); if (triangles != null && indices != null) { _collisionWiresModel.LODs[0].Meshes[0].UpdateMesh(triangles, indices); } if (_collisionWiresShowActor == null) { _collisionWiresShowActor = StaticModel.New(); _preview.Task.CustomActors.Add(_collisionWiresShowActor); } _collisionWiresShowActor.Model = _collisionWiresModel; _collisionWiresShowActor.Entries[0].Material = FlaxEngine.Content.LoadAsyncInternal <MaterialBase>(EditorAssets.WiresDebugMaterial); _preview.Model = _asset.Model; }
public Preview(ModelWindow window) : base(true) { _window = window; // Show floor widget _showFloorButton = ViewWidgetShowMenu.AddButton("Floor", OnShowFloorModelClicked); _showFloorButton.IndexInParent = 1; // Show current LOD widget _showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", OnShowCurrentLODClicked); _showCurrentLODButton.IndexInParent = 2; // Floor model _floorModel = StaticModel.New(); _floorModel.Position = new Vector3(0, -25, 0); _floorModel.Scale = new Vector3(5, 0.5f, 5); _floorModel.Model = FlaxEngine.Content.LoadAsync <Model>(StringUtils.CombinePaths(Globals.EditorFolder, "Primitives/Cube.flax")); _floorModel.IsActive = false; Task.AddCustomActor(_floorModel); // Enable shadows PreviewLight.ShadowsMode = ShadowsCastingMode.All; PreviewLight.CascadeCount = 3; PreviewLight.ShadowsDistance = 2000.0f; Task.ViewFlags |= ViewFlags.Shadows; }
/// <summary> /// Updates the collision data debug model. /// </summary> private void UpdateWiresModel() { // Don't update on a importer/worker thread if (Platform.CurrentThreadID != Globals.MainThreadID) { _updateWireMesh = true; return; } if (_collisionWiresModel == null) { _collisionWiresModel = FlaxEngine.Content.CreateVirtualAsset <Model>(); _collisionWiresModel.SetupLODs(new[] { 1 }); } Editor.Internal_GetCollisionWires(Asset.unmanagedPtr, out var triangles, out var indices); if (triangles != null && indices != null) { _collisionWiresModel.LODs[0].Meshes[0].UpdateMesh(triangles, indices); } else { Editor.LogWarning("Failed to get collision wires for " + Asset); } if (_collisionWiresShowActor == null) { _collisionWiresShowActor = StaticModel.New(); _preview.Task.AddCustomActor(_collisionWiresShowActor); } _collisionWiresShowActor.Model = _collisionWiresModel; _collisionWiresShowActor.SetMaterial(0, FlaxEngine.Content.LoadAsyncInternal <MaterialBase>(EditorAssets.WiresDebugMaterial)); _preview.Model = FlaxEngine.Content.LoadAsync <Model>(_asset.Options.Model); }
private void Update() { Screen.CursorVisible = false; Screen.CursorLock = CursorLockMode.Locked; // Mouse Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")); pitch = Mathf.Clamp(pitch + mouseDelta.Y, -88, 88); yaw += mouseDelta.X; // Jump if (CanJump && Input.GetAction("Jump")) { _jump = true; } // Shoot if (Input.GetAction("Fire")) { var ball = RigidBody.New(); var ballCollider = SphereCollider.New(); var ballModel = StaticModel.New(); ball.Name = "Bullet"; ball.StaticFlags = StaticFlags.None; ballModel.Model = SphereModel; ballModel.Parent = ball; ballModel.StaticFlags = StaticFlags.None; ballCollider.Parent = ball; ballCollider.StaticFlags = StaticFlags.None; ball.UseCCD = true; Actor gun = this.Actor.FindActor("BulletSpawner"); ball.Transform = new Transform( gun.Position, Quaternion.Identity, new Vector3(0.1f)); SceneManager.SpawnActor(ball); ball.LinearVelocity = gun.Direction * 600.0f; Destroy(ball, 5.0f); } }
public Preview(AnimationGraphWindow window) : base(true) { _window = window; // Show floor widget _showFloorButton = ViewWidgetButtonMenu.AddButton("Show floor", OnShowFloorModelClicked); _showFloorButton.Icon = Style.Current.CheckBoxTick; _showFloorButton.IndexInParent = 1; // Floor model _floorModel = StaticModel.New(); _floorModel.Position = new Vector3(0, -25, 0); _floorModel.Scale = new Vector3(5, 0.5f, 5); _floorModel.Model = FlaxEngine.Content.LoadAsync <Model>(StringUtils.CombinePaths(Globals.EditorFolder, "Primitives/Cube.flax")); Task.CustomActors.Add(_floorModel); // Enable shadows PreviewLight.ShadowsMode = ShadowsCastingMode.All; PreviewLight.CascadeCount = 2; PreviewLight.ShadowsDistance = 1000.0f; Task.Flags |= ViewFlags.Shadows; }
/// <inheritdoc /> protected override void DrawSelectionDepth(GPUContext context, SceneRenderTask task, GPUTexture customDepth) { var foliage = GizmoMode.SelectedFoliage; if (!foliage) { return; } var instanceIndex = GizmoMode.SelectedInstanceIndex; if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount) { return; } // Draw single instance var instance = foliage.GetInstance(instanceIndex); var model = foliage.GetFoliageType(instance.Type).Model; if (model) { Transform instanceWorld = foliage.Transform.LocalToWorld(instance.Transform); if (!_staticModel) { _staticModel = StaticModel.New(); _staticModel.StaticFlags = StaticFlags.None; } _staticModel.Model = model; _staticModel.Transform = instanceWorld; _actors.Add(_staticModel); Renderer.DrawSceneDepth(context, task, customDepth, _actors); } }
/// <inheritdoc /> protected override void DrawSelectionDepth(GPUContext context, SceneRenderTask task, RenderTarget customDepth) { var foliage = GizmoMode.SelectedFoliage; if (!foliage) { return; } var instanceIndex = GizmoMode.SelectedInstanceIndex; if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount) { return; } // Draw single instance foliage.GetInstance(instanceIndex, out var instance); var model = foliage.GetFoliageTypeModel(instance.Type); if (model) { Transform instanceWorld = foliage.Transform.LocalToWorld(instance.Transform); if (!_staticModel) { _staticModel = StaticModel.New(); _staticModel.StaticFlags = StaticFlags.None; } _staticModel.Model = model; _staticModel.Transform = instanceWorld; _actors.Add(_staticModel); context.DrawSceneDepth(task, customDepth, true, _actors, ActorsSources.CustomActors); } }
private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector3 hitLocation) { switch (item.ItemDomain) { case ContentDomain.Material: { if (hit is StaticModelNode.EntryNode meshNode) { var material = FlaxEngine.Content.LoadAsync <MaterialBase>(item.ID); using (new UndoBlock(Undo, meshNode.Model, "Change material")) meshNode.Entry.Material = material; } else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode) { var material = FlaxEngine.Content.LoadAsync <MaterialBase>(item.ID); using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material")) brushSurfaceNode.Surface.Material = material; } break; } case ContentDomain.Model: { if (item.TypeName == typeof(SkinnedModel).FullName) { var model = FlaxEngine.Content.LoadAsync <SkinnedModel>(item.ID); var actor = AnimatedModel.New(); actor.Name = item.ShortName; actor.SkinnedModel = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Editor.Instance.SceneEditing.Spawn(actor); } else { var model = FlaxEngine.Content.LoadAsync <Model>(item.ID); var actor = StaticModel.New(); actor.Name = item.ShortName; actor.Model = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Editor.Instance.SceneEditing.Spawn(actor); } break; } case ContentDomain.Audio: { var clip = FlaxEngine.Content.LoadAsync <AudioClip>(item.ID); var actor = AudioSource.New(); actor.Name = item.ShortName; actor.Clip = clip; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Editor.Instance.SceneEditing.Spawn(actor); break; } case ContentDomain.Prefab: { var prefab = FlaxEngine.Content.LoadAsync <Prefab>(item.ID); var actor = PrefabManager.SpawnPrefab(prefab, null); actor.Name = item.ShortName; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Editor.Instance.SceneEditing.Spawn(actor); break; } case ContentDomain.Scene: { Editor.Instance.Scene.OpenScene(item.ID, true); break; } default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Creates the new scene file. The default scene contains set of simple actors. /// </summary> /// <param name="path">The path.</param> public void CreateSceneFile(string path) { // Create a sample scene var scene = Scene.New(); var sky = Sky.New(); var sun = DirectionalLight.New(); var skyLight = SkyLight.New(); var floor = StaticModel.New(); var cam = Camera.New(); // scene.StaticFlags = StaticFlags.FullyStatic; scene.AddChild(sky); scene.AddChild(sun); scene.AddChild(skyLight); scene.AddChild(floor); scene.AddChild(cam); // sky.Name = "Sky"; sky.LocalPosition = new Vector3(40, 150, 0); sky.SunLight = sun; sky.StaticFlags = StaticFlags.FullyStatic; // sun.Name = "Sun"; sun.Brightness = 4.0f; sun.LocalPosition = new Vector3(40, 160, 0); sun.LocalEulerAngles = new Vector3(45, 0, 0); sun.StaticFlags = StaticFlags.FullyStatic; // skyLight.Mode = SkyLight.Modes.CustomTexture; skyLight.Brightness = 1.8f; skyLight.CustomTexture = FlaxEngine.Content.LoadAsyncInternal <CubeTexture>(EditorAssets.DefaultSkyCubeTexture); skyLight.StaticFlags = StaticFlags.FullyStatic; // floor.Name = "Floor"; floor.Scale = new Vector3(4, 0.5f, 4); floor.Model = FlaxEngine.Content.LoadAsync <Model>(StringUtils.CombinePaths(Globals.EditorFolder, "Primitives/Cube.flax")); if (floor.Model) { floor.Model.WaitForLoaded(); floor.Entries[0].Material = FlaxEngine.Content.LoadAsync <MaterialBase>(StringUtils.CombinePaths(Globals.EngineFolder, "WhiteMaterial.flax")); } floor.StaticFlags = StaticFlags.FullyStatic; // cam.Name = "Camera"; cam.Position = new Vector3(0, 150, -300); // Serialize var bytes = SceneManager.SaveSceneToBytes(scene); // Cleanup Object.Destroy(ref scene); if (bytes == null || bytes.Length == 0) { throw new Exception("Failed to serialize scene."); } // Write to file using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) fileStream.Write(bytes, 0, bytes.Length); }
/// <inheritdoc /> protected override DragDropEffect OnDragDropHeader(DragData data) { var result = DragDropEffect.None; Actor myActor = Actor; Actor newParent; int newOrder = -1; // Check if has no actor (only for Root Actor) if (myActor == null) { // Append to the last scene var scenes = SceneManager.Scenes; if (scenes == null || scenes.Length == 0) { throw new InvalidOperationException("No scene loaded."); } newParent = scenes[scenes.Length - 1]; } else { newParent = myActor; // Use drag positioning to change target parent and index if (DragOverMode == DragItemPositioning.Above) { if (myActor.HasParent) { newParent = myActor.Parent; newOrder = myActor.OrderInParent; } } else if (DragOverMode == DragItemPositioning.Below) { if (myActor.HasParent) { newParent = myActor.Parent; newOrder = myActor.OrderInParent + 1; } } } if (newParent == null) { throw new InvalidOperationException("Missing parent actor."); } // Drag actors if (_dragActors != null && _dragActors.HasValidDrag) { bool worldPositionLock = Root.GetKey(Keys.Control) == false; var singleObject = _dragActors.Objects.Count == 1; if (singleObject) { var targetActor = _dragActors.Objects[0].Actor; var customAction = targetActor.HasPrefabLink ? new ReparentAction(targetActor) : null; using (new UndoBlock(ActorNode.Root.Undo, targetActor, "Change actor parent", customAction)) { targetActor.SetParent(newParent, worldPositionLock); targetActor.OrderInParent = newOrder; } } else { var targetActors = _dragActors.Objects.ConvertAll(x => x.Actor); var customAction = targetActors.Any(x => x.HasPrefabLink) ? new ReparentAction(targetActors) : null; using (new UndoMultiBlock(ActorNode.Root.Undo, targetActors, "Change actors parent", customAction)) { for (int i = 0; i < targetActors.Count; i++) { var targetActor = targetActors[i]; targetActor.SetParent(newParent, worldPositionLock); targetActor.OrderInParent = newOrder; } } } result = DragDropEffect.Move; } // Drag assets else if (_dragAssets != null && _dragAssets.HasValidDrag) { for (int i = 0; i < _dragAssets.Objects.Count; i++) { var item = _dragAssets.Objects[i]; switch (item.ItemDomain) { case ContentDomain.Model: { if (item.TypeName == typeof(SkinnedModel).FullName) { // Create actor var model = FlaxEngine.Content.LoadAsync <SkinnedModel>(item.ID); var actor = AnimatedModel.New(); actor.StaticFlags = Actor.StaticFlags; actor.Name = item.ShortName; actor.SkinnedModel = model; actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); } else { // Create actor var model = FlaxEngine.Content.LoadAsync <Model>(item.ID); var actor = StaticModel.New(); actor.StaticFlags = Actor.StaticFlags; actor.Name = item.ShortName; actor.Model = model; actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); } break; } case ContentDomain.Other: { if (item.TypeName == typeof(CollisionData).FullName) { // Create actor var actor = MeshCollider.New(); actor.StaticFlags = Actor.StaticFlags; actor.Name = item.ShortName; actor.CollisionData = FlaxEngine.Content.LoadAsync <CollisionData>(item.ID); actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); } break; } case ContentDomain.Audio: { // Create actor var actor = AudioSource.New(); actor.StaticFlags = Actor.StaticFlags; actor.Name = item.ShortName; actor.Clip = FlaxEngine.Content.LoadAsync <AudioClip>(item.ID); actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); break; } case ContentDomain.Prefab: { // Create prefab instance var prefab = FlaxEngine.Content.LoadAsync <Prefab>(item.ID); var actor = PrefabManager.SpawnPrefab(prefab, null); actor.StaticFlags = Actor.StaticFlags; actor.Name = item.ShortName; actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); break; } } } result = DragDropEffect.Move; } // Drag actor type else if (_dragActorType != null && _dragActorType.HasValidDrag) { for (int i = 0; i < _dragActorType.Objects.Count; i++) { var item = _dragActorType.Objects[i]; // Create actor var actor = FlaxEngine.Object.New(item) as Actor; if (actor == null) { Editor.LogWarning("Failed to spawn actor of type " + item.FullName); continue; } actor.StaticFlags = Actor.StaticFlags; actor.Name = item.Name; actor.Transform = Actor.Transform; // Spawn ActorNode.Root.Spawn(actor, Actor); } result = DragDropEffect.Move; } // Clear cache _dragHandlers.OnDragDrop(null); // Check if scene has been modified if (result != DragDropEffect.None) { var node = SceneGraphFactory.FindNode(newParent.ID) as ActorNode; node?.TreeNode.Expand(); } return(result); }
private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector3 hitLocation) { // TODO: refactor this and dont use ContentDomain but only asset Type for matching if (item is BinaryAssetItem binaryAssetItem) { if (binaryAssetItem.Type == typeof(ParticleSystem)) { var particleSystem = FlaxEngine.Content.LoadAsync <ParticleSystem>(item.ID); var actor = ParticleEffect.New(); actor.Name = item.ShortName; actor.ParticleSystem = particleSystem; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } } switch (item.ItemDomain) { case ContentDomain.Material: { if (hit is StaticModelNode.EntryNode meshNode) { var material = FlaxEngine.Content.LoadAsync <MaterialBase>(item.ID); using (new UndoBlock(Undo, meshNode.Model, "Change material")) meshNode.Entry.Material = material; } else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode) { var material = FlaxEngine.Content.LoadAsync <MaterialBase>(item.ID); using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material")) brushSurfaceNode.Surface.Material = material; } break; } case ContentDomain.Model: { if (item.TypeName == typeof(SkinnedModel).FullName) { var model = FlaxEngine.Content.LoadAsync <SkinnedModel>(item.ID); var actor = AnimatedModel.New(); actor.Name = item.ShortName; actor.SkinnedModel = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); } else { var model = FlaxEngine.Content.LoadAsync <Model>(item.ID); var actor = StaticModel.New(); actor.Name = item.ShortName; actor.Model = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); } break; } case ContentDomain.Audio: { var clip = FlaxEngine.Content.LoadAsync <AudioClip>(item.ID); var actor = AudioSource.New(); actor.Name = item.ShortName; actor.Clip = clip; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); break; } case ContentDomain.Prefab: { var prefab = FlaxEngine.Content.LoadAsync <Prefab>(item.ID); var actor = PrefabManager.SpawnPrefab(prefab, null); actor.Name = item.ShortName; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); break; } default: throw new ArgumentOutOfRangeException(); } }
private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation) { if (item is BinaryAssetItem binaryAssetItem) { if (binaryAssetItem.Type == typeof(ParticleSystem)) { var particleSystem = FlaxEngine.Content.LoadAsync <ParticleSystem>(item.ID); var actor = ParticleEffect.New(); actor.Name = item.ShortName; actor.ParticleSystem = particleSystem; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } if (typeof(MaterialBase).IsAssignableFrom(binaryAssetItem.Type)) { if (hit is StaticModelNode staticModelNode) { var staticModel = (StaticModel)staticModelNode.Actor; var ray = ConvertMouseToRay(ref location); if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex)) { var material = FlaxEngine.Content.LoadAsync <MaterialBase>(item.ID); using (new UndoBlock(Undo, staticModel, "Change material")) staticModel.SetMaterial(entryIndex, material); } } return; } if (typeof(SkinnedModel).IsAssignableFrom(binaryAssetItem.Type)) { var model = FlaxEngine.Content.LoadAsync <SkinnedModel>(item.ID); var actor = AnimatedModel.New(); actor.Name = item.ShortName; actor.SkinnedModel = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } if (typeof(Model).IsAssignableFrom(binaryAssetItem.Type)) { var model = FlaxEngine.Content.LoadAsync <Model>(item.ID); var actor = StaticModel.New(); actor.Name = item.ShortName; actor.Model = model; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } if (typeof(AudioClip).IsAssignableFrom(binaryAssetItem.Type)) { var clip = FlaxEngine.Content.LoadAsync <AudioClip>(item.ID); var actor = AudioSource.New(); actor.Name = item.ShortName; actor.Clip = clip; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } if (typeof(Prefab).IsAssignableFrom(binaryAssetItem.Type)) { var prefab = FlaxEngine.Content.LoadAsync <Prefab>(item.ID); var actor = PrefabManager.SpawnPrefab(prefab, null); actor.Name = item.ShortName; actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation); Spawn(actor); return; } } }