Exemple #1
0
        /// <summary>
        /// Whether the plane and a ray intersect and where
        /// http://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection
        /// </summary>
        public bool intersects(ref SSRay ray, out Vector3 intersectPt)
        {
            Vector3 n = this.normal;
            var     rayDirDotPlaneN = Vector3.Dot(ray.dir, n);

            if (Math.Abs(rayDirDotPlaneN) < epsilon)
            {
                // rayDirDotPlaneN == 0; ray and the plane are parallel
                intersectPt = new Vector3(float.NaN);
                return(false);
            }
            else
            {
                // plug parametric equation of a line into the plane normal equation
                // solve (rayPos + rayDir * t - planeP0) dot planeN == 0
                // rayDir dot planeN + (rayPos - planeP0) dot planeN == 0
                Vector3 p0 = this.pickASurfacePoint();
                float   t  = Vector3.Dot(p0 - ray.pos, n) / rayDirDotPlaneN;
                if (t < -epsilon)
                {
                    // this means that the line-plane intersection is behind the ray origin (in the wrong
                    // direction). in the context of a ray this means no intersection
                    intersectPt = new Vector3(float.NaN);
                    return(false);
                }
                intersectPt = ray.pos + ray.dir * t;
                return(true);
            }
        }
Exemple #2
0
        public void setupInput()
        {
            // hook mouse drag input...
            this.MouseDown += (object sender, MouseButtonEventArgs e) => {
                this.mouseButtonDown = true;

                // cast ray for mouse click
                var     clientRect = new System.Drawing.Size(ClientRectangle.Width, ClientRectangle.Height);
                Vector2 mouseLoc   = new Vector2(e.X, e.Y);

                SSRay ray = OpenTKHelper.MouseToWorldRay(
                    this.scene.ProjectionMatrix, this.scene.InvCameraViewMatrix, clientRect, mouseLoc);

                // Console.WriteLine("mouse ({0},{1}) unproject to ray ({2})",e.X,e.Y,ray);
                // scene.addObject(new SSObjectRay(ray));

                selectedObject = scene.Intersect(ref ray);
            };
            this.MouseUp += (object sender, MouseButtonEventArgs e) => {
                this.mouseButtonDown = false;
            };
            this.MouseMove += (object sender, MouseMoveEventArgs e) => {
                if (this.mouseButtonDown)
                {
                    // Console.WriteLine("mouse dragged: {0},{1}",e.XDelta,e.YDelta);
                    this.scene.ActiveCamera.MouseDeltaOrient(e.XDelta, e.YDelta);
                    // this.activeModel.MouseDeltaOrient(e.XDelta,e.YDelta);
                }
            };
            this.MouseWheel += (object sender, MouseWheelEventArgs e) => {
                // Console.WriteLine("mousewheel {0} {1}",e.Delta,e.DeltaPrecise);
                SSCameraThirdPerson ctp = scene.ActiveCamera as SSCameraThirdPerson;
                if (ctp != null)
                {
                    ctp.followDistance += -e.DeltaPrecise;
                }
            };

            this.KeyPress += (object sender, KeyPressEventArgs e) => {
                switch (e.KeyChar)
                {
                case 'w':
                    scene.DrawWireFrameMode = SSRenderConfig.NextWireFrameMode(scene.DrawWireFrameMode);
                    updateWireframeDisplayText(scene.DrawWireFrameMode);

                    // if we need single-pass wireframes, set the GLSL uniform variable
                    shaderPgm.Activate();
                    shaderPgm.u_ShowWireframes = (scene.DrawWireFrameMode == WireframeMode.GLSL_SinglePass);
                    break;
                }
            };
        }
 public override bool preciseIntersect(ref SSRay localRay, out float nearestLocalRayContact)
 {
     nearestLocalRayContact = float.PositiveInfinity;
     foreach (var s in _renderSubMeshes)
     {
         float contact;
         if (s.preciseIntersect(ref localRay, out contact) &&
             contact < nearestLocalRayContact)
         {
             nearestLocalRayContact = contact;
         }
     }
     return(nearestLocalRayContact < float.PositiveInfinity);
 }
        protected virtual void mouseDownHandler(object sender, MouseButtonEventArgs e)
        {
            if (!base.Focused)
            {
                return;
            }

            this.mouseButtonDown = true;

            // cast ray for mouse click
            var     clientRect = new System.Drawing.Size(ClientRectangle.Width, ClientRectangle.Height);
            Vector2 mouseLoc   = new Vector2(e.X, e.Y);

            SSRay ray = OpenTKHelper.MouseToWorldRay(
                this.scene.renderConfig.projectionMatrix, this.scene.renderConfig.invCameraViewMatrix, clientRect, mouseLoc);

            // Console.WriteLine("mouse ({0},{1}) unproject to ray ({2})",e.X,e.Y,ray);
            // scene.addObject(new SSObjectRay(ray));

            selectedObject = scene.Intersect(ref ray);
            updateWireframeDisplayText();
        }
        public static bool intersectRayAABox1(SSRay ray, SSAABB box, ref float tnear, ref float tfar)
        {
            // r.dir is unit direction vector of ray
            Vector3 dirfrac = new Vector3();
            float   t;

            dirfrac.X = 1.0f / ray.dir.X;
            dirfrac.Y = 1.0f / ray.dir.Y;
            dirfrac.Z = 1.0f / ray.dir.Z;
            // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
            // r.org is origin of ray
            float t1 = (box.Min.X - ray.pos.X) * dirfrac.X;
            float t2 = (box.Max.X - ray.pos.X) * dirfrac.X;
            float t3 = (box.Min.Y - ray.pos.Y) * dirfrac.Y;
            float t4 = (box.Max.Y - ray.pos.Y) * dirfrac.Y;
            float t5 = (box.Min.Z - ray.pos.Z) * dirfrac.Z;
            float t6 = (box.Max.Z - ray.pos.Z) * dirfrac.Z;

            float tmin = Math.Max(Math.Max(Math.Min(t1, t2), Math.Min(t3, t4)), Math.Min(t5, t6));
            float tmax = Math.Min(Math.Min(Math.Max(t1, t2), Math.Max(t3, t4)), Math.Max(t5, t6));

            // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
            if (tmax < 0)
            {
                t = tmax;
                return(false);
            }

            // if tmin > tmax, ray doesn't intersect AABB
            if (tmin > tmax)
            {
                t = tmax;
                return(false);
            }

            t = tmin;
            return(true);
        }
