protected override void OnSpaceBoundsUpdate(ref SpaceBounds newBounds) { base.OnSpaceBoundsUpdate(ref newBounds); if (rigidBody != null) { var tr = Transform.Value; var trNoScale = new Transform(tr.Position, tr.Rotation); Bounds bounds = Bounds.Cleared; foreach (var p in rigidBodyLocalPoints) { bounds.Add(trNoScale * new Vector3(p, 0)); } if (!bounds.IsCleared()) { bounds.Expand(new Vector3(0, 0, 0.001)); var b = new SpaceBounds(bounds); newBounds = SpaceBounds.Merge(newBounds, b); } } }
protected override void OnRender(ViewportRenderingContext context, Component_RenderingPipeline.IFrameData frameData, ref Component_Image actualTexture) { base.OnRender(context, frameData, ref actualTexture); var pipeline = context.RenderingPipeline as Component_RenderingPipeline_Basic; if (pipeline == null) { return; } var frameData2 = frameData as Component_RenderingPipeline_Basic.FrameData; if (frameData2 == null) { return; } if (Intensity.Value == 0) { return; } bool skip = true; foreach (var lightIndex in frameData2.LightsInFrustumSorted) { var lightItem = frameData2.Lights[lightIndex]; if (lightItem.data.children != null) { foreach (var child in lightItem.data.children) { var lensFlares = child as Component_LensFlares; if (lensFlares != null) { skip = false; break; } } } } if (skip) { return; } //init context data ViewportRenderingContextData contextData; if (context.anyData.TryGetValue("LensEffects", out var contextData2)) { contextData = (ViewportRenderingContextData)contextData2; } else { contextData = new ViewportRenderingContextData(); context.anyData["LensEffects"] = contextData; } //update context data light items contextData.Update(context.Owner.LastUpdateTimeStep, Intensity, FadeSpeed); //create copy var newTexture = context.RenderTarget2D_Alloc(actualTexture.Result.ResultSize, actualTexture.Result.ResultFormat, createSimple3DRenderer: true, createCanvasRenderer: true); var viewport = newTexture.Result.GetRenderTarget().Viewports[0]; //!!!!double precision Matrix4F viewMatrix = context.Owner.CameraSettings.ViewMatrix.ToMatrix4F(); Matrix4F projectionMatrix = context.Owner.CameraSettings.ProjectionMatrix.ToMatrix4F(); context.SetViewport(viewport, viewMatrix, projectionMatrix); pipeline.CopyToCurrentViewport(context, actualTexture); var simple3DRenderer = viewport.Simple3DRenderer; var canvasRenderer = viewport.CanvasRenderer; //render foreach (var lightIndex in frameData2.LightsInFrustumSorted) { var lightItem = frameData2.Lights[lightIndex]; if (lightItem.data.children != null) { foreach (var child in lightItem.data.children) { var lensFlares = child as Component_LensFlares; if (lensFlares != null) { var light = lightItem.data.Creator as Component_Light; if (light != null) { CheckVisibilityScreenPosition(context, lightItem.data.Position, out var gotScreenPosition, out var insideScreen); if (gotScreenPosition) { //update { switch (CheckVisibilityMethod.Value) { case CheckVisibilityMethodEnum.OcclusionQuery: { var parameter = (contextData, light); if (RenderingSystem.TryCreateOcclusionQuery(OcclusionQueryCallback, parameter, out var query)) { var thickness = context.Owner.Simple3DRenderer.GetThicknessByPixelSize(lightItem.data.Position, 5); var bounds = new Bounds(lightItem.data.Position); bounds.Expand(thickness * 0.5); simple3DRenderer.SetColor(new ColorValue(1, 0, 0)); simple3DRenderer.SetOcclusionQuery(query); simple3DRenderer.AddBounds(bounds, true); //simple3DRenderer.AddSphere( new Sphere( lightItem.data.Position, 0.5 ), 4, true ); simple3DRenderer.SetOcclusionQuery(null); } } break; case CheckVisibilityMethodEnum.PhysicsRayCast: if (CheckVisibilityPhysics(context, lightItem.data.Position)) { contextData.UpdateLastTimeVisible(light); } break; } } //render var intensity = contextData.GetIntensity(light); if (intensity > 0) { //simple3DRenderer.SetColor( new ColorValue( 1, 0, 0 ) ); //simple3DRenderer.AddSphere( new Sphere( lightItem.data.Position, 0.5 ), 10, true ); lensFlares.RenderUI(canvasRenderer, lightItem.data, context.Owner, intensity); } } else { contextData.Remove(light); } } } } } } //render if (simple3DRenderer._ViewportRendering_PrepareRenderables()) { simple3DRenderer._ViewportRendering_RenderToCurrentViewport(context); simple3DRenderer._Clear(); } canvasRenderer._ViewportRendering_RenderToCurrentViewport(context, true, context.Owner.LastUpdateTime); //free old textures context.DynamicTexture_Free(actualTexture); //update actual texture actualTexture = newTexture; }
public virtual IComponent_InteractiveObject PickInteractiveObject(UIControl playScreen, Viewport viewport) { IComponent_InteractiveObject result = null; PickInteractiveObjectEvent?.Invoke(this, playScreen, viewport, ref result); if (!FreeCamera) { //pick for 3D if (Scene.Mode.Value == Component_Scene.ModeEnum._3D) { if (UseBuiltInCamera.Value == BuiltInCameraEnum.FirstPerson || UseBuiltInCamera.Value == BuiltInCameraEnum.ThirdPerson) { Ray ray; { double rayDistance = UseBuiltInCamera.Value == BuiltInCameraEnum.FirstPerson ? 2.5 : 10; //scaling { var obj = ObjectControlledByPlayer.Value as Component_ObjectInSpace; if (obj != null) { rayDistance *= obj.TransformV.Scale.MaxComponent(); } } ray = viewport.CameraSettings.GetRayByScreenCoordinates(new Vector2(0.5, 0.5)); ray.Direction = ray.Direction.GetNormalize() * rayDistance; } var getObjectsItem = new Component_Scene.GetObjectsInSpaceItem(Component_Scene.GetObjectsInSpaceItem.CastTypeEnum.All, null, true, ray); Scene.GetObjectsInSpace(getObjectsItem); foreach (var item in getObjectsItem.Result) { var obj = item.Object.FindThisOrParent <IComponent_InteractiveObject>(); if (obj != null) { if (GetInteractiveObjectInfo(playScreen, obj).AllowInteract) { result = obj; } } } } } //pick for 2D if (Scene.Mode.Value == Component_Scene.ModeEnum._2D) { if (UseBuiltInCamera.Value == BuiltInCameraEnum.None || UseBuiltInCamera.Value == BuiltInCameraEnum.ThirdPerson) { var character = ObjectControlledByPlayer.Value as Component_Character2D; if (character != null) { double maxDistance = 2.0; //scaling { var obj = ObjectControlledByPlayer.Value as Component_ObjectInSpace; if (obj != null) { maxDistance *= obj.TransformV.Scale.MaxComponent(); } } var bounds = new Bounds(character.TransformV.Position); bounds.Expand(new Vector3(maxDistance, maxDistance, 10000)); var getObjectsItem = new Component_Scene.GetObjectsInSpaceItem(Component_Scene.GetObjectsInSpaceItem.CastTypeEnum.All, null, true, bounds); Scene.GetObjectsInSpace(getObjectsItem); foreach (var item in getObjectsItem.Result) { var obj = item.Object.FindThisOrParent <IComponent_InteractiveObject>(); if (obj != null) { var objectInSpace = obj as Component_ObjectInSpace; if (objectInSpace != null) { var distance = (objectInSpace.TransformV.Position - character.TransformV.Position).Length(); if (distance <= maxDistance) { if (GetInteractiveObjectInfo(playScreen, obj).AllowInteract) { result = obj; } } } } } } } } } //Component_CameraManagement var m = GetCurrentCameraManagement(); if (m != null) { result = m.PickInteractiveObject(this, playScreen, viewport); } return(result); }
public void ToBounds(out Bounds result) { result = new Bounds(Point1); result.Add(Point2); result.Expand(Radius); }
public static void CreatePreviewObjects(Component_Scene scene, Component_Surface surface) { DestroyPreviewObjects(scene); var center = Vector3.Zero; //!!!!среднее от всех групп double minDistanceBetweenObjects; { var groups = surface.GetComponents <Component_SurfaceGroupOfElements>(); if (groups.Length != 0) { minDistanceBetweenObjects = 0; foreach (var group in groups) { minDistanceBetweenObjects += group.MinDistanceBetweenObjects; } minDistanceBetweenObjects /= groups.Length; } else { minDistanceBetweenObjects = 1; } } //!!!! var toolRadius = minDistanceBetweenObjects * 5; // CreateObjectsBrushRadius; var toolStrength = 1.0; // CreateObjectsBrushStrength; var toolHardness = 0; // CreateObjectsBrushHardness; var random = new Random(0); double GetHardnessFactor(double length) { if (length == 0 || length <= toolHardness * toolRadius) { return(1); } else { double c; if (toolRadius - toolRadius * toolHardness != 0) { c = (length - toolRadius * toolHardness) / (toolRadius - toolRadius * toolHardness); } else { c = 0; } return((float)Math.Cos(Math.PI / 2 * c)); } } //calculate object count int count; { var toolSquare = Math.PI * toolRadius * toolRadius; double radius = minDistanceBetweenObjects / 2; double objectSquare = Math.PI * radius * radius; if (objectSquare < 0.1) { objectSquare = 0.1; } double maxCount = toolSquare / objectSquare; maxCount /= 10; count = (int)(toolStrength * (double)maxCount); count = Math.Max(count, 1); count *= 20; } var data = new List <Component_GroupOfObjects.Object>(count); //create point container to check by MinDistanceBetweenObjects PointContainer3D pointContainerFindFreePlace; { double minDistanceBetweenObjectsMax = 0; foreach (var group in surface.GetComponents <Component_SurfaceGroupOfElements>()) { minDistanceBetweenObjectsMax = Math.Max(minDistanceBetweenObjectsMax, group.MinDistanceBetweenObjects); } var bounds = new Bounds(center); bounds.Expand(toolRadius + minDistanceBetweenObjectsMax); pointContainerFindFreePlace = new PointContainer3D(bounds, 100); } for (int n = 0; n < count; n++) { surface.GetRandomVariation(new Component_Surface.GetRandomVariationOptions(), random, out var groupIndex, out var elementIndex, out var positionZ, out var rotation, out var scale); var surfaceGroup = surface.GetGroup(groupIndex); Vector3?position = null; int counter = 0; while (counter < 20) { var offset = new Vector2(random.Next(toolRadius * 2) - toolRadius, random.Next(toolRadius * 2) - toolRadius); //check by radius and by hardness var length = offset.Length(); if (length <= toolRadius && random.NextDouble() <= GetHardnessFactor(length)) { var position2 = center.ToVector2() + offset; //var result = Component_Scene_Utility.CalculateObjectPositionZ( Scene, toGroupOfObjects, center.Z, position2, destinationCachedBaseObjects ); //if( result.found ) //{ var p = new Vector3(position2, 0); // result.positionZ ); //check by MinDistanceBetweenObjects if (surfaceGroup == null || !pointContainerFindFreePlace.Contains(new Sphere(p, surfaceGroup.MinDistanceBetweenObjects))) { //found place to create position = p; break; } //} } counter++; } if (position != null) { var objPosition = position.Value + new Vector3(0, 0, positionZ); var objRotation = rotation; var objScale = scale; var surfaceElement = surfaceGroup.GetElement(elementIndex); var surfaceElementMesh = surfaceElement as Component_SurfaceElement_Mesh; if (surfaceElementMesh != null) { var meshInSpace = scene.CreateComponent <Component_MeshInSpace>(enabled: false); meshInSpace.Transform = new Transform(objPosition, objRotation, objScale); //!!!!так копировать? meshInSpace.Mesh = surfaceElementMesh.Mesh; if (meshInSpace.Mesh.Value == null) { meshInSpace.Mesh = ResourceUtility.MeshInvalid; } //!!!!так копировать? if (surfaceElementMesh.ReplaceMaterial.ReferenceSpecified) { meshInSpace.ReplaceMaterial = surfaceElementMesh.ReplaceMaterial; } meshInSpace.Enabled = true; } //add to point container pointContainerFindFreePlace.Add(ref objPosition); } } }
//!!!!подобное для Brush режима //public delegate void CalculateCreateObjectPositionUnderCursorEventDelegate( Component_ObjectInSpace objectInSpace, ref bool found, ref Vector3 position ); //public static event CalculateCreateObjectPositionUnderCursorEventDelegate CalculateCreateObjectPositionUnderCursorEvent; //public class CalculateCreateObjectPositionByRayResult //{ // public bool Found; // public Vector3 Position; // public Component_ObjectInSpace CollidedWith; // public Vector3F Normal; //} public static (bool found, Vector3 position, Component_ObjectInSpace collidedWith) CalculateCreateObjectPositionByRay(Component_Scene scene, Component_ObjectInSpace objectInSpace, Ray ray, bool allowSnap) { //var viewport = ViewportControl.Viewport; //Vector2 mouse; //if( overrideMouse.HasValue ) // mouse = overrideMouse.Value; //else //{ // mouse = viewport.MousePosition; // if( !new Rectangle( 0, 0, 1, 1 ).Contains( mouse ) ) // mouse = new Vector2( 0.5, 0.5 ); //} //Ray ray; //if( overrideRay.HasValue ) // ray = overrideRay.Value; //else // ray = viewport.CameraSettings.GetRayByScreenCoordinates( mouse ); //!!!!? clamp max distance //ray.Direction = ray.Direction.GetNormalize() * 100; //!!!!можно конвекс форму делать вместо бокса Bounds localBounds = new Bounds(); if (objectInSpace != null) { //particle system specific if (!(objectInSpace is Component_ParticleSystemInSpace)) { localBounds = objectInSpace.SpaceBounds.CalculatedBoundingBox - objectInSpace.Transform.Value.Position; } } if (localBounds.GetSize().X < 0.001) { localBounds.Expand(new Vector3(0.001, 0, 0)); } if (localBounds.GetSize().Y < 0.001) { localBounds.Expand(new Vector3(0, 0.001, 0)); } if (localBounds.GetSize().Z < 0.001) { localBounds.Expand(new Vector3(0, 0, 0.001)); } double resultMinScale = 1.01; Component_ObjectInSpace resultMinScaleCollidedWith = null; if (objectInSpace != null) { //when objectInSpace != null Plane[] planes; { var b1 = localBounds + ray.Origin; var b2 = b1 + ray.Direction; var points = CollectionUtility.Merge(b1.ToPoints(), b2.ToPoints()); ConvexHullAlgorithm.Create(points, out planes); } var item = new Component_Scene.GetObjectsInSpaceItem(Component_Scene.GetObjectsInSpaceItem.CastTypeEnum.All, null, true, planes); scene.GetObjectsInSpace(item); foreach (var resultItem in item.Result) { if (objectInSpace != resultItem.Object && !resultItem.Object.GetAllParents(false).Contains(objectInSpace)) { //mesh in space if (resultItem.Object is Component_MeshInSpace meshInSpace) { Vector3[] verticesFull; int[] indices; { var b1 = localBounds + ray.Origin; var b2 = b1 + ray.Direction; var points = CollectionUtility.Merge(b1.ToPoints(), b2.ToPoints()); ConvexHullAlgorithm.Create(points, out verticesFull, out indices); } if (meshInSpace._Intersects(verticesFull, indices)) { double minScale = 1.01; double currentScale = 0.5; //!!!!? const double threshold = 0.00001; double step = 0.25; while (step > threshold) { Vector3[] vertices = new Vector3[verticesFull.Length]; for (int n = 0; n < vertices.Length; n++) { vertices[n] = verticesFull[n] - ray.Direction + ray.Direction * currentScale; } //Vector3[] vertices; //int[] indices; //{ // var b1 = localBounds + ray.Origin; // var b2 = b1 + ray.Direction * currentScale; // var points = CollectionUtility.Merge( b1.ToPoints(), b2.ToPoints() ); // ConvexHullAlgorithm.Create( points, out vertices, out indices ); //} bool intersects = meshInSpace._Intersects(vertices, indices); if (!intersects) { minScale = currentScale; } if (intersects) { currentScale -= step; } else { currentScale += step; } step /= 2; } if (minScale <= 1 && minScale < resultMinScale) { resultMinScale = minScale; resultMinScaleCollidedWith = meshInSpace; } } } //!!!!какие еще } } } else { //when objectInSpace == null var item = new Component_Scene.GetObjectsInSpaceItem(Component_Scene.GetObjectsInSpaceItem.CastTypeEnum.All, null, true, ray); scene.GetObjectsInSpace(item); foreach (var resultItem in item.Result) { //mesh in space if (resultItem.Object is Component_MeshInSpace meshInSpace) { if (meshInSpace.RayCast(ray, Component_Mesh.CompiledData.RayCastMode.Auto, out var scale, out var triangleIndex)) { if (scale <= 1 && scale < resultMinScale) { resultMinScale = scale; resultMinScaleCollidedWith = meshInSpace; //if( triangleIndex != -1 ) //{ //} } } } //!!!!какие еще } } bool found; Vector3 pos; if (resultMinScale <= 1) { found = true; pos = ray.GetPointOnRay(resultMinScale); } else { found = false; pos = ray.Origin + ray.Direction.GetNormalize() * Math.Max(localBounds.GetBoundingSphere().Radius, 1) * 20; } //snap for 2D mode if (scene.Mode.Value == Component_Scene.ModeEnum._2D) { pos.Z = Math.Ceiling(pos.Z); } //snap if (allowSnap) { double snap; //if( Form.ModifierKeys.HasFlag( Keys.Control ) ) snap = ProjectSettings.Get.SceneEditorStepMovement; //else // snap = 0; if (snap != 0) { Vector3 snapVec = new Vector3(snap, snap, snap); pos += snapVec / 2; pos /= snapVec; pos = new Vector3I((int)pos.X, (int)pos.Y, (int)pos.Z).ToVector3(); pos *= snapVec; } } //CalculateCreateObjectPositionUnderCursorEvent?.Invoke( objectInSpace, ref found, ref pos ); return(found, pos, resultMinScaleCollidedWith); //objectToTransform.Transform = new Transform( pos, objectToTransform.Transform.Value.Rotation, objectToTransform.Transform.Value.Scale ); //} //else //{ // var localBounds = objectInSpace.SpaceBounds.CalculatedBoundingBox - objectInSpace.Transform.Value.Position; // //disable object to disable collisions // var disable = ContainsPhysicsBodies( objectInSpace ); // if( disable ) // objectInSpace.Enabled = false; // //!!!!contact group // PhysicsConvexSweepTestItem castItem = new PhysicsConvexSweepTestItem( Matrix4.FromTranslate( ray.Origin ), // Matrix4.FromTranslate( ray.Origin + ray.Direction ), 1, -1, PhysicsConvexSweepTestItem.ModeEnum.OneClosest, localBounds ); // Scene.PhysicsConvexSweepTest( new PhysicsConvexSweepTestItem[] { castItem } ); // //restore disabled object // if( disable ) // objectInSpace.Enabled = true; // Vector3 pos; // if( castItem.Result.Length != 0 ) // pos = castItem.Result[ 0 ].Position; // else // { // pos = ray.Origin + ray.Direction.GetNormalize() * Math.Max( localBounds.GetBoundingSphere().Radius, 1 ) * 20; // } // objectInSpace.Transform = new Transform( pos, objectInSpace.Transform.Value.Rotation, objectInSpace.Transform.Value.Scale ); //} }