//!!!!подобное для 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;
                }

                //Light, Camera, Decal, Grid specific. use bounds without scaling

                if (objectInSpace is Component_Light || objectInSpace is Component_Camera)
                {
                    var bounds = new Bounds(objectInSpace.TransformV.Position);
                    bounds.Expand(0.5);
                    localBounds = bounds - objectInSpace.Transform.Value.Position;
                }
                else if (objectInSpace is Component_Decal || objectInSpace is Component_SoundSource || objectInSpace.GetType().Name == "Component_Grid")
                {
                    var bounds = new Bounds(objectInSpace.TransformV.Position);
                    bounds.Expand(0.25);
                    localBounds = bounds - 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 );
            //}
        }
Ejemplo n.º 2
0
 public PointContainer3D(Bounds bounds, int cellCount)
 {
     this.bounds = bounds;
     sizeX       = bounds.GetSize().X;
     cells       = new Cell[cellCount];
 }
Ejemplo n.º 3
0
        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;
        }