Exemple #6
0
        public virtual bool hitTest(SSpaceMissileData missile, out Vector3 hitLocation)
        {
            var   mParams      = missile.parameters;
            float simStep      = missile.parameters.simulationStep;
            float nextTickDist = missile.velocity.LengthFast * simStep;
            float testDistSq   = (nextTickDist + targetObj.worldBoundingSphereRadius);

            testDistSq *= testDistSq;
            float toTargetDistSq = (targetObj.Pos - missile.position).LengthSquared;

            if (toTargetDistSq <= mParams.atTargetDistance * mParams.atTargetDistance)
            {
                hitLocation = missile.position;
                return(true);
            }
            else if (testDistSq > toTargetDistSq)
            {
                Vector3 velNorm = (missile.velocity - this.velocity);
                velNorm.NormalizeFast();
                SSRay ray         = new SSRay(missile.position, velNorm);
                float rayDistance = 0f;
                if (targetObj.PreciseIntersect(ref ray, ref rayDistance))
                {
                    if (rayDistance - nextTickDist < mParams.atTargetDistance)
                    {
                        hitLocation = missile.position + this.velocity * simStep
                                      + velNorm * rayDistance;
                        return(true);
                    }
                }
            }


            hitLocation = new Vector3(float.PositiveInfinity);
            return(false);
        }
