Ejemplo n.º 1
0
        public void updateSprites(SInstancedSpriteData instanceData, ref RectangleF clientRect,
                                  ref Vector3 cameraPos, ref Matrix4 camera3dView, ref Matrix4 camera3dProj)
        {
            Matrix4 camera3dViewProjMat = camera3dView * camera3dProj;

            if (_sunDiskOccObj != null)
            {
                Matrix4 viewInverted = _sunDiskOccScene.renderConfig.invCameraViewMatrix.Inverted();
                Vector3 viewRight    = Vector3.Transform(Vector3.UnitX, viewInverted).Normalized();
                Vector3 viewUp       = Vector3.Transform(Vector3.UnitY, viewInverted).Normalized();
                _sunDiskOccPos = OpenTKHelper.WorldToScreen(_sunDiskOccObj.Pos, ref camera3dViewProjMat, ref clientRect);
                float bbFullEstimate;
                // note that it is assumed that the sun object is fully symmertircal when it is in view
                if (_sunDiskOccObj.renderState.matchScaleToScreenPixels)
                {
                    _sunDiskScreenSize = 2f * _sunDiskOccObj.Scale.Xy;
                    bbFullEstimate     = (float)Math.PI * _sunDiskOccObj.Scale.X * _sunDiskOccObj.Scale.Y;
                }
                else
                {
                    Vector3 occRightMost   = _sunDiskOccObj.Pos + viewRight * _sunDiskOccObj.Scale.X;
                    Vector3 occTopMost     = _sunDiskOccObj.Pos + viewUp * _sunDiskOccObj.Scale.Y;
                    Vector2 occRightMostPt = OpenTKHelper.WorldToScreen(occRightMost, ref camera3dViewProjMat, ref clientRect);
                    Vector2 occTopMostPt   = OpenTKHelper.WorldToScreen(occTopMost, ref camera3dViewProjMat, ref clientRect);
                    _sunDiskScreenSize = 2f * new Vector2(occRightMostPt.X - _sunDiskOccPos.X, _sunDiskOccPos.Y - occTopMostPt.Y);
                    bbFullEstimate     = (float)Math.PI * (float)_sunDiskScreenSize.X * (float)_sunDiskScreenSize.Y / 4f;
                }
                _sunDiskOccIntensity = Math.Min((float)_sunDiskOccObj.OcclusionQueueryResult / bbFullEstimate, 1f);
            }

            int numElements = _spriteSlotIdxs.Length;

            if (_sunDiskOccIntensity <= 0f)
            {
                // hide all sprites
                for (int i = 0; i < numElements; ++i)
                {
                    instanceData.writePosition(_spriteSlotIdxs [i], new Vector2(float.NaN));  // hide all sprites
                }
            }
            else
            {
                Vector2 compScale = new Vector2(Math.Max(_sunDiskScreenSize.X, _sunDiskScreenSize.Y)
                                                * Math.Min(1.5f, 1f / (1f - _sunDiskOccIntensity)));
                Vector2 center = new Vector2(clientRect.X, clientRect.Y)
                                 + new Vector2(clientRect.Width, clientRect.Height) / 2f;
                Vector2 towardsCenter = center - _sunDiskOccPos;
                var     color4        = _sunDiskOccObj.MainColor;
                color4.A = _sunDiskOccIntensity;
                for (int i = 0; i < numElements; ++i)
                {
                    int writeIdx = _spriteSlotIdxs [i];
                    instanceData.writeComponentScale(writeIdx, compScale);
                    instanceData.writeColor(writeIdx, color4);

                    Vector2 spriteCenter = _sunDiskOccPos + towardsCenter * 2.5f
                                           / (float)numElements * (float)i;
                    instanceData.writePosition(_spriteSlotIdxs[i], spriteCenter);
                }
            }
        }
