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);
                }
            }
        }
示例#2
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;
        }
示例#3
0
        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);
        }
示例#4
0
 public void ToBounds(out Bounds result)
 {
     result = new Bounds(Point1);
     result.Add(Point2);
     result.Expand(Radius);
 }
示例#5
0
        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 );
            //}
        }