Exemple #7
0
        public void update(float absoluteTimeS)
        {
            float periodicT = absoluteTimeS + _periodicTOffset;
            var laserParams = _laser.parameters;

            // update variables
            _interferenceOffset = laserParams.middleInterferenceUFunc(periodicT);
            _periodicIntensity = laserParams.intensityPeriodicFunction(periodicT);
            _periodicIntensity *= laserParams.intensityModulation(periodicT);

            // evaluate start position for this update
            Vector3 beamOriginLocal = Vector3.Zero;
            if (_laser.beamOriginPresets != null && _laser.beamOriginPresets.Count > 1) {
                var presetIdx = _beamId;
                if (presetIdx >= _laser.beamOriginPresets.Count) {
                    presetIdx %= _laser.beamOriginPresets.Count;
                }
                beamOriginLocal = _laser.beamOriginPresets [presetIdx];
            }
            _beamStartWorld = _laser.txfmSourceToWorld(beamOriginLocal);
            _beamEndWorld = _laser.txfmTargetToWorld(Vector3.Zero);
            Vector3 beamDirWorld = (_beamEndWorld - _beamStartWorld).Normalized();
            Vector3 laserXaxisWorld, laserYaxisWorld;
            OpenTKHelper.TwoPerpAxes(beamDirWorld, out laserXaxisWorld, out laserYaxisWorld);
            // local placement to start start placement in world coordinates
            Vector3 localPlacement = laserParams.getBeamPlacementVector(_beamId, laserParams.numBeams, absoluteTimeS);
            Vector3 startPlacement = localPlacement * laserParams.beamStartPlacementScale;
            Vector3 startPlacementWorldOffset =
                laserXaxisWorld * startPlacement.X + laserYaxisWorld * startPlacement.Y + beamDirWorld * startPlacement.Z;
            _beamStartWorld += startPlacementWorldOffset;

            // end position in world coordinates including drift; before intersection test
            float driftX = laserParams.driftXFunc (periodicT);
            float driftY = laserParams.driftYFunc (periodicT);
            var driftMod = laserParams.driftModulationFunc (periodicT);
            Vector3 driftedEndPlacement = laserParams.beamDestSpread * localPlacement
                + new Vector3(driftX, driftY, 0f) * driftMod;
            Vector3 endPlacementWorldOffset =
                laserXaxisWorld * driftedEndPlacement.X + laserYaxisWorld * driftedEndPlacement.Y + beamDirWorld * driftedEndPlacement.Z;
            _beamEndWorld += endPlacementWorldOffset;

            _hitsAnObstacle = false;
            // intersects with any of the intersecting objects
            if (_laser.beamObstacles != null) {
                //if (false) {
                // TODO note the code below is slow. Wen you start having many lasers
                // this will cause problems. Consider using BVH for ray tests or analyzing
                // intersection math.
                float closestDistance = float.PositiveInfinity;
                foreach (var obj in _laser.beamObstacles) {
                    float distanceToInterect;
                    var ray = new SSRay(_beamStartWorld, (_beamEndWorld - _beamStartWorld).Normalized());
                    if (obj.Intersect(ref ray, out distanceToInterect)) {
                        if (distanceToInterect < closestDistance) {
                            closestDistance = distanceToInterect;
                            _hitsAnObstacle = true;
                            _beamEndWorld = _beamStartWorld + ray.dir * closestDistance;
                        }
                    }
                }
            }
        }
Exemple #8
0
        public List <ssBVHNode <GO> > traverse(SSRay ray)
        {
            float tnear = 0f, tfar = 0f;

            return(traverse(box => OpenTKHelper.intersectRayAABox1(ray, box, ref tnear, ref tfar)));
        }