Ejemplo n.º 2
0
        public void updateSprites(SInstancedSpriteData instanceData, ref RectangleF clientRect,
                                  ref Vector3 cameraPos, ref Matrix4 camera3dView, ref Matrix4 camera3dProj)
        {
            var beam               = _laser.beam(_beamId);
            var ray                = beam.rayWorld();
            var laserParams        = _laser.parameters;
            var beamSrcInViewSpace = Vector3.Transform(beam.startPosWorld, camera3dView);

            bool    hideSprites = true;
            Vector3 intersectPt3d;

            if (beamSrcInViewSpace.Z < 0f)
            {
                Matrix4 cameraViewProjMat3d = camera3dView * camera3dProj;
                // extract a near plane from the camera view projection matrix
                // https://www.opengl.org/discussion_boards/showthread.php/159332-Extract-clip-planes-from-projection-matrix
                SSPlane3d nearPlane = new SSPlane3d()
                {
                    A = cameraViewProjMat3d.M14 + cameraViewProjMat3d.M13,
                    B = cameraViewProjMat3d.M24 + cameraViewProjMat3d.M23,
                    C = cameraViewProjMat3d.M34 + cameraViewProjMat3d.M33,
                    D = cameraViewProjMat3d.M44 + cameraViewProjMat3d.M43
                };

                if (nearPlane.intersects(ref ray, out intersectPt3d))
                {
                    #if false
                    Console.WriteLine("camera at world pos = " + cameraPos);
                    Console.WriteLine("camera in screen pos = " + OpenTKHelper.WorldToScreen(
                                          cameraPos, ref cameraViewProjMat3d, ref clientRect));
                    Console.WriteLine("screen hit at world pos = " + intersectPt3d);
                    #endif

                    float lengthToIntersectionSq =
                        (intersectPt3d - beam.startPosWorld).LengthSquared;
                    float beamLengthSq = beam.lengthSqWorld();
                    if (lengthToIntersectionSq < beamLengthSq)
                    {
                        hideSprites = false;
                        Vector2 drawScreenPos = OpenTKHelper.WorldToScreen(
                            intersectPt3d - ray.dir * 1f, ref cameraViewProjMat3d, ref clientRect);
                        //Console.WriteLine("screen hit at screen pos = " + drawScreenPos);
                        float   intensity = _laser.envelopeIntensity * beam.periodicIntensity;
                        Vector2 drawScale
                            = new Vector2(laserParams.hitFlareSizeMaxPx * (float)Math.Exp(intensity));
                        for (int i = 0; i < _spriteSlotIdxs.Length; ++i)
                        {
                            int writeIdx = _spriteSlotIdxs [i];
                            instanceData.writePosition(writeIdx, drawScreenPos);
                            instanceData.writeComponentScale(writeIdx, drawScale);
                            instanceData.writeOrientationZ(writeIdx, intensity * 2f * (float)Math.PI);
                        }

                        Color4 backgroundColor = laserParams.backgroundColor;
                        backgroundColor.A = intensity;
                        instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.coronaBackground], backgroundColor);

                        Color4 overlayColor = laserParams.overlayColor;
                        //overlayColor.A = intensity / _laser.parameters.intensityEnvelope.sustainLevel;
                        overlayColor.A = Math.Min(intensity * 2f, 1f);
                        instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.coronaOverlay], overlayColor);
                        //System.Console.WriteLine("overlay.alpha == " + overlayColor.A);

                        Color4 ring1Color = laserParams.overlayColor;
                        //ring1Color.A = (float)Math.Pow(intensity, 5.0);
                        ring1Color.A = 0.1f * intensity;
                        instanceData.writeComponentScale(_spriteSlotIdxs[(int)SpriteId.ring1],
                                                         drawScale * (float)Math.Exp(intensity));
                        instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.ring1], ring1Color);
                        //instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.ring1], Color4.LimeGreen);

                        Color4 ring2Color = laserParams.backgroundColor;
                        //ring2Color.A = (float)Math.Pow(intensity, 10.0);
                        ring2Color.A = intensity * 0.1f;
                        instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.ring2], ring2Color);
                        //instanceData.writeColor(_spriteSlotIdxs[(int)SpriteId.ring2], Color4.Magenta);
                    }
                }
            }

            if (hideSprites)
            {
                // hide sprites
                for (int i = 0; i < _spriteSlotIdxs.Length; ++i)
                {
                    instanceData.writeComponentScale(_spriteSlotIdxs[i], Vector2.Zero);
                }
            }
            //System.Console.WriteLine("beam id " + _beamId + " hitting screen at xy " + hitPosOnScreen);
        }