Exemple #9
0
        public void update(float absoluteTimeS)
        {
            float periodicT   = absoluteTimeS + _periodicTOffset;
            var   laserParams = _laser.parameters;

            // update variables
            _interferenceOffset = laserParams.middleInterferenceUFunc(periodicT);
            _periodicIntensity  = laserParams.intensityPeriodicFunction(periodicT);
            _periodicIntensity *= laserParams.intensityModulation(periodicT);

            // evaluate start position for this update
            Vector3 beamOriginLocal = Vector3.Zero;

            if (_laser.beamOriginPresets != null && _laser.beamOriginPresets.Count > 1)
            {
                var presetIdx = _beamId;
                if (presetIdx >= _laser.beamOriginPresets.Count)
                {
                    presetIdx %= _laser.beamOriginPresets.Count;
                }
                beamOriginLocal = _laser.beamOriginPresets [presetIdx];
            }
            _beamStartWorld = _laser.txfmSourceToWorld(beamOriginLocal);
            _beamEndWorld   = _laser.txfmTargetToWorld(Vector3.Zero);
            Vector3 beamDirWorld = (_beamEndWorld - _beamStartWorld).Normalized();
            Vector3 laserXaxisWorld, laserYaxisWorld;

            OpenTKHelper.TwoPerpAxes(beamDirWorld, out laserXaxisWorld, out laserYaxisWorld);
            // local placement to start start placement in world coordinates
            Vector3 localPlacement            = laserParams.getBeamPlacementVector(_beamId, laserParams.numBeams, absoluteTimeS);
            Vector3 startPlacement            = localPlacement * laserParams.beamStartPlacementScale;
            Vector3 startPlacementWorldOffset =
                laserXaxisWorld * startPlacement.X + laserYaxisWorld * startPlacement.Y + beamDirWorld * startPlacement.Z;

            _beamStartWorld += startPlacementWorldOffset;

            // end position in world coordinates including drift; before intersection test
            float   driftX              = laserParams.driftXFunc(periodicT);
            float   driftY              = laserParams.driftYFunc(periodicT);
            var     driftMod            = laserParams.driftModulationFunc(periodicT);
            Vector3 driftedEndPlacement = laserParams.beamDestSpread * localPlacement
                                          + new Vector3(driftX, driftY, 0f) * driftMod;
            Vector3 endPlacementWorldOffset =
                laserXaxisWorld * driftedEndPlacement.X + laserYaxisWorld * driftedEndPlacement.Y + beamDirWorld * driftedEndPlacement.Z;

            _beamEndWorld += endPlacementWorldOffset;

            _hitsAnObstacle = false;
            // intersects with any of the intersecting objects
            if (_laser.beamObstacles != null)
            {
                //if (false) {
                // TODO note the code below is slow. Wen you start having many lasers
                // this will cause problems. Consider using BVH for ray tests or analyzing
                // intersection math.
                float closestDistance = float.PositiveInfinity;
                foreach (var obj in _laser.beamObstacles)
                {
                    float distanceToInterect;
                    var   ray = new SSRay(_beamStartWorld, (_beamEndWorld - _beamStartWorld).Normalized());
                    if (obj.Intersect(ref ray, out distanceToInterect))
                    {
                        if (distanceToInterect < closestDistance)
                        {
                            closestDistance = distanceToInterect;
                            _hitsAnObstacle = true;
                            _beamEndWorld   = _beamStartWorld + ray.dir * closestDistance;
                        }
                    }
                }
            }
        }
Exemple #10
0
        public virtual bool hitTest(SSpaceMissileData missile, out Vector3 hitLocation)
        {
            var mParams = missile.cluster.parameters;
            float simStep = missile.cluster.parameters.simulationStep;
            float nextTickDist = missile.velocity.LengthFast * simStep;
            float testDistSq = (nextTickDist + targetObj.worldBoundingSphereRadius);
            testDistSq *= testDistSq;
            float toTargetDistSq = (targetObj.Pos - missile.position).LengthSquared;

            if (toTargetDistSq <= mParams.atTargetDistance * mParams.atTargetDistance) {
                hitLocation = missile.position;
                return true;
            } else if (testDistSq > toTargetDistSq) {
                Vector3 velNorm = (missile.velocity - this.velocity);
                velNorm.NormalizeFast();
                SSRay ray = new SSRay (missile.position, velNorm);
                float rayDistance = 0f;
                if (targetObj.PreciseIntersect(ref ray, ref rayDistance)) {
                    if (rayDistance - nextTickDist < mParams.atTargetDistance) {
                        hitLocation = missile.position + this.velocity * simStep
                            + velNorm * rayDistance;
                        return true;
                    }
                }
            }

            hitLocation = new Vector3(float.PositiveInfinity);
            return false;
        }