예제 #1
0
		public void CreateLine3D()
		{
			CreateLookAtCamera(Vector3D.One * 4.0f, Vector3D.Zero);
			var entity = new Line3D(Vector3D.Zero, Vector3D.One, Color.Red);
			Assert.AreEqual(Vector3D.Zero, entity.StartPoint);
			Assert.AreEqual(Vector3D.One, entity.EndPoint);
		}
예제 #2
0
                private bool IntersectsInner(Line3D other, out double f1, out double f2)
                {
                    f2 = (-(P.X * V.Y - P.Y * V.X - other.P.X * V.Y + other.P.Y * V.X)) / (V.X * other.V.Y - V.Y * other.V.X);
                    f1 = ((other.P.X + f2 * other.V.X) - P.X) / V.X;

                    return P.Z + f1 * V.Z == other.P.Z + f2 * other.V.Z;
                }
예제 #3
0
 public void Length(string p1s, string p2s, double expected)
 {
     var p1 = Point3D.Parse(p1s);
     var p2 = Point3D.Parse(p2s);
     var l = new Line3D(p1, p2);
     Assert.AreEqual(expected, l.Length, 1e-6);
 }
예제 #4
0
                /// <summary>
                /// Bestimmt, ob diese Gerade parallel zu einer anderen ist.
                /// </summary>
                /// <returns></returns>
                public bool ParallelTo(Line3D other)
                {
                    var factorX = System.Math.Abs(V.X / other.V.X);
                    var factorY = System.Math.Abs(V.Y / other.V.Y);
                    var factorZ = System.Math.Abs(V.Z / other.V.Z);

                    return (factorX == factorY) && (factorX == factorZ);
                }
예제 #5
0
 public void Equals(string p1s, string p2s, string p3s, string p4s, bool expected)
 {
     var line1 = new Line3D(Point3D.Parse(p1s), Point3D.Parse(p2s));
     var line2 = new Line3D(Point3D.Parse(p3s), Point3D.Parse(p4s));
     Assert.AreEqual(expected, line1.Equals(line2));
     Assert.AreEqual(expected, line1 == line2);
     Assert.AreEqual(!expected, line1 != line2);
 }
 public static Line3D[] Generate(Mesh mesh)
 {
     Vector3D boundsSize = mesh.Bounds.Size;
     float size = Math.Max(boundsSize.X, Math.Max(boundsSize.Y, boundsSize.Z)) / 50.0f;
     Line3D[] result = new Line3D[mesh.Normals.Count];
     for (int i = 0; i < mesh.Normals.Count; ++i)
         result[i] = new Line3D(mesh.Positions[i], mesh.Positions[i] + (mesh.Normals[i] * size));
     return result;
 }
예제 #7
0
		public void SetLine3DPointList()
		{
			CreateLookAtCamera(Vector3D.One * 4.0f, Vector3D.Zero);
			var entity = new Line3D(Vector3D.Zero, Vector3D.Zero, Color.Red)
			{
				Points = new List<Vector3D> { Vector3D.UnitZ, Vector3D.UnitY }
			};
			Assert.AreEqual(Vector3D.UnitZ, entity.StartPoint);
			Assert.AreEqual(Vector3D.UnitY, entity.EndPoint);
		}
예제 #8
0
 public void LineToTest(string p1s, string p2s, string ps, bool mustStartFromLine, string sps)
 {
     var p1 = Point3D.Parse(p1s);
     var p2 = Point3D.Parse(p2s);
     Line3D l = new Line3D(p1, p2);
     var p = Point3D.Parse(ps);
     var actual = l.LineTo(p, mustStartFromLine);
     AssertGeometry.AreEqual(Point3D.Parse(sps), actual.StartPoint, 1e-6);
     AssertGeometry.AreEqual(p, actual.EndPoint, 1e-6);
 }
예제 #9
0
                /// <summary>
                /// Bestimmt, ob eine andere Line3D-Instanz die selbe Gerade beschreibt.
                /// </summary>
                /// <returns></returns>
                public bool IsSame(Line3D other)
                {
                    if (!ParallelTo(other))
                        return false;

                    var factor = (other.P.X - P.X) / V.X;
                    var y = other.P.Y + (factor * other.V.Y);
                    var z = other.P.Z + (factor * other.V.Z);

                    return (y == P.Y) && (z == P.Z);
                }
예제 #10
0
    internal void LimitThirdPersonCameraToWalls(Game game, Vector3Ref eye, Vector3Ref target, FloatRef curtppcameradistance)
    {
        float one = 1;
        Vector3Ref ray_start_point = target;
        Vector3Ref raytarget = eye;

        Line3D pick = new Line3D();
        float raydirX = (raytarget.X - ray_start_point.X);
        float raydirY = (raytarget.Y - ray_start_point.Y);
        float raydirZ = (raytarget.Z - ray_start_point.Z);

        float raydirLength1 = game.Length(raydirX, raydirY, raydirZ);
        raydirX /= raydirLength1;
        raydirY /= raydirLength1;
        raydirZ /= raydirLength1;
        raydirX = raydirX * (game.tppcameradistance + 1);
        raydirY = raydirY * (game.tppcameradistance + 1);
        raydirZ = raydirZ * (game.tppcameradistance + 1);
        pick.Start = Vec3.FromValues(ray_start_point.X, ray_start_point.Y, ray_start_point.Z);
        pick.End = new float[3];
        pick.End[0] = ray_start_point.X + raydirX;
        pick.End[1] = ray_start_point.Y + raydirY;
        pick.End[2] = ray_start_point.Z + raydirZ;

        //pick terrain
        IntRef pick2Count = new IntRef();
        BlockPosSide[] pick2 = game.Pick(game.s, pick, pick2Count);

        if (pick2Count.value > 0)
        {
            BlockPosSide pick2nearest = game.Nearest(pick2, pick2Count.value, ray_start_point.X, ray_start_point.Y, ray_start_point.Z);
            //pick2.Sort((a, b) => { return (FloatArrayToVector3(a.blockPos) - ray_start_point).Length.CompareTo((FloatArrayToVector3(b.blockPos) - ray_start_point).Length); });

            float pickX = pick2nearest.blockPos[0] - target.X;
            float pickY = pick2nearest.blockPos[1] - target.Y;
            float pickZ = pick2nearest.blockPos[2] - target.Z;
            float pickdistance = game.Length(pickX, pickY, pickZ);
            curtppcameradistance.value = MathCi.MinFloat(pickdistance - 1, curtppcameradistance.value);
            if (curtppcameradistance.value < one * 3 / 10) { curtppcameradistance.value = one * 3 / 10; }
        }

        float cameraDirectionX = target.X - eye.X;
        float cameraDirectionY = target.Y - eye.Y;
        float cameraDirectionZ = target.Z - eye.Z;
        float raydirLength = game.Length(raydirX, raydirY, raydirZ);
        raydirX /= raydirLength;
        raydirY /= raydirLength;
        raydirZ /= raydirLength;
        eye.X = target.X + raydirX * curtppcameradistance.value;
        eye.Y = target.Y + raydirY * curtppcameradistance.value;
        eye.Z = target.Z + raydirZ * curtppcameradistance.value;
    }
예제 #11
0
 public void BinaryRountrip()
 {
     var line = new Line3D(new Point3D(1, 2, 3), new Point3D(4, 5, 6));
     using (var ms = new MemoryStream())
     {
         var formatter = new BinaryFormatter();
         formatter.Serialize(ms, line);
         ms.Flush();
         ms.Position = 0;
         var roundTrip = (Line3D)formatter.Deserialize(ms);
         AssertGeometry.AreEqual(line, roundTrip);
     }
 }
예제 #12
0
    public void GetPickingLine(Game game, Line3D retPick, bool ispistolshoot)
    {
        int mouseX;
        int mouseY;

        if (game.cameratype == CameraType.Fpp || game.cameratype == CameraType.Tpp)
        {
            mouseX = game.Width() / 2;
            mouseY = game.Height() / 2;
        }
        else
        {
            mouseX = game.mouseCurrentX;
            mouseY = game.mouseCurrentY;
        }

        PointFloatRef aim = GetAim(game);
        if (ispistolshoot && (aim.X != 0 || aim.Y != 0))
        {
            mouseX += game.platform.FloatToInt(aim.X);
            mouseY += game.platform.FloatToInt(aim.Y);
        }

        tempViewport[0] = 0;
        tempViewport[1] = 0;
        tempViewport[2] = game.Width();
        tempViewport[3] = game.Height();

        unproject.UnProject(mouseX, game.Height() - mouseY, 1, game.mvMatrix.Peek(), game.pMatrix.Peek(), tempViewport, tempRay);
        unproject.UnProject(mouseX, game.Height() - mouseY, 0, game.mvMatrix.Peek(), game.pMatrix.Peek(), tempViewport, tempRayStartPoint);

        float raydirX = (tempRay[0] - tempRayStartPoint[0]);
        float raydirY = (tempRay[1] - tempRayStartPoint[1]);
        float raydirZ = (tempRay[2] - tempRayStartPoint[2]);
        float raydirLength = game.Length(raydirX, raydirY, raydirZ);
        raydirX /= raydirLength;
        raydirY /= raydirLength;
        raydirZ /= raydirLength;

        retPick.Start = new float[3];
        retPick.Start[0] = tempRayStartPoint[0];// +raydirX; //do not pick behind
        retPick.Start[1] = tempRayStartPoint[1];// +raydirY;
        retPick.Start[2] = tempRayStartPoint[2];// +raydirZ;

        float pickDistance1 = CurrentPickDistance(game) * ((ispistolshoot) ? 100 : 1);
        pickDistance1 += 1;
        retPick.End = new float[3];
        retPick.End[0] = tempRayStartPoint[0] + raydirX * pickDistance1;
        retPick.End[1] = tempRayStartPoint[1] + raydirY * pickDistance1;
        retPick.End[2] = tempRayStartPoint[2] + raydirZ * pickDistance1;
    }
예제 #13
0
    public BlockPosSide[] LineIntersection(DelegateIsBlockEmpty isEmpty, DelegateGetBlockHeight getBlockHeight, Line3D line, IntRef retCount)
    {
        lCount = 0;
        currentLine = line;
        currentHit[0] = 0;
        currentHit[1] = 0;
        currentHit[2] = 0;
        ListBox3d l1 = Search(PredicateBox3DHit.Create(this));
        for (int i = 0; i < l1.count; i++)
        {
            Box3D node = l1.arr[i];
            float[] hit = currentHit;
            float x = node.MinEdge[0];
            float y = node.MinEdge[2];
            float z = node.MinEdge[1];
            if (!isEmpty.IsBlockEmpty(platform.FloatToInt(x),platform.FloatToInt(y),platform.FloatToInt( z)))
            {
                Box3D node2 = new Box3D();
                node2.MinEdge = Vec3.CloneIt(node.MinEdge);
                node2.MaxEdge = Vec3.CloneIt(node.MaxEdge);
                node2.MaxEdge[1] = node2.MinEdge[1] + getBlockHeight.GetBlockHeight(platform.FloatToInt(x),platform.FloatToInt(y),platform.FloatToInt(z));

                BlockPosSide b = new BlockPosSide();
                float[] hit2 = new float[3];

                float[] dir = new float[3];
                dir[0] = line.End[0] - line.Start[0];
                dir[1] = line.End[1] - line.Start[1];
                dir[2] = line.End[2] - line.Start[2];
                bool ishit = Intersection.HitBoundingBox(node2.MinEdge, node2.MaxEdge, line.Start, dir, hit2);
                if (ishit)
                {
                    //hit2.pos = Vec3.FromValues(x, z, y);
                    b.blockPos = Vec3.FromValues(platform.FloatToInt(x), platform.FloatToInt(z), platform.FloatToInt(y));
                    b.collisionPos = hit2;
                    l[lCount++] = b;
                }
            }
        }
        BlockPosSide[] ll = new BlockPosSide[lCount];
        for (int i = 0; i < lCount; i++)
        {
            ll[i] = l[i];
        }
        retCount.value = lCount;
        return ll;
    }
 /// <summary>
 /// Find intersection between Line3D and Plane
 /// http://geomalgorithms.com/a05-_intersect-1.html
 /// </summary>
 /// <param name="line"></param>
 /// <param name="tolerance"></param>
 /// <returns>Intersection Point or null</returns>
 public static Point3D IntersectionWith(Plane plane, Line3D line, double tolerance = float.Epsilon)
 {
     if (line.Direction.IsPerpendicularTo(plane.Normal)) { //either parallel or lies in the plane
         Point3D projectedPoint = plane.Project(line.StartPoint, line.Direction);
         if (projectedPoint == line.StartPoint) { //Line lies in the plane
             throw new InvalidOperationException("Line lies in the plane"); //Not sure what should be done here
         } else { // Line and plane are parallel
             throw new InvalidOperationException("NULLLLLLL");
         }
     }
     var d = plane.SignedDistanceTo(line.StartPoint);
     var u = line.StartPoint.VectorTo(line.EndPoint);
     var t = -1 * d / u.DotProduct(plane.Normal);
     if (t > 1 || t < 0) { // They are not intersected
         throw new InvalidOperationException("NULLLLLLL");
     }
     return line.StartPoint + (t * u);
 }
예제 #15
0
    public void runIndoorTest()
    {
        device = new IrrlichtDevice(SelectedDriverType,
            new Dimension2D(800,600), 16, false, true, false);

        device.EventReceiver = this;
        device.ResizeAble = true;
        device.WindowCaption = "Irrlicht.NET indoor test";

        // load some textures and meshes

        ITexture texSydney = device.VideoDriver.GetTexture(@"..\..\media\sydney.bmp");
        ITexture texWall = device.VideoDriver.GetTexture(@"..\..\media\wall.jpg");
        ITexture texLogo = device.VideoDriver.GetTexture(@"..\..\media\irrlichtlogoaligned.jpg");
        Irrlicht.Scene.IAnimatedMesh mesh =
            device.SceneManager.GetMesh(@"..\..\media\sydney.md2");

        if (mesh == null)
        {
            System.Windows.Forms.MessageBox.Show(
                @"Could not load mesh ..\..\media\sydney.md2, exiting.",
                "Problem starting program");
            return;
        }

        // add a cube to the scene

        ISceneNode node = device.SceneManager.AddCubeSceneNode(15,
            null, -1, new Vector3D(30,-15,0));
        node.SetMaterialTexture(0, texWall);
        node.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false);

        // add an animator to the cube to make it rotate

        ISceneNodeAnimator anim = device.SceneManager.CreateRotationAnimator(new Vector3D(0.2f, 0.2f, 0));
        node.AddAnimator(anim);

        // add animated mesh

        IAnimatedMeshSceneNode anode = device.SceneManager.AddAnimatedMeshSceneNode(mesh, null, -1);
        anode.SetMaterialTexture(0, texSydney);
        anode.SetMaterialFlag(MaterialFlag.LIGHTING, false);

        anode.Scale = new Vector3D(2,2,2);
        anode.Position = new Vector3D(0, -20, 0);

        // add a shadow

        Shadow = anode.AddShadowVolumeSceneNode();
        if (Shadow != null)
            Shadow.Visible = false;

        // where no light there no shadow
        device.SceneManager.AddLightSceneNode(null, new Vector3D(20,100,-50),
            new Colorf(255,0,0), 200, -1);

        // add quake 3 level

        device.FileSystem.AddZipFileArchive("../../media/map-20kdm2.pk3");

        IAnimatedMesh q3levelmesh = device.SceneManager.GetMesh("20kdm2.bsp");
        ISceneNode q3node = device.SceneManager.AddOctTreeSceneNode(q3levelmesh, null, -1);
        q3node.Position = new Vector3D(-1370,-130,-1400);

        // create octtree triangle selector for q3 mesh

        ITriangleSelector selector = device.SceneManager.CreateOctTreeTriangleSelector(
            q3levelmesh.GetMesh(0), q3node, 128);

        // add billboard

        IBillboardSceneNode bill = device.SceneManager.AddBillboardSceneNode(null,
            new Dimension2Df(20,20), new Vector3D(0,0,0), -1);

        bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR);
        bill.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/particle.bmp"));
        bill.SetMaterialFlag(MaterialFlag.LIGHTING, false);
        bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false);

        // create camera

        ICameraSceneNode cam =
            device.SceneManager.AddCameraSceneNodeFPS(null, 100, 300, -1);
        cam.Position = new Vector3D(20,300,-50);

        // make cursor invisible
        device.CursorControl.Visible = false;

        // create collision animator and add it to the camera

        ISceneNodeAnimator collAnim = device.SceneManager.CreateCollisionResponseAnimator(
            selector, cam,
            new Vector3D(30,50,30),  // size of ellipsoid around camera
            new Vector3D(0, -3, 0),  // gravity
            new Vector3D(0, 50, 0),  // translation
            0.0005f);                // sliding value

        cam.AddAnimator(collAnim);

        // load some font and set it into the skin

        IGUIFont font = device.GUIEnvironment.GetFont("../../media/fonthaettenschweiler.bmp");
        device.GUIEnvironment.Skin.Font = font;

        // add some gui stuff

        device.GUIEnvironment.AddMessageBox("Hello World",
            "I'm a Irrlicht.NET MessageBox. Please press SPACE to close me.", true,
            MessageBoxFlag.OK | MessageBoxFlag.CANCEL, null, -1);

        // start drawing loop

        int fps = 0;

        device.Run(); // fix for a temporary bug where quit messages are not be removed in the queue
        while(device.Run())
            if (device.WindowActive)
            {
                device.VideoDriver.BeginScene(true, true, new Color(255,0,0,50));

                // draw scene

                device.SceneManager.DrawAll();
                device.GUIEnvironment.DrawAll();

                // do some collision testing

                Line3D line = new Line3D();
                line.start = cam.Position;
                line.end = ((cam.Target - line.start).Normalize() * 1000.0f ) + line.start;

                Vector3D intersection = new Vector3D();
                Triangle3D tri = new Triangle3D();

                if (device.SceneManager.SceneCollisionManager.GetCollisionPoint(
                    line, selector, out intersection, out tri))
                {
                    bill.Position = intersection;

                    Material mat = new Material();
                    mat.Lighting = false;

                    device.VideoDriver.SetTransform(TransformationState.WORLD, new Matrix4());
                    device.VideoDriver.SetMaterial(mat);
                    device.VideoDriver.Draw3DTriangle(tri, new Color(0,255,0,0));
                }

                // draw 2d logo

                device.VideoDriver.Draw2DImage(
                    texLogo, new Position2D(10,10),
                    new Rect(0,0,88,31),
                    new Rect(new Position2D(0,0),device.VideoDriver.ScreenSize),
                    new Color(0xffffff), false);

                // draw some text
                font.Draw("Press 'S' to toggle the visibility of the realtime shadow.",
                    new Position2D(120,20), new Color(100,150,200,200));

                device.VideoDriver.EndScene();

                if (fps != device.VideoDriver.FPS)
                {
                    fps = device.VideoDriver.FPS;
                    device.WindowCaption = "Irrlicht.NET test (primitives:" +
                        device.VideoDriver.PrimitiveCountDrawn + ") fps:" + fps;
                }
            }
    }
예제 #16
0
 /// <summary>
 /// Prüft, ob sich diese Gerade mit einer anderen schneidet.
 /// </summary>
 /// <returns></returns>
 public bool IntersectsWith(Line3D other)
 {
     double f1, f2;
     return IntersectsInner(other, out f1, out f2);
 }
예제 #17
0
        /// <summary>
        /// 构造函数,此方法之能处理同一个平面的所有线段
        /// </summary>
        /// <param name="searchLines"></param>
        /// <param name="isLargeRegion"></param>
        public ClosedLinesAlgorithm(List <Line3D> searchLines, bool isLargeRegion, bool isDecompose = true, Line3D orginLine = null)
        {
            //要选择的选段
            this.SearchLines = searchLines;

            this.IsLargeRegion = isLargeRegion;

            this.IsDecompose = isDecompose;

            if (orginLine != null)
            {
                //起点位置
                this.OrginLine = orginLine;
                //起点高度
                this.Elevation = OrginLine.Start.Z;
            }
        }
예제 #18
0
        public static bool IsOnLineBetween(this Point3D p, Point3D start, Point3D end)
        {
            var l = new Line3D(start, end);

            return(l.IsOnLine(p));
        }
예제 #19
0
 public bool IntersectLine(Line3D line, out double intersectDistance)
 {
     intersectDistance = this.Intersect(line.ToRay());
     return(intersectDistance >= 0.0 && intersectDistance <= 1.0);
 }
예제 #20
0
        public void ProjectLineOnTest()
        {
            var unitVector = UnitVector3D.ZAxis;
            var rootPoint = new Point3D(0, 0, 1);
            var plane = new Plane(unitVector, rootPoint);

            var line = new Line3D(new Point3D(0, 0, 0), new Point3D(1, 0, 0));
            var projectOn = plane.Project(line);
            AssertGeometry.AreEqual(new Line3D(new Point3D(0, 0, 1), new Point3D(1, 0, 1)), projectOn, float.Epsilon);
        }
예제 #21
0
파일: Form2.cs 프로젝트: fel88/GeomPad
        private void intersectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count != 2)
            {
                return;
            }
            var i0 = listView1.SelectedItems[0].Tag as HelperItem;
            var i1 = listView1.SelectedItems[1].Tag as HelperItem;

            var objs = new[] { i0, i1 };

            if (i0 is LineHelper lh0 && i1 is LineHelper lh1)
            {
                var inter = Geometry.Intersect3dCrossedLines(new Line3D()
                {
                    Start = lh0.Start, End = lh0.End
                }, new Line3D()
                {
                    Start = lh1.Start, End = lh1.End
                });
                if (inter != null && !double.IsNaN(inter.Value.X) && !double.IsInfinity(inter.Value.X))
                {
                    Helpers.Add(new PointHelper()
                    {
                        Position = inter.Value
                    });
                    updateHelpersList();
                }
                else
                {
                    SetStatus("no intersection", StatusTypeEnum.Warning);
                }
            }
            if (objs.Any(z => z is LineHelper) && objs.Any(z => z is PointHelper))
            {
                var pl = objs.First(z => z is PointHelper) as PointHelper;
                var th = objs.First(z => z is LineHelper) as LineHelper;

                var l = new Line3D()
                {
                    Start = th.Start, End = th.End
                };
                if (l.IsPointOnLine(pl.Position))
                {
                    SetStatus($"point is on line ({(l.IsPointInsideSegment(pl.Position) ? "inside" : "not inside")})", StatusTypeEnum.Information);
                }
                else
                {
                    SetStatus("point is not on line", StatusTypeEnum.Warning);
                }
            }
            if (objs.Any(z => z is TriangleHelper) && objs.Any(z => z is PlaneHelper))
            {
                var pl = objs.First(z => z is PlaneHelper) as PlaneHelper;
                var th = objs.First(z => z is TriangleHelper) as TriangleHelper;

                var n0     = th.V2 - th.V0;
                var n1     = th.V1 - th.V0;
                var normal = Vector3d.Cross(n0, n1);
                var pln    = new PlaneHelper()
                {
                    Position = th.V0, Normal = normal
                };
                var ln = pln.Intersect(pl);
                if (ln != null)
                {
                    Helpers.Add(new LineHelper()
                    {
                        Start = ln.Start, End = ln.End
                    });
                    updateHelpersList();
                }
            }
            if (objs.All(z => z is PlaneHelper))
            {
                var pl  = objs[0] as PlaneHelper;
                var pl2 = objs[1] as PlaneHelper;

                var ln = pl2.Intersect(pl);
                if (ln != null)
                {
                    Helpers.Add(new LineHelper()
                    {
                        Start = ln.Start, End = ln.End
                    });
                    updateHelpersList();
                }
            }
        }
예제 #22
0
    void PickEntity(Game game, Line3D pick, BlockPosSide[] pick2, IntRef pick2count)
    {
        game.SelectedEntityId        = -1;
        game.currentlyAttackedEntity = -1;
        float one = 1;

        for (int i = 0; i < game.entitiesCount; i++)
        {
            if (game.entities[i] == null)
            {
                continue;
            }
            if (i == game.LocalPlayerId)
            {
                continue;
            }
            if (game.entities[i].drawModel == null)
            {
                continue;
            }
            Entity p_ = game.entities[i];
            if (p_.networkPosition == null)
            {
                continue;
            }
            if (!p_.networkPosition.PositionLoaded)
            {
                continue;
            }
            if (!p_.usable)
            {
                continue;
            }
            float feetposX = p_.position.x;
            float feetposY = p_.position.y;
            float feetposZ = p_.position.z;

            float dist = game.Dist(feetposX, feetposY, feetposZ, game.player.position.x, game.player.position.y, game.player.position.z);
            if (dist > 5)
            {
                continue;
            }

            //var p = PlayerPositionSpawn;
            Box3D bodybox = new Box3D();
            float h       = p_.drawModel.ModelHeight;
            float r       = one * 35 / 100;

            bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ - r);
            bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ + r);
            bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ - r);
            bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ + r);

            bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
            bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
            bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
            bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

            float[] p;
            float   localeyeposX = game.EyesPosX();
            float   localeyeposY = game.EyesPosY();
            float   localeyeposZ = game.EyesPosZ();
            p = Intersection.CheckLineBoxExact(pick, bodybox);
            if (p != null)
            {
                //do not allow to shoot through terrain
                if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                                              > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                {
                    game.SelectedEntityId = i;
                    if (game.cameratype == CameraType.Fpp || game.cameratype == CameraType.Tpp)
                    {
                        game.currentlyAttackedEntity = i;
                    }
                }
            }
        }
    }
예제 #23
0
    internal void NextBullet(Game game, int bulletsshot)
    {
        float one    = 1;
        bool  left   = game.mouseLeft;
        bool  middle = game.mouseMiddle;
        bool  right  = game.mouseRight;

        bool IsNextShot = bulletsshot != 0;

        if (!game.leftpressedpicking)
        {
            if (game.mouseleftclick)
            {
                game.leftpressedpicking = true;
            }
            else
            {
                left = false;
            }
        }
        else
        {
            if (game.mouseleftdeclick)
            {
                game.leftpressedpicking = false;
                left = false;
            }
        }
        if (!left)
        {
            game.currentAttackedBlock = null;
        }

        Packet_Item item          = game.d_Inventory.RightHand[game.ActiveMaterial];
        bool        ispistol      = (item != null && game.blocktypes[item.BlockId].IsPistol);
        bool        ispistolshoot = ispistol && left;
        bool        isgrenade     = ispistol && game.blocktypes[item.BlockId].PistolType == Packet_PistolTypeEnum.Grenade;

        if (ispistol && isgrenade)
        {
            ispistolshoot = game.mouseleftdeclick;
        }
        //grenade cooking - TODO: fix instant explosion when closing ESC menu
        if (game.mouseleftclick)
        {
            game.grenadecookingstartMilliseconds = game.platform.TimeMillisecondsFromStart();
            if (ispistol && isgrenade)
            {
                if (game.blocktypes[item.BlockId].Sounds.ShootCount > 0)
                {
                    game.AudioPlay(game.platform.StringFormat("{0}.ogg", game.blocktypes[item.BlockId].Sounds.Shoot[0]));
                }
            }
        }
        float wait = ((one * (game.platform.TimeMillisecondsFromStart() - game.grenadecookingstartMilliseconds)) / 1000);

        if (isgrenade && left)
        {
            if (wait >= game.grenadetime && isgrenade && game.grenadecookingstartMilliseconds != 0)
            {
                ispistolshoot         = true;
                game.mouseleftdeclick = true;
            }
            else
            {
                return;
            }
        }
        else
        {
            game.grenadecookingstartMilliseconds = 0;
        }

        if (ispistol && game.mouserightclick && (game.platform.TimeMillisecondsFromStart() - game.lastironsightschangeMilliseconds) >= 500)
        {
            game.IronSights = !game.IronSights;
            game.lastironsightschangeMilliseconds = game.platform.TimeMillisecondsFromStart();
        }

        IntRef pick2count = new IntRef();
        Line3D pick       = new Line3D();

        GetPickingLine(game, pick, ispistolshoot);
        BlockPosSide[] pick2 = game.Pick(game.s, pick, pick2count);

        if (left)
        {
            game.handSetAttackDestroy = true;
        }
        else if (right)
        {
            game.handSetAttackBuild = true;
        }

        if (game.overheadcamera && pick2count.value > 0 && left)
        {
            //if not picked any object, and mouse button is pressed, then walk to destination.
            if (game.Follow == null)
            {
                //Only walk to destination when not following someone
                game.playerdestination = Vector3Ref.Create(pick2[0].blockPos[0], pick2[0].blockPos[1] + 1, pick2[0].blockPos[2]);
            }
        }
        bool pickdistanceok = (pick2count.value > 0); //&& (!ispistol);

        if (pickdistanceok)
        {
            if (game.Dist(pick2[0].blockPos[0] + one / 2, pick2[0].blockPos[1] + one / 2, pick2[0].blockPos[2] + one / 2,
                          pick.Start[0], pick.Start[1], pick.Start[2]) > CurrentPickDistance(game))
            {
                pickdistanceok = false;
            }
        }
        bool playertileempty = game.IsTileEmptyForPhysics(
            game.platform.FloatToInt(game.player.position.x),
            game.platform.FloatToInt(game.player.position.z),
            game.platform.FloatToInt(game.player.position.y + (one / 2)));
        bool playertileemptyclose = game.IsTileEmptyForPhysicsClose(
            game.platform.FloatToInt(game.player.position.x),
            game.platform.FloatToInt(game.player.position.z),
            game.platform.FloatToInt(game.player.position.y + (one / 2)));
        BlockPosSide pick0 = new BlockPosSide();

        if (pick2count.value > 0 &&
            ((pickdistanceok && (playertileempty || (playertileemptyclose))) ||
             game.overheadcamera)
            )
        {
            game.SelectedBlockPositionX = game.platform.FloatToInt(pick2[0].Current()[0]);
            game.SelectedBlockPositionY = game.platform.FloatToInt(pick2[0].Current()[1]);
            game.SelectedBlockPositionZ = game.platform.FloatToInt(pick2[0].Current()[2]);
            pick0 = pick2[0];
        }
        else
        {
            game.SelectedBlockPositionX = -1;
            game.SelectedBlockPositionY = -1;
            game.SelectedBlockPositionZ = -1;
            pick0.blockPos    = new float[3];
            pick0.blockPos[0] = -1;
            pick0.blockPos[1] = -1;
            pick0.blockPos[2] = -1;
        }
        PickEntity(game, pick, pick2, pick2count);
        if (game.cameratype == CameraType.Fpp || game.cameratype == CameraType.Tpp)
        {
            int ntileX = game.platform.FloatToInt(pick0.Current()[0]);
            int ntileY = game.platform.FloatToInt(pick0.Current()[1]);
            int ntileZ = game.platform.FloatToInt(pick0.Current()[2]);
            if (game.IsUsableBlock(game.map.GetBlock(ntileX, ntileZ, ntileY)))
            {
                game.currentAttackedBlock = Vector3IntRef.Create(ntileX, ntileZ, ntileY);
            }
        }
        if (game.GetFreeMouse())
        {
            if (pick2count.value > 0)
            {
                OnPick_(pick0);
            }
            return;
        }

        if ((one * (game.platform.TimeMillisecondsFromStart() - lastbuildMilliseconds) / 1000) >= BuildDelay(game) ||
            IsNextShot)
        {
            if (left && game.d_Inventory.RightHand[game.ActiveMaterial] == null)
            {
                game.SendPacketClient(ClientPackets.MonsterHit(game.platform.FloatToInt(2 + game.rnd.NextFloat() * 4)));
            }
            if (left && !fastclicking)
            {
                //todo animation
                fastclicking = false;
            }
            if ((left || right || middle) && (!isgrenade))
            {
                lastbuildMilliseconds = game.platform.TimeMillisecondsFromStart();
            }
            if (isgrenade && game.mouseleftdeclick)
            {
                lastbuildMilliseconds = game.platform.TimeMillisecondsFromStart();
            }
            if (game.reloadstartMilliseconds != 0)
            {
                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (ispistolshoot)
            {
                if ((!(game.LoadedAmmo[item.BlockId] > 0)) ||
                    (!(game.TotalAmmo[item.BlockId] > 0)))
                {
                    game.AudioPlay("Dry Fire Gun-SoundBible.com-2053652037.ogg");
                    PickingEnd(left, right, middle, ispistol);
                    return;
                }
            }
            if (ispistolshoot)
            {
                float toX = pick.End[0];
                float toY = pick.End[1];
                float toZ = pick.End[2];
                if (pick2count.value > 0)
                {
                    toX = pick2[0].blockPos[0];
                    toY = pick2[0].blockPos[1];
                    toZ = pick2[0].blockPos[2];
                }

                Packet_ClientShot shot = new Packet_ClientShot();
                shot.FromX     = game.SerializeFloat(pick.Start[0]);
                shot.FromY     = game.SerializeFloat(pick.Start[1]);
                shot.FromZ     = game.SerializeFloat(pick.Start[2]);
                shot.ToX       = game.SerializeFloat(toX);
                shot.ToY       = game.SerializeFloat(toY);
                shot.ToZ       = game.SerializeFloat(toZ);
                shot.HitPlayer = -1;

                for (int i = 0; i < game.entitiesCount; i++)
                {
                    if (game.entities[i] == null)
                    {
                        continue;
                    }
                    if (game.entities[i].drawModel == null)
                    {
                        continue;
                    }
                    Entity p_ = game.entities[i];
                    if (p_.networkPosition == null)
                    {
                        continue;
                    }
                    if (!p_.networkPosition.PositionLoaded)
                    {
                        continue;
                    }
                    float feetposX = p_.position.x;
                    float feetposY = p_.position.y;
                    float feetposZ = p_.position.z;
                    //var p = PlayerPositionSpawn;
                    Box3D bodybox  = new Box3D();
                    float headsize = (p_.drawModel.ModelHeight - p_.drawModel.eyeHeight) * 2; //0.4f;
                    float h        = p_.drawModel.ModelHeight - headsize;
                    float r        = one * 35 / 100;

                    bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ - r);
                    bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ + r);
                    bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ - r);
                    bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ + r);

                    bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
                    bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
                    bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
                    bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

                    Box3D headbox = new Box3D();

                    headbox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
                    headbox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
                    headbox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
                    headbox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

                    headbox.AddPoint(feetposX - r, feetposY + h + headsize, feetposZ - r);
                    headbox.AddPoint(feetposX - r, feetposY + h + headsize, feetposZ + r);
                    headbox.AddPoint(feetposX + r, feetposY + h + headsize, feetposZ - r);
                    headbox.AddPoint(feetposX + r, feetposY + h + headsize, feetposZ + r);

                    float[] p;
                    float   localeyeposX = game.EyesPosX();
                    float   localeyeposY = game.EyesPosY();
                    float   localeyeposZ = game.EyesPosZ();
                    p = Intersection.CheckLineBoxExact(pick, headbox);
                    if (p != null)
                    {
                        //do not allow to shoot through terrain
                        if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                                                      > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                        {
                            if (!isgrenade)
                            {
                                Entity entity = new Entity();
                                Sprite sprite = new Sprite();
                                sprite.positionX = p[0];
                                sprite.positionY = p[1];
                                sprite.positionZ = p[2];
                                sprite.image     = "blood.png";
                                entity.sprite    = sprite;
                                entity.expires   = Expires.Create(one * 2 / 10);
                                game.EntityAddLocal(entity);
                            }
                            shot.HitPlayer = i;
                            shot.IsHitHead = 1;
                        }
                    }
                    else
                    {
                        p = Intersection.CheckLineBoxExact(pick, bodybox);
                        if (p != null)
                        {
                            //do not allow to shoot through terrain
                            if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                                                          > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                            {
                                if (!isgrenade)
                                {
                                    Entity entity = new Entity();
                                    Sprite sprite = new Sprite();
                                    sprite.positionX = p[0];
                                    sprite.positionY = p[1];
                                    sprite.positionZ = p[2];
                                    sprite.image     = "blood.png";
                                    entity.sprite    = sprite;
                                    entity.expires   = Expires.Create(one * 2 / 10);
                                    game.EntityAddLocal(entity);
                                }
                                shot.HitPlayer = i;
                                shot.IsHitHead = 0;
                            }
                        }
                    }
                }
                shot.WeaponBlock = item.BlockId;
                game.LoadedAmmo[item.BlockId] = game.LoadedAmmo[item.BlockId] - 1;
                game.TotalAmmo[item.BlockId]  = game.TotalAmmo[item.BlockId] - 1;
                float projectilespeed = game.DeserializeFloat(game.blocktypes[item.BlockId].ProjectileSpeedFloat);
                if (projectilespeed == 0)
                {
                    {
                        Entity entity = game.CreateBulletEntity(
                            pick.Start[0], pick.Start[1], pick.Start[2],
                            toX, toY, toZ, 150);
                        game.EntityAddLocal(entity);
                    }
                }
                else
                {
                    float vX      = toX - pick.Start[0];
                    float vY      = toY - pick.Start[1];
                    float vZ      = toZ - pick.Start[2];
                    float vLength = game.Length(vX, vY, vZ);
                    vX /= vLength;
                    vY /= vLength;
                    vZ /= vLength;
                    vX *= projectilespeed;
                    vY *= projectilespeed;
                    vZ *= projectilespeed;
                    shot.ExplodesAfter = game.SerializeFloat(game.grenadetime - wait);

                    {
                        Entity grenadeEntity = new Entity();

                        Sprite sprite = new Sprite();
                        sprite.image          = "ChemicalGreen.png";
                        sprite.size           = 14;
                        sprite.animationcount = 0;
                        sprite.positionX      = pick.Start[0];
                        sprite.positionY      = pick.Start[1];
                        sprite.positionZ      = pick.Start[2];
                        grenadeEntity.sprite  = sprite;

                        Grenade_ projectile = new Grenade_();
                        projectile.velocityX    = vX;
                        projectile.velocityY    = vY;
                        projectile.velocityZ    = vZ;
                        projectile.block        = item.BlockId;
                        projectile.sourcePlayer = game.LocalPlayerId;

                        grenadeEntity.expires = Expires.Create(game.grenadetime - wait);

                        grenadeEntity.grenade = projectile;
                        game.EntityAddLocal(grenadeEntity);
                    }
                }
                Packet_Client packet = new Packet_Client();
                packet.Id   = Packet_ClientIdEnum.Shot;
                packet.Shot = shot;
                game.SendPacketClient(packet);

                if (game.blocktypes[item.BlockId].Sounds.ShootEndCount > 0)
                {
                    game.pistolcycle = game.rnd.Next() % game.blocktypes[item.BlockId].Sounds.ShootEndCount;
                    game.AudioPlay(game.platform.StringFormat("{0}.ogg", game.blocktypes[item.BlockId].Sounds.ShootEnd[game.pistolcycle]));
                }

                bulletsshot++;
                if (bulletsshot < game.DeserializeFloat(game.blocktypes[item.BlockId].BulletsPerShotFloat))
                {
                    NextBullet(game, bulletsshot);
                }

                //recoil
                game.player.position.rotx -= game.rnd.NextFloat() * game.CurrentRecoil();
                game.player.position.roty += game.rnd.NextFloat() * game.CurrentRecoil() * 2 - game.CurrentRecoil();

                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (ispistol && right)
            {
                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (pick2count.value > 0)
            {
                if (middle)
                {
                    int newtileX = game.platform.FloatToInt(pick0.Current()[0]);
                    int newtileY = game.platform.FloatToInt(pick0.Current()[1]);
                    int newtileZ = game.platform.FloatToInt(pick0.Current()[2]);
                    if (game.map.IsValidPos(newtileX, newtileZ, newtileY))
                    {
                        int  clonesource  = game.map.GetBlock(newtileX, newtileZ, newtileY);
                        int  clonesource2 = game.d_Data.WhenPlayerPlacesGetsConvertedTo()[clonesource];
                        bool gotoDone     = false;
                        //find this block in another right hand.
                        for (int i = 0; i < 10; i++)
                        {
                            if (game.d_Inventory.RightHand[i] != null &&
                                game.d_Inventory.RightHand[i].ItemClass == Packet_ItemClassEnum.Block &&
                                game.d_Inventory.RightHand[i].BlockId == clonesource2)
                            {
                                game.ActiveMaterial = i;
                                gotoDone            = true;
                            }
                        }
                        if (!gotoDone)
                        {
                            IntRef freehand = game.d_InventoryUtil.FreeHand(game.ActiveMaterial);
                            //find this block in inventory.
                            for (int i = 0; i < game.d_Inventory.ItemsCount; i++)
                            {
                                Packet_PositionItem k = game.d_Inventory.Items[i];
                                if (k == null)
                                {
                                    continue;
                                }
                                if (k.Value_.ItemClass == Packet_ItemClassEnum.Block &&
                                    k.Value_.BlockId == clonesource2)
                                {
                                    //free hand
                                    if (freehand != null)
                                    {
                                        game.WearItem(
                                            game.InventoryPositionMainArea(k.X, k.Y),
                                            game.InventoryPositionMaterialSelector(freehand.value));
                                        break;
                                    }
                                    //try to replace current slot
                                    if (game.d_Inventory.RightHand[game.ActiveMaterial] != null &&
                                        game.d_Inventory.RightHand[game.ActiveMaterial].ItemClass == Packet_ItemClassEnum.Block)
                                    {
                                        game.MoveToInventory(
                                            game.InventoryPositionMaterialSelector(game.ActiveMaterial));
                                        game.WearItem(
                                            game.InventoryPositionMainArea(k.X, k.Y),
                                            game.InventoryPositionMaterialSelector(game.ActiveMaterial));
                                    }
                                }
                            }
                        }
                        string[] sound = game.d_Data.CloneSound()[clonesource];
                        if (sound != null)            // && sound.Length > 0)
                        {
                            game.AudioPlay(sound[0]); //todo sound cycle
                        }
                    }
                }
                if (left || right)
                {
                    BlockPosSide tile = pick0;
                    int          newtileX;
                    int          newtileY;
                    int          newtileZ;
                    if (right)
                    {
                        newtileX = game.platform.FloatToInt(tile.Translated()[0]);
                        newtileY = game.platform.FloatToInt(tile.Translated()[1]);
                        newtileZ = game.platform.FloatToInt(tile.Translated()[2]);
                    }
                    else
                    {
                        newtileX = game.platform.FloatToInt(tile.Current()[0]);
                        newtileY = game.platform.FloatToInt(tile.Current()[1]);
                        newtileZ = game.platform.FloatToInt(tile.Current()[2]);
                    }
                    if (game.map.IsValidPos(newtileX, newtileZ, newtileY))
                    {
                        //Console.WriteLine(". newtile:" + newtile + " type: " + d_Map.GetBlock(newtileX, newtileZ, newtileY));
                        if (!(pick0.blockPos[0] == -1 &&
                              pick0.blockPos[1] == -1 &&
                              pick0.blockPos[2] == -1))
                        {
                            int blocktype;
                            if (left)
                            {
                                blocktype = game.map.GetBlock(newtileX, newtileZ, newtileY);
                            }
                            else
                            {
                                blocktype = ((game.BlockInHand() == null) ? 1 : game.BlockInHand().value);
                            }
                            if (left && blocktype == game.d_Data.BlockIdAdminium())
                            {
                                PickingEnd(left, right, middle, ispistol);
                                return;
                            }
                            string[] sound = left ? game.d_Data.BreakSound()[blocktype] : game.d_Data.BuildSound()[blocktype];
                            if (sound != null)            // && sound.Length > 0)
                            {
                                game.AudioPlay(sound[0]); //todo sound cycle
                            }
                        }
                        //normal attack
                        if (!right)
                        {
                            //attack
                            int posx = newtileX;
                            int posy = newtileZ;
                            int posz = newtileY;
                            game.currentAttackedBlock = Vector3IntRef.Create(posx, posy, posz);
                            if (!game.blockHealth.ContainsKey(posx, posy, posz))
                            {
                                game.blockHealth.Set(posx, posy, posz, game.GetCurrentBlockHealth(posx, posy, posz));
                            }
                            game.blockHealth.Set(posx, posy, posz, game.blockHealth.Get(posx, posy, posz) - game.WeaponAttackStrength());
                            float health = game.GetCurrentBlockHealth(posx, posy, posz);
                            if (health <= 0)
                            {
                                if (game.currentAttackedBlock != null)
                                {
                                    game.blockHealth.Remove(posx, posy, posz);
                                }
                                game.currentAttackedBlock = null;
                                OnPick(game, game.platform.FloatToInt(newtileX), game.platform.FloatToInt(newtileZ), game.platform.FloatToInt(newtileY),
                                       game.platform.FloatToInt(tile.Current()[0]), game.platform.FloatToInt(tile.Current()[2]), game.platform.FloatToInt(tile.Current()[1]),
                                       tile.collisionPos,
                                       right);
                            }
                            PickingEnd(left, right, middle, ispistol);
                            return;
                        }
                        if (!right)
                        {
                            game.particleEffectBlockBreak.StartParticleEffect(newtileX, newtileY, newtileZ);//must be before deletion - gets ground type.
                        }
                        if (!game.map.IsValidPos(newtileX, newtileZ, newtileY))
                        {
                            game.platform.ThrowException("Error in picking - NextBullet()");
                        }
                        OnPick(game, game.platform.FloatToInt(newtileX), game.platform.FloatToInt(newtileZ), game.platform.FloatToInt(newtileY),
                               game.platform.FloatToInt(tile.Current()[0]), game.platform.FloatToInt(tile.Current()[2]), game.platform.FloatToInt(tile.Current()[1]),
                               tile.collisionPos,
                               right);
                        //network.SendSetBlock(new Vector3((int)newtile.X, (int)newtile.Z, (int)newtile.Y),
                        //    right ? BlockSetMode.Create : BlockSetMode.Destroy, (byte)MaterialSlots[activematerial]);
                    }
                }
            }
        }
        PickingEnd(left, right, middle, ispistol);
    }
예제 #24
0
        /// <summary>
        /// Performs a ray/mesh intersection with the depth map
        /// </summary>
        /// <param name="kinectCalibration">Defines the calibration (extrinsics and intrinsics) for the Kinect</param>
        /// <param name="line">Ray to intersect against depth map</param>
        /// <param name="depthImage">Depth map to ray cast against</param>
        /// <param name="skipFactor">Distance to march on each step along ray</param>
        /// <param name="undistort">Should undistortion be applied to the point?</param>
        /// <returns>Returns point of intersection</returns>
        internal static Point3D?IntersectLineWithDepthMesh(IKinectCalibration kinectCalibration, Line3D line, Image depthImage, double skipFactor, bool undistort = true)
        {
            // max distance to check for intersection with the scene
            double totalDistance = 5;
            var    delta         = skipFactor * (line.EndPoint - line.StartPoint).Normalize();

            // size of increment along the ray
            int maxSteps        = (int)(totalDistance / delta.Length);
            var hypothesisPoint = line.StartPoint;

            for (int i = 0; i < maxSteps; i++)
            {
                hypothesisPoint += delta;

                // get the mesh distance at the extended point
                float meshDistance = DepthExtensions.GetMeshDepthAtPoint(kinectCalibration, depthImage, hypothesisPoint, undistort);

                // if the mesh distance is less than the distance to the point we've hit the mesh
                if (!float.IsNaN(meshDistance) && (meshDistance < hypothesisPoint.Z))
                {
                    return(hypothesisPoint);
                }
            }

            return(null);
        }
        //mxd
        protected void RenderGuidelines(Vector2D start, Vector2D end, PixelColor c, double angle)
        {
            start = start.GetRotated(angle);
            end   = end.GetRotated(angle);

            if (end.x != start.x && end.y != start.y)
            {
                Vector2D tr = new Vector2D(Math.Max(end.x, start.x), Math.Max(end.y, start.y));
                Vector2D bl = new Vector2D(Math.Min(end.x, start.x), Math.Min(end.y, start.y));

                // Create guidelines
                Line3D[] lines = new Line3D[5];
                lines[0] = new Line3D(new Vector2D(tr.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(tr.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                lines[1] = new Line3D(new Vector2D(bl.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(bl.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                lines[2] = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, tr.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, tr.y).GetRotated(-angle), c, false);
                lines[3] = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, bl.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, bl.y).GetRotated(-angle), c, false);

                // Create current line extent. Make sure v1 is to the left of v2
                Line2D current = (end.x < start.x ? new Line2D(end, start) : new Line2D(start, end));

                Vector2D extentstart, extentend;
                if (current.v1.y < current.v2.y)                // Start is lower
                {
                    // Start point can hit left or bottom boundaries
                    extentstart = Line2D.GetIntersectionPoint(left, current, false);
                    if (extentstart.y < General.Map.Config.BottomBoundary)
                    {
                        extentstart = Line2D.GetIntersectionPoint(bottom, current, false);
                    }

                    // End point can hit right or top boundaries
                    extentend = Line2D.GetIntersectionPoint(right, current, false);
                    if (extentend.y > General.Map.Config.TopBoundary)
                    {
                        extentend = Line2D.GetIntersectionPoint(top, current, false);
                    }
                }
                else                 // Start is higher
                {
                    // Start point can hit left or top boundaries
                    extentstart = Line2D.GetIntersectionPoint(left, current, false);
                    if (extentstart.y > General.Map.Config.TopBoundary)
                    {
                        extentstart = Line2D.GetIntersectionPoint(top, current, false);
                    }

                    // End point can hit right or bottom boundaries
                    extentend = Line2D.GetIntersectionPoint(right, current, false);
                    if (extentend.y < General.Map.Config.BottomBoundary)
                    {
                        extentend = Line2D.GetIntersectionPoint(bottom, current, false);
                    }
                }

                lines[4] = new Line3D(extentstart.GetRotated(-angle), extentend.GetRotated(-angle), c, false);

                // Render them
                renderer.RenderArrows(lines);

                // Update horiz/vert length labels
                if (guidelabels != null)
                {
                    guidelabels[0].Move(tr.GetRotated(-angle), new Vector2D(tr.x, bl.y).GetRotated(-angle));
                    guidelabels[1].Move(new Vector2D(bl.x, tr.y).GetRotated(-angle), tr.GetRotated(-angle));
                    guidelabels[2].Move(new Vector2D(tr.x, bl.y).GetRotated(-angle), bl.GetRotated(-angle));
                    guidelabels[3].Move(bl.GetRotated(-angle), new Vector2D(bl.x, tr.y).GetRotated(-angle));
                }
            }
            // Render horizontal line + 2 vertical guidelines
            else if (end.x != start.x)
            {
                Line3D l  = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, end.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, end.y).GetRotated(-angle), c, false);
                Line3D gs = new Line3D(new Vector2D(start.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(start.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                Line3D ge = new Line3D(new Vector2D(end.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(end.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                renderer.RenderArrows(new List <Line3D> {
                    l, gs, ge
                });
            }
            // Render vertical line + 2 horizontal guidelines
            else if (end.y != start.y)
            {
                Line3D l  = new Line3D(new Vector2D(end.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(end.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                Line3D gs = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, start.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, start.y).GetRotated(-angle), c, false);
                Line3D ge = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, end.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, end.y).GetRotated(-angle), c, false);
                renderer.RenderArrows(new List <Line3D> {
                    l, gs, ge
                });
            }
            // Start and end match. Render a cross
            else
            {
                Line3D gs = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, start.y).GetRotated(-angle), new Vector2D(General.Map.Config.RightBoundary, start.y).GetRotated(-angle), c, false);
                Line3D ge = new Line3D(new Vector2D(start.x, General.Map.Config.TopBoundary).GetRotated(-angle), new Vector2D(start.x, General.Map.Config.BottomBoundary).GetRotated(-angle), c, false);
                renderer.RenderArrows(new List <Line3D> {
                    gs, ge
                });
            }
        }
예제 #26
0
        /// <summary>
        /// Aligns the solution using the specified planets
        /// </summary>
        /// <remarks>WARNING!!! 3D MATH!!!</remarks>
        /// <param name="alignment">The planets to align using.</param>
        /// <param name="planetLocations">The planet location data.</param>
        private void FlattenAlignment(string[] alignment, Dictionary <string, PlanetInfo> planetLocations)
        {
            // ** STEP ONE **
            // Translate everything such that the first alignment planet is at { 0, 0, 0 }
            Vector3D offset = planetLocations[alignment[0]].Location;

            if (offset.Length > 0)
            {
                foreach (PlanetInfo curInfo in planetLocations.Values)
                {
                    curInfo.Location -= offset;
                }
            }

            // ** STEP TWO **
            // Rotate everything such that the second alignment planet is on the x-axis (without translating the previous alignment planets)
            Vector3D xAxis = new Vector3D(1, 0, 0);

            Angle    angle        = planetLocations[alignment[1]].Location.AngleTo(xAxis);
            Vector3D rotationAxis = xAxis.CrossProduct(planetLocations[alignment[1]].Location);

            if (rotationAxis.Length > 0)
            {
                rotationAxis = rotationAxis.Normalize().ToVector3D();

                foreach (PlanetInfo curInfo in planetLocations.Values)
                {
                    curInfo.Location = curInfo.Location.Rotate(rotationAxis, -angle);
                }
            }

            // ** STEP THREE **
            // Rotate everything such that the third alignment planet is on the x/y-plane (without translating the previous alignment planets)
            Point3D planetOne   = planetLocations[alignment[0]].Location.ToPoint3D();
            Point3D planetTwo   = planetLocations[alignment[1]].Location.ToPoint3D();
            Point3D planetThree = planetLocations[alignment[2]].Location.ToPoint3D();

            Line3D oneTwoLine  = new Line3D(planetOne, planetTwo);
            Line3D lineToThird = oneTwoLine.LineTo(planetThree, false);

            Vector3D vectorToThird = (lineToThird.EndPoint - lineToThird.StartPoint);
            Vector3D destLine      = new Vector3D(vectorToThird.Y < 0 ? -vectorToThird.X : vectorToThird.X, vectorToThird.Y < 0 ? -vectorToThird.Y : vectorToThird.Y, 0);

            angle        = destLine.AngleTo(vectorToThird);
            rotationAxis = destLine.CrossProduct(vectorToThird);

            if (rotationAxis.Length > 0)
            {
                rotationAxis = rotationAxis.Normalize().ToVector3D();

                foreach (PlanetInfo curInfo in planetLocations.Values)
                {
                    curInfo.Location = curInfo.Location.Rotate(rotationAxis, -angle);
                }
            }

            // ** STEP FOUR **
            // Invert the Z coordinates of all planets to ensure the first non-aligned planet has a positive Z location
            if (planetLocations.Values.First(cur => !alignment.Contains(cur.Name)).Location.Z < 0)
            {
                foreach (PlanetInfo curInfo in planetLocations.Values)
                {
                    curInfo.Location = new Vector3D(curInfo.Location.X, curInfo.Location.Y, -curInfo.Location.Z);
                }
            }

            // Just double check the alignment worked...
            foreach (string curAlignment in alignment)
            {
                if (Math.Round(planetLocations[curAlignment].Location.Z, 4) != 0)
                {
                    throw new Exception("Alignment Failed!!!");
                }
            }
        }
예제 #27
0
        public void CanGetPoint()
        {
            var line = new Line3D(new Point3D(2, 3, 1), new Vector3(2, 1, 2));

            Assert.AreEqual(new Point3D(6, 5, 5), line.GetPoint(2));
        }
        //mxd
        protected void AlignTextureToClosestLine(bool alignx, bool aligny)
        {
            if (!(mode.HighlightedObject is BaseVisualSector))
            {
                return;
            }

            // Do we need to align this? (and also grab texture scale while we are at it)
            float scaleX, scaleY;
            bool  isFloor = (geometrytype == VisualGeometryType.FLOOR);

            if (mode.HighlightedTarget is VisualFloor)
            {
                Sector      target;
                VisualFloor vf = (VisualFloor)mode.HighlightedTarget;

                // Use the control sector if the floor belongs to a 3D floor
                if (vf.ExtraFloor == null)
                {
                    target = vf.Sector.Sector;
                }
                else
                {
                    target = vf.GetControlSector();
                }

                // Check texture
                if (target.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscalefloor", 1.0f);
                scaleY = target.Fields.GetValue("yscalefloor", 1.0f);
            }
            else
            {
                Sector        target;
                VisualCeiling vc = (VisualCeiling)mode.HighlightedTarget;

                // Use the control sector if the ceiling belongs to a 3D floor
                if (vc.ExtraFloor == null)
                {
                    target = vc.Sector.Sector;
                }
                else
                {
                    target = vc.GetControlSector();
                }

                // Check texture
                if (target.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscaleceiling", 1.0f);
                scaleY = target.Fields.GetValue("yscaleceiling", 1.0f);
            }

            //find a linedef to align to
            Vector2D hitpos = mode.GetHitPosition();

            if (!hitpos.IsFinite())
            {
                return;
            }

            //align to line of highlighted sector, which is closest to hitpos
            Sector         highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector;
            List <Linedef> lines             = new List <Linedef>();

            foreach (Sidedef side in highlightedSector.Sidedefs)
            {
                lines.Add(side.Line);
            }

            Linedef targetLine = MapSet.NearestLinedef(lines, hitpos);

            if (targetLine == null)
            {
                return;
            }

            bool isFront = targetLine.SideOfLine(hitpos) > 0;

            Sector.Sector.Fields.BeforeFieldsChange();

            //find an angle to rotate texture
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);

            if (!isFront)
            {
                sourceAngle = General.ClampAngle(sourceAngle + 180);
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            // Scale texture if it's a slope and the appropriate option is set
            if (level.plane.Normal.z != 1.0f && BuilderPlug.Me.ScaleTexturesOnSlopes != 2)
            {
                Vector2D basescale = new Vector2D(1.0f, 1.0f);

                // User wants to use the current scale as a base?
                if (BuilderPlug.Me.ScaleTexturesOnSlopes == 1)
                {
                    basescale.x = scaleX;
                    basescale.y = scaleY;
                }

                // Create a unit vector of the direction of the target line in 3D space
                Vector3D targetlinevector = new Line3D(new Vector3D(targetLine.Start.Position, level.plane.GetZ(targetLine.Start.Position)), new Vector3D(targetLine.End.Position, level.plane.GetZ(targetLine.End.Position))).GetDelta().GetNormal();

                // Get a perpendicular vector of the target line in 3D space. This is used to get the slope angle relative to the target line
                Vector3D targetlineperpendicular = Vector3D.CrossProduct(targetlinevector, level.plane.Normal);

                if (alignx)
                {
                    scaleX = Math.Abs(basescale.x * (1.0f / (float)Math.Cos(targetlinevector.GetAngleZ())));
                }

                if (aligny)
                {
                    scaleY = Math.Abs(basescale.y * (1.0f / (float)Math.Cos(targetlineperpendicular.GetAngleZ())));
                }
            }

            //set scale
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f);
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f);

            //update offset
            float    distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
            float    distToEnd   = Vector2D.Distance(hitpos, targetLine.End.Position);
            Vector2D offset      = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
예제 #29
0
 /// <summary>
 /// states if given wcs segment is contained in this plane
 /// </summary>
 public bool Contains(double tol, Line3D line)
 {
     return(Contains(tol, line.From) && Contains(tol, line.To));
 }
예제 #30
0
 /// <summary>
 /// Returns an intersection with a 3d line.
 /// </summary>
 /// <param name="line">Line to intersect with.</param>
 /// <param name="outIntersection">Place to store the intersection point, if there is one.</param>
 /// <returns>Returns true if there was an intersection, false if there was not.</returns>
 public bool GetIntersectionWithLimitedLine(Line3D line, out Vector3D outIntersection)
 {
     return GetIntersectionWithLine(line.Start, line.Vector, out outIntersection) &&
            outIntersection.IsBetweenPoints(line.Start, line.End);
 }
예제 #31
0
        /// <summary>
        /// states if the given polygon contains the test point ( z not considered )
        /// https://en.wikipedia.org/wiki/Point_in_polygon
        /// By default check the point contained in the polygon perimeter.
        /// Optionally duplicate points are zapped in comparing.
        /// </summary>
        public static bool ContainsPoint(this IReadOnlyList <Vector3D> _pts, double tol, Vector3D _pt, bool zapDuplicates = false)
        {
            var pt          = _pt.Set(OrdIdx.Z, 0);
            var pts         = _pts.Select(w => w.Set(OrdIdx.Z, 0));
            var ptHs        = new HashSet <Vector3D>(new Vector3DEqualityComparer(tol));
            var ptsFiltered = pts;

            var pts_bbox = _pts.BBox();

            if (!pts_bbox.Contains2D(tol, _pt))
            {
                return(false);
            }

            if (zapDuplicates)
            {
                var tmp = new List <Vector3D>();
                foreach (var p in pts)
                {
                    if (!ptHs.Contains(p))
                    {
                        ptHs.Add(p);
                        tmp.Add(p);
                    }
                }
                ptsFiltered = tmp;
            }
            var segs = ptsFiltered.PolygonSegments(tol);

            if (_pts.Any(w => _pt.EqualsTol(tol, w)))
            {
                return(true);
            }

            var ray            = new Line3D(pt, Vector3D.XAxis, Line3DConstructMode.PointAndVector);
            var conflictVertex = false;

            do
            {
                conflictVertex = false;
                foreach (var pp in ptsFiltered)
                {
                    if (ray.LineContainsPoint(tol, pp))
                    {
                        conflictVertex = true;
                        // ray intersect vertex, change it
                        ray = new Line3D(pt, pp + Vector3D.YAxis * tol * 1.1);
                        break;
                    }
                }
            }while (conflictVertex);

            var intCnt = 0;

            foreach (var seg in segs)
            {
                if (seg.SegmentContainsPoint(tol, pt))
                {
                    return(true);
                }

                Vector3D ip = null;

                ip = ray.Intersect(tol, seg);
                if (ip != null && seg.SegmentContainsPoint(tol, ip))
                {
                    if (pt.X.GreatThanOrEqualsTol(tol, ip.X))
                    {
                        ++intCnt;
                    }
                }
            }

            return(intCnt % 2 != 0);
        }
        public Vector<double> Solve(List<double[]> Vertices, List<int[]> Triangles, List<int> IndiceOfFixedPoints, Point3D oRoot, UnitVector3D vDir1, UnitVector3D vDir2)
        {
            Vector<double> Solution = Vector<double>.Build.Dense(Triangles.Count * 3);

            List<List<int[]>> Wheels = new List<List<int[]>>();
            for (int i = 0; i < Vertices.Count; i++) {
                List<int> TrianglesWithThisVertice = new List<int>();
                for (int t = 0; t < Triangles.Count; t++) {
                    if (Triangles[t][0] == i || Triangles[t][1] == i || Triangles[t][2] == i) TrianglesWithThisVertice.Add(t);
                }
                int[] SheredEdge = new int[] { 0, 0 };
                int Last = 0;
                int Firt = 0;
                if (Triangles[TrianglesWithThisVertice[0]][0] == i) { SheredEdge = new int[] {i, Triangles[TrianglesWithThisVertice[0]][1] }; }
                else if( Triangles[TrianglesWithThisVertice[0]][1] == i) { SheredEdge = new int[] {i, Triangles[TrianglesWithThisVertice[0]][2] }; }
                else if (Triangles[TrianglesWithThisVertice[0]][2] == i) { SheredEdge = new int[] { i, Triangles[TrianglesWithThisVertice[0]][0] }; }
                List<int[]> WheelEdges = new List<int[]>();
                WheelEdges.Add(SheredEdge);
                do {
                    int found=-1 ;
                    for (int t = 0; t < TrianglesWithThisVertice.Count; t++) {
                        if (t != Last) {
                            if (SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][0]) && SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][1])) {
                                SheredEdge = new int[] { i, Triangles[TrianglesWithThisVertice[t]][2] }; found = t;
                            } else if (SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][1]) && SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][2])) {
                                SheredEdge = new int[] { i, Triangles[TrianglesWithThisVertice[t]][0] }; found = t;
                            } else if (SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][0]) && SheredEdge.Contains(Triangles[TrianglesWithThisVertice[t]][2])) {
                                SheredEdge = new int[] { i, Triangles[TrianglesWithThisVertice[t]][1] }; found = t;
                            }
                        }
                    }
                    if (found != -1) {
                        Last = found;
                        if (Last == Firt) goto ClosedWeel;
                        WheelEdges.Add(SheredEdge);
                    } else goto Continue;
                } while (true);
                ClosedWeel:
                Wheels.Add(WheelEdges);
                Continue:
                continue;
            }

            Matrix <double> StiffMatrix = Matrix<double>.Build.Dense(Vertices.Count+ Triangles.Count+ Wheels.Count, Triangles.Count * 3);

            //Vertex consistency ∑ei = 2π −∑αi
            Vector<double> VertexConsistency = Vector<double>.Build.Dense(Vertices.Count + Triangles.Count + Wheels.Count);
            for (int i = 0; i < Vertices.Count; i++) {
                Point3D CurrentVertex = new Point3D(Vertices[i]);
                List<double> Angles = new List<double>();
                foreach (int[] t in Triangles) {
                    int i1 = -1, i2 = 0, i0 = 0;
                    if (t[0] == i) { i1 = 0; } else if (t[1] == i) { i1 = 1; } else if (t[2] == i) { i1 = 2; }
                    if (i1 != -1) {
                        i2 = i1 + 1;
                        if (i2 == 3) i2 = 0;
                        i0 = i1 - 1;
                        if (i0 == -1) i0 = 2;
                        Point3D vd0, vd1, vd2;
                        vd0 = new Point3D(Vertices[t[i0]]);
                        vd1 = new Point3D(Vertices[t[i1]]);
                        vd2 = new Point3D(Vertices[t[i2]]);

                        Line3D lU, lD;
                        lU = new Line3D(vd1, vd0);
                        lD = new Line3D(vd1, vd2);
                        Angles.Add(lD.Direction.AngleTo(lU.Direction).Radians);
                    }
                }
                VertexConsistency[i] = 2 * Math.PI - Angles.Sum();
            }

            //Triangle Consistency eα +eβ +eγ = π − (α + β + γ)
            Vector<double> TriangleConsistency = Vector<double>.Build.Dense(Vertices.Count + Triangles.Count + Wheels.Count);
            for (int t = 0; t < Triangles.Count; t++) {
                double[] Angles = new double[] { 0, 0, 0 };
                for (int i = 0; i < 3; i++) {
                    int i1 = i, i2 = 0, i0 = 0;
                    i2 = i1 + 1;
                    if (i2 == 3) i2 = 0;
                    i0 = i1 - 1;
                    if (i0 == -1) i0 = 2;
                    Point3D vd0, vd1, vd2;
                    vd0 = new Point3D(Vertices[Triangles[t][i0]]);
                    vd1 = new Point3D(Vertices[Triangles[t][i1]]);
                    vd2 = new Point3D(Vertices[Triangles[t][i2]]);

                    Line3D lU, lD;
                    lU = new Line3D(vd1, vd0);
                    lD = new Line3D(vd1, vd2);
                    Angles[i] = lD.Direction.AngleTo(lU.Direction).Radians;
                    StiffMatrix[Vertices.Count + t, t * 3 + i] = 1;
                }
                TriangleConsistency[Vertices.Count + t] = Math.PI - Angles.Sum();
            }

            //Wheel Consistency ∑cot(βi) eβi − cot(γi) eγi =∑log(sinγi) − log(sinβi)
            Vector<double> WheelConsistency = Vector<double>.Build.Dense(Vertices.Count + Triangles.Count + Wheels.Count);
            for (int t = 0; t < Wheels.Count; t++) {
                double cotβi = 0;
                double cotγi = 0;
                double logSinβi = 0;
                double logSinγi = 0;
                double[] Angles = new double[] { 0, 0, 0 };
                for (int i = 0; i < Wheels[t].Count; i++) {
                    Point3D vd0, vd1, vd2;
                    vd0 = new Point3D(Vertices[Wheels[t][i][0]]);
                    vd1 = new Point3D(Vertices[Wheels[t][i][1]]);
                    int other = i + 1;
                    if (other == Wheels[t].Count) other = 0;
                    vd2 = new Point3D(Vertices[Wheels[t][other][1]]);

                    Line3D lV1, lV2, lOp;
                    lV1 = new Line3D(vd0, vd1);
                    lV2 = new Line3D(vd0, vd2);
                    lOp = new Line3D(vd1, vd2);
                    cotβi += Acot(Math.Abs(lV2.Direction.AngleTo(lOp.Direction).Radians));
                    cotγi += Acot(Math.Abs(lV1.Direction.AngleTo(lOp.Direction).Radians));

                    logSinβi += Math.Log(Math.Sin(Math.Abs(lV2.Direction.AngleTo(lOp.Direction).Radians)));
                    logSinγi += Math.Log(Math.Sin(Math.Abs(lV1.Direction.AngleTo(lOp.Direction).Radians)));

                    StiffMatrix[Vertices.Count + t, t * 3 + i] = 1;
                }
                TriangleConsistency[Vertices.Count + t] = Math.PI - Angles.Sum();
            }

            double[,] MatrixA = new double[Vertices.Count * 2, Vertices.Count * 2];

            for (int i = 0; i < Vertices.Count; i++) {
                int[] CurTri = new int[] { 0, 0, 0 };
                int indexDown0 = -1;
                foreach (int[] t in Triangles) {
                    for (int j = 0; j < 3; j++) {
                        if (t[j] == i) { indexDown0 = j; break; }
                    }
                    if (indexDown0 != -1) { CurTri = t; break; }
                }
                int indexDown1 = indexDown0 - 1;
                if (indexDown1 < 0) indexDown1 = 2;
                int indexDown2 = indexDown1 - 1;
                if (indexDown2 < 0) indexDown2 = 2;

                Point3D vd0, vd1, vd2;
                vd0 = new Point3D(Vertices[CurTri[indexDown0]]);
                vd1 = new Point3D(Vertices[CurTri[indexDown1]]);
                vd2 = new Point3D(Vertices[CurTri[indexDown2]]);

                Line3D lU, lD;
                lU = new Line3D(vd1, vd0);
                lD = new Line3D(vd1, vd2);

                double Ang = -lU.Direction.AngleTo(lD.Direction).Radians;
                double Len = lD.Length / lU.Length;

                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown0] * 2] = 1;
                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown0] * 2 + 1] = 0;

                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown1] * 2] = -Len * Math.Cos(Ang);
                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown1] * 2 + 1] = Len * Math.Sin(Ang);

                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown2] * 2] = Len * Math.Cos(Ang) - 1;
                MatrixA[CurTri[indexDown0] * 2, CurTri[indexDown2] * 2 + 1] = -Len * Math.Sin(Ang);

                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown0] * 2] = 0;
                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown0] * 2 + 1] = 1;

                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown1] * 2] = -Len * Math.Sin(Ang);
                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown1] * 2 + 1] = -Len * Math.Cos(Ang);

                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown2] * 2] = Len * Math.Sin(Ang);
                MatrixA[CurTri[indexDown0] * 2 + 1, CurTri[indexDown2] * 2 + 1] = Len * Math.Cos(Ang) - 1;
            }

            double[,] MatrixCa = new double[IndiceOfFixedPoints.Count * 2, Vertices.Count * 2];
            double[] VectorR = new double[IndiceOfFixedPoints.Count * 2];

            Plane oPlane = new Plane(vDir1.CrossProduct(vDir2), oRoot);

            for (int i = 0; i < IndiceOfFixedPoints.Count; i++) {
                MatrixCa[i * 2, IndiceOfFixedPoints[i] * 2] = 1;
                VectorR[i * 2] = new Point3D(Vertices[IndiceOfFixedPoints[i]]).ProjectOn(oPlane).X;
                MatrixCa[i * 2 + 1, IndiceOfFixedPoints[i] * 2 + 1] = 1;
                VectorR[i * 2 + 1] = new Point3D(Vertices[IndiceOfFixedPoints[i]]).ProjectOn(oPlane).Y;
            }

            Matrix<double> Ca = Matrix<double>.Build.DenseOfArray(MatrixCa);
            Console.WriteLine(Ca);
            Vector<double> R = Vector<double>.Build.DenseOfArray(VectorR);
            Console.WriteLine(R);
            Matrix<double> A = Matrix<double>.Build.DenseOfArray(MatrixA);
            Console.WriteLine(A);
            double Penalty = 1000;

            Matrix<double> Ak = A.Transpose() * A + Penalty * Ca.Transpose() * Ca;
            Console.WriteLine(Ak);
            Vector<double> X = Ak.Solve(Penalty * Ca.Transpose() * R);
            Console.WriteLine(X);
            return X;
        }
예제 #33
0
 public void ProjectOn(string p1s, string p2s, string pls, string ep1s, string ep2s)
 {
     var p1 = Point3D.Parse(p1s);
     var p2 = Point3D.Parse(p2s);
     var line = new Line3D(p1, p2);
     var plane = Plane.Parse(pls);
     var expected = new Line3D(Point3D.Parse(ep1s), Point3D.Parse(ep2s));
     AssertGeometry.AreEqual(expected, line.ProjectOn(plane));
 }
예제 #34
0
 public static float DistanceSquaredToLine(vec3 p, vec3 e0, vec3 e1)
 {
     return(Line3D.DistanceSquared(p, e0, e1));
 }
예제 #35
0
 public static Line3D LongestLineBetweenCoords(vector_Coord3D tab, ref int startIndex, ref int endIndex) {
   Line3D ret = new Line3D(VisionLabPINVOKE.LongestLineBetweenCoords__SWIG_2(vector_Coord3D.getCPtr(tab), ref startIndex, ref endIndex), true);
   if (VisionLabPINVOKE.SWIGPendingException.Pending) throw VisionLabPINVOKE.SWIGPendingException.Retrieve();
   return ret;
 }
예제 #36
0
 public static vec3 ClosestPointOnLine(vec3 p, vec3 e0, vec3 e1)
 {
     return(Line3D.ClosestPoint(p, e0, e1));
 }
예제 #37
0
        /// <summary>
        /// 开始查找
        /// </summary>
        /// <returns></returns>
        public List <Line3D> Find()
        {
            List <Line3D> result = new List <Line3D>();


            //将所有的线段投影到XYZ平面
            List <Line2D> line2ds = new List <Line2D>();

            //获取线段的标高信息
            this.Elevation = SearchLines.First().Start.Z;
            //首先投影所有线段
            SearchLines.ForEach(x =>
            {
                if (!x.Start.Z.AreEqual(this.Elevation) || !x.End.Z.AreEqual(this.Elevation))
                {
                    result = null;
                }
                Vector2D start = new Vector2D(x.Start.X, x.Start.Y);
                Vector2D end   = new Vector2D(x.End.X, x.End.Y);
                Line2D line2d  = Line2D.Create(start, end);
                line2ds.Add(line2d);
            });



            if (result == null)
            {
                //说明直线高度不一致
                throw new Exception("给的线段高度不一致");
            }


            List <Line2D> remainingLines = null;

            if (IsDecompose)
            {
                //对当前的线段进行打断
                remainingLines = line2ds.Decompose();
            }
            else
            {
                remainingLines = new List <Line2D>(line2ds);
            }


            //首先要移除独立的线,不和其他线供端点,或者只公用一个端点



            //获取最近点坐标
            Vector2D origin = null;

            //返回所有最靠近原点的店
            List <Line2D> huntLines = this.GetHuntWithOrigin(out origin, remainingLines);

            //所有的外框线
            List <Line2D> outerLines = new List <Line2D>();

            //获取起点的墙体
            this.FindOuterLinessWithAngle(remainingLines, huntLines, outerLines, origin);


            if (outerLines != null)
            {
                outerLines.ForEach(x =>
                {
                    Line3D line3d = new Line3D(Vector3D.Create(x.Start.X, x.Start.Y, Elevation), Vector3D.Create(x.End.X, x.End.Y, Elevation));
                    result.Add(line3d);
                });
            }

            return(result);
        }
예제 #38
0
 public static float DistanceToLine(vec3 p, vec3 e0, vec3 e1, out float t)
 {
     return(Line3D.Distance(p, e0, e1, out t));
 }
예제 #39
0
 public BlockPosSide[] Pick(BlockOctreeSearcher s_, Line3D line, IntRef retCount)
 {
     //pick terrain
     int minX = platform.FloatToInt(MathCi.MinFloat(line.Start[0], line.End[0]));
     int minY = platform.FloatToInt(MathCi.MinFloat(line.Start[1], line.End[1]));
     int minZ = platform.FloatToInt(MathCi.MinFloat(line.Start[2], line.End[2]));
     if (minX < 0) { minX = 0; }
     if (minY < 0) { minY = 0; }
     if (minZ < 0) { minZ = 0; }
     int maxX = platform.FloatToInt(MathCi.MaxFloat(line.Start[0], line.End[0]));
     int maxY = platform.FloatToInt(MathCi.MaxFloat(line.Start[1], line.End[1]));
     int maxZ = platform.FloatToInt(MathCi.MaxFloat(line.Start[2], line.End[2]));
     if (maxX > map.MapSizeX) { maxX = map.MapSizeX; }
     if (maxY > map.MapSizeZ) { maxY = map.MapSizeZ; }
     if (maxZ > map.MapSizeY) { maxZ = map.MapSizeY; }
     int sizex = maxX - minX + 1;
     int sizey = maxY - minY + 1;
     int sizez = maxZ - minZ + 1;
     int size = BitTools.NextPowerOfTwo(MathCi.MaxInt(sizex, MathCi.MaxInt(sizey, sizez)));
     s_.StartBox = Box3D.Create(minX, minY, minZ, size);
     //s_.StartBox = Box3D.Create(0, 0, 0, BitTools.NextPowerOfTwo(MaxInt(MapSizeX, MaxInt(MapSizeY, MapSizeZ))));
     BlockPosSide[] pick2 = s_.LineIntersection(IsBlockEmpty_.Create(this), GetBlockHeight_.Create(this), line, retCount);
     PickSort(pick2, retCount.value, line.Start[0], line.Start[1], line.Start[2]);
     return pick2;
 }
예제 #40
0
 public FaceIntersectionLineResult(Geom_Curve curve, Line3D intersectionLine)
 {
     Curve            = curve;
     IntersectionLine = intersectionLine;
 }
예제 #41
0
 /// <summary>
 /// Berechnet den Schnittpunkt zweier Geraden.
 /// </summary>
 /// <returns></returns>
 public Point3D IntersectionWith(Line3D other)
 {
     double f1, f2;
     if (IntersectsInner(other, out f1, out f2))
         return GetPoint(f1);
     else
         throw new InvalidOperationException("Diese beiden Geraden schneiden sich nicht.");
 }
예제 #42
0
 public static TopoDS_Face FromEdges(Line3D line1, Line3D line2)
 {
     return(BRepFill.Face(
                new BRepBuilderAPI_MakeEdge(line1.From.gp_Pnt(), line1.To.gp_Pnt()).Edge(),
                new BRepBuilderAPI_MakeEdge(line2.From.gp_Pnt(), line2.To.gp_Pnt()).Edge()));
 }
예제 #43
0
        public void run()
        {
            /* At first, we let the user select the driver type,
             * then start up the engine, set a caption, and get a
             * pointer to the video driver.
             */

            // ask user for driver
            DriverType driverType;

            // Ask user to select driver:
            StringBuilder sb = new StringBuilder();

            sb.Append("Please select the driver you want for this example:\n");
            sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5");
            sb.Append("\n(d) Software Renderer\n(e) Apfelbaum Software Renderer");
            sb.Append("\n(f) Null Device\n(otherKey) exit\n\n");

            // Get the user's input:
            TextReader tIn  = Console.In;
            TextWriter tOut = Console.Out;

            tOut.Write(sb.ToString());
            string input = tIn.ReadLine();

            // Select device based on user's input:
            switch (input)
            {
            case "a":
                driverType = DriverType.DIRECT3D9;
                break;

            case "b":
                driverType = DriverType.DIRECT3D8;
                break;

            case "c":
                driverType = DriverType.OPENGL;
                break;

            case "d":
                driverType = DriverType.SOFTWARE;
                break;

            case "e":
                driverType = DriverType.SOFTWARE2;
                break;

            case "f":
                driverType = DriverType.NULL_DRIVER;
                break;

            default:
                return;
            }

            // Create device and exit if creation fails:
            device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, false, true, true);

            if (device == null)
            {
                tOut.Write("Device creation failed.");
                return;
            }

            /*
             * Get a pointer to the video driver and the SceneManager so that
             * we do not always have to write device->getVideoDriver() and
             * device->getSceneManager().
             */

            ISceneManager smgr   = device.SceneManager;
            IVideoDriver  driver = device.VideoDriver;

            device.FileSystem.AddZipFileArchive(path + "map-20kdm2.pk3");

            IAnimatedMesh q3levelmesh = smgr.GetMesh("20kdm2.bsp");
            ISceneNode    q3node      = null;

            if (q3levelmesh != null)
            {
                q3node = smgr.AddOctTreeSceneNode(q3levelmesh.GetMesh(0), null, 0);
            }

            /*So far so good, we've loaded the quake 3 level like in tutorial 2.
            *  Now, here comes something different: We create a triangle selector. A
            *  triangle selector is a class which can fetch the triangles from scene
            *  nodes for doing different things with them, for example collision
            *  detection. There are different triangle selectors, and all can be
            *  created with the ISceneManager. In this example, we create an
            *  OctTreeTriangleSelector, which optimizes the triangle output a little
            *  bit by reducing it like an octree. This is very useful for huge meshes
            *  like quake 3 levels.
            *  After we created the triangle selector, we attach it to the q3node.
            *  This is not necessary, but in this way, we do not need to care for the
            *  selector, for example dropping it after we do not need it anymore.*/

            ITriangleSelector selector = null;

            if (q3node != null)
            {
                q3node.Position = new Vector3D(-1370, -130, -1400);
                selector        = smgr.CreateOctTreeTriangleSelector(
                    q3levelmesh.GetMesh(0), q3node, 128);
                // not implemented but not necessary
                //q3node.TriangleSelector=selector;
            }

            /*We add a first person shooter camera to the scene for being able to move in
             * the quake 3 level like in tutorial 2. But this, time, we add a special
             * animator to the camera: A Collision Response animator. This thing modifies
             * the scene node to which it is attached to in that way, that it may no
             * more move through walls and is affected by gravity. The only thing we have
             * to tell the animator is how the world looks like, how big the scene node is,
             * how gravity and so on. After the collision response animator is attached to
             * the camera, we do not have to do anything more for collision detection,
             * anything is done automaticly, all other collision detection code below is
             * for picking. And please note another cool feature: The collsion response
             * animator can be attached also to all other scene nodes, not only to cameras.
             * And it can be mixed with other scene node animators. In this way, collision
             * detection and response in the Irrlicht engine is really, really easy.
             * Now we'll take a closer look on the parameters of
             * createCollisionResponseAnimator(). The first parameter is the TriangleSelector,
             * which specifies how the world, against collision detection is done looks like.
             * The second parameter is the scene node, which is the object, which is affected
             * by collision detection, in our case it is the camera. The third defines how big
             * the object is, it is the radius of an ellipsoid. Try it out and change the radius
             * to smaller values, the camera will be able to move closer to walls after this.
             * The next parameter is the direction and speed of gravity. You could set it to
             * (0,0,0) to disable gravity. And the last value is just a translation: Without
             * this, the ellipsoid with which collision detection is done would be around
             * the camera, and the camera would be in the middle of the ellipsoid. But as
             * human beings, we are used to have our eyes on top of the body, with which
             * we collide with our world, not in the middle of it. So we place the scene
             * node 50 units over the center of the ellipsoid with this parameter. And
             * that's it, collision detection works now.
             */
            ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100, 300, 0);

            camera.Position = new Vector3D(-100, 50, -150);
            ISceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator(
                selector, camera, new Vector3D(30, 50, 30),
                new Vector3D(0, -3, 0), new Vector3D(0, 50, 0), 0);

            camera.AddAnimator(anim);

            /*Because collision detection is no big deal in irrlicht, I'll describe how
             * to do two different types of picking in the next section. But before this,
             * I'll prepare the scene a little. I need three animated characters which we
             * could pick later, a dynamic light for lighting them, a billboard for drawing
             * where we found an intersection, and, yes, I need to get rid of this mouse
             * cursor. :)*/
            //disable mouse cursor
            device.CursorControl.Visible = false;

            // add billboard
            IBillboardSceneNode bill = smgr.AddBillboardSceneNode(
                null, new Dimension2Df(20, 20), new Vector3D(), 0);

            bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR);
            bill.SetMaterialTexture(0, driver.GetTexture(
                                        path + "particle.bmp"));
            bill.SetMaterialFlag(MaterialFlag.LIGHTING, false);
            bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false);
            Material material = new Material();

            material.Texture1 = driver.GetTexture(
                path + "faerie2.bmp");
            material.Lighting = true;

            IAnimatedMeshSceneNode node   = null;
            IAnimatedMesh          faerie = smgr.GetMesh(
                path + "faerie.md2");

            if (faerie != null)
            {
                node          = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
                node.Position = new Vector3D(-70, 0, -90);
                node.SetMD2Animation(MD2AnimationType.RUN);
                node.SetMaterial(0, material);

                node          = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
                node.Position = new Vector3D(-70, 0, -30);
                node.SetMD2Animation(MD2AnimationType.SALUTE);
                node.SetMaterial(0, material);

                node          = smgr.AddAnimatedMeshSceneNode(faerie, null, 0);
                node.Position = new Vector3D(-70, 0, -60);
                node.SetMD2Animation(MD2AnimationType.JUMP);
                node.SetMaterial(0, material);
            }

            material.Texture1 = null;
            material.Lighting = false;

            //Add a light
            smgr.AddLightSceneNode(null, new Vector3D(-60, 100, 400),
                                   new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 600, 0);

            /*For not making it too complicated, I'm doing picking inside the drawing
             * loop. We take two pointers for storing the current and the last selected
             * scene node and start the loop.*/
            ISceneNode selectedSceneNode     = null;
            ISceneNode lastSelectedSceneNode = null;

            int lastFPS = -1;

            while (device.Run())
            {
                if (device.WindowActive)
                {
                    device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200));
                    device.SceneManager.DrawAll();

                    /*After we've drawn the whole scene whit smgr->drawAll(), we'll do the
                     * first picking: We want to know which triangle of the world we are
                     * looking at. In addition, we want the exact point of the quake 3
                     * level we are looking at. For this, we create a 3d line starting at
                     * the position of the camera and going through the lookAt-target of it.
                     * Then we ask the collision manager if this line collides with a
                     * triangle of the world stored in the triangle selector. If yes, we draw
                     * the 3d triangle and set the position of the billboard to the intersection
                     * point.*/
                    Line3D line = new Line3D();
                    line.start = camera.Position;
                    line.end   = line.start +
                                 (camera.Target - line.start).Normalize() * 1000;
                    Vector3D   intersection;
                    Triangle3D tri;
                    if (smgr.SceneCollisionManager.GetCollisionPoint(
                            line, selector, out intersection, out tri))
                    {
                        bill.Position = intersection;

                        driver.SetTransform(TransformationState.WORLD, new Matrix4());
                        driver.SetMaterial(material);
                        driver.Draw3DTriangle(tri, new Color(0, 255, 0, 0));
                    }

                    /*Another type of picking supported by the Irrlicht Engine is scene node
                     * picking based on bouding boxes. Every scene node has got a bounding box,
                     * and because of that, it's very fast for example to get the scene node
                     * which the camera looks at. Again, we ask the collision manager for this,
                     * and if we've got a scene node, we highlight it by disabling Lighting in
                     * its material, if it is not the billboard or the quake 3 level.*/
                    selectedSceneNode = smgr.SceneCollisionManager.
                                        GetSceneNodeFromCameraBB(camera, 0);

                    if (lastSelectedSceneNode != null)
                    {
                        lastSelectedSceneNode.SetMaterialFlag(
                            MaterialFlag.LIGHTING, true);
                    }

                    if (selectedSceneNode == q3node ||
                        selectedSceneNode == bill)
                    {
                        selectedSceneNode = null;
                    }

                    if (selectedSceneNode != null)
                    {
                        selectedSceneNode.SetMaterialFlag(
                            MaterialFlag.LIGHTING, false);
                    }
                    lastSelectedSceneNode = selectedSceneNode;

                    /*That's it, we just have to finish drawing.*/

                    driver.EndScene();

                    int fps = device.VideoDriver.FPS;
                    if (lastFPS != fps)
                    {
                        device.WindowCaption = "Irrlicht Engine - Quake 3 Map example [" +
                                               device.VideoDriver.Name + "] FPS:" + fps.ToString();
                        lastFPS = fps;
                    }
                }
            }

            /*
             * In the end, delete the Irrlicht device.
             */
            // Instead of device->drop, we'll use:
            GC.Collect();
        }
예제 #44
0
        // This checks if the view offset/zoom changed and updates the check (never used. mxd)

        /*protected bool CheckViewChanged()
         * {
         *      // View changed?
         *      bool viewchanged = (renderer.OffsetX != lastoffsetx || renderer.OffsetY != lastoffsety || renderer.Scale != lastscale);
         *
         *      // Keep view information
         *      lastoffsetx = renderer.OffsetX;
         *      lastoffsety = renderer.OffsetY;
         *      lastscale = renderer.Scale;
         *
         *      // Return result
         *      return viewchanged;
         * }*/

        // This updates the dragging
        protected virtual void Update()
        {
            PixelColor stitchcolor = General.Colors.Highlight;
            PixelColor losecolor   = General.Colors.Selection;

            snaptocardinaldirection = General.Interface.ShiftState && General.Interface.AltState;             //mxd
            snaptogrid    = (snaptocardinaldirection || General.Interface.ShiftState ^ General.Interface.SnapToGrid);
            snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

            DrawnVertex curp  = GetCurrentPosition();
            float       vsize = (renderer.VertexSize + 1.0f) / renderer.Scale;

            // Update label positions (mxd)
            if (labels.Count > 0)
            {
                // Update labels for already drawn lines
                for (int i = 0; i < labels.Count - 1; i++)
                {
                    labels[i].ShowAngle = showguidelines;
                    labels[i].Move(points[i].pos, points[i + 1].pos);
                }

                // Update label for active line
                labels[labels.Count - 1].ShowAngle = showguidelines;
                labels[labels.Count - 1].Move(points[points.Count - 1].pos, curp.pos);
            }

            // Render drawing lines
            if (renderer.StartOverlay(true))
            {
                // Go for all points to draw lines
                PixelColor color;
                if (points.Count > 0)
                {
                    //mxd
                    bool renderguidelabels = false;
                    if (showguidelines)
                    {
                        Vector2D   prevp = points[points.Count - 1].pos;
                        PixelColor c     = General.Colors.InfoLine.WithAlpha(80);
                        if (curp.pos.x != prevp.x && curp.pos.y != prevp.y)
                        {
                            renderguidelabels = true;

                            Vector2D tr = new Vector2D(Math.Max(curp.pos.x, prevp.x), Math.Max(curp.pos.y, prevp.y));
                            Vector2D bl = new Vector2D(Math.Min(curp.pos.x, prevp.x), Math.Min(curp.pos.y, prevp.y));

                            // Create guidelines
                            Line3D[] lines = new Line3D[5];
                            lines[0] = new Line3D(new Vector2D(tr.x, General.Map.Config.TopBoundary), new Vector2D(tr.x, General.Map.Config.BottomBoundary), c, false);
                            lines[1] = new Line3D(new Vector2D(bl.x, General.Map.Config.TopBoundary), new Vector2D(bl.x, General.Map.Config.BottomBoundary), c, false);
                            lines[2] = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, tr.y), new Vector2D(General.Map.Config.RightBoundary, tr.y), c, false);
                            lines[3] = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, bl.y), new Vector2D(General.Map.Config.RightBoundary, bl.y), c, false);

                            // Create current line extent. Make sure v1 is to the left of v2
                            Line2D current = (curp.pos.x < prevp.x ? new Line2D(curp.pos, prevp) : new Line2D(prevp, curp.pos));

                            Vector2D extentstart, extentend;
                            if (current.v1.y < current.v2.y)                            // Start is lower
                            {
                                // Start point can hit left or bottom boundaries
                                extentstart = Line2D.GetIntersectionPoint(left, current, false);
                                if (extentstart.y < General.Map.Config.BottomBoundary)
                                {
                                    extentstart = Line2D.GetIntersectionPoint(bottom, current, false);
                                }

                                // End point can hit right or top boundaries
                                extentend = Line2D.GetIntersectionPoint(right, current, false);
                                if (extentend.y > General.Map.Config.TopBoundary)
                                {
                                    extentend = Line2D.GetIntersectionPoint(top, current, false);
                                }
                            }
                            else                             // Start is higher
                            {
                                // Start point can hit left or top boundaries
                                extentstart = Line2D.GetIntersectionPoint(left, current, false);
                                if (extentstart.y > General.Map.Config.TopBoundary)
                                {
                                    extentstart = Line2D.GetIntersectionPoint(top, current, false);
                                }

                                // End point can hit right or bottom boundaries
                                extentend = Line2D.GetIntersectionPoint(right, current, false);
                                if (extentend.y < General.Map.Config.BottomBoundary)
                                {
                                    extentend = Line2D.GetIntersectionPoint(bottom, current, false);
                                }
                            }

                            lines[4] = new Line3D(extentstart, extentend, c, false);

                            // Render them
                            renderer.RenderArrows(lines);

                            // Update horiz/vert length labels
                            guidelabels[0].Move(tr, new Vector2D(tr.x, bl.y));
                            guidelabels[1].Move(new Vector2D(bl.x, tr.y), tr);
                            guidelabels[2].Move(new Vector2D(tr.x, bl.y), bl);
                            guidelabels[3].Move(bl, new Vector2D(bl.x, tr.y));
                        }
                        // Render horizontal line
                        else if (curp.pos.x != prevp.x)
                        {
                            Line3D l = new Line3D(new Vector2D(General.Map.Config.LeftBoundary, curp.pos.y), new Vector2D(General.Map.Config.RightBoundary, curp.pos.y), c, false);
                            renderer.RenderArrows(new List <Line3D> {
                                l
                            });
                        }
                        // Render vertical line
                        else if (curp.pos.y != prevp.y)
                        {
                            Line3D l = new Line3D(new Vector2D(curp.pos.x, General.Map.Config.TopBoundary), new Vector2D(curp.pos.x, General.Map.Config.BottomBoundary), c, false);
                            renderer.RenderArrows(new List <Line3D> {
                                l
                            });
                        }
                    }

                    // Render lines
                    DrawnVertex lastp = points[0];
                    for (int i = 1; i < points.Count; i++)
                    {
                        // Determine line color
                        if (lastp.stitchline && points[i].stitchline)
                        {
                            color = stitchcolor;
                        }
                        else
                        {
                            color = losecolor;
                        }

                        // Render line
                        renderer.RenderLine(lastp.pos, points[i].pos, LINE_THICKNESS, color, true);
                        RenderLinedefDirectionIndicator(lastp.pos, points[i].pos, color);                         //mxd
                        lastp = points[i];
                    }

                    // Determine line color
                    color = (lastp.stitchline && snaptonearest ? stitchcolor : losecolor);

                    // Render line to cursor
                    renderer.RenderLine(lastp.pos, curp.pos, LINE_THICKNESS, color, true);
                    RenderLinedefDirectionIndicator(lastp.pos, curp.pos, color);                     //mxd

                    // Render vertices
                    for (int i = 0; i < points.Count; i++)
                    {
                        // Determine vertex color
                        color = points[i].stitch ? stitchcolor : losecolor;

                        // Render vertex
                        renderer.RenderRectangleFilled(new RectangleF(points[i].pos.x - vsize, points[i].pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
                    }

                    //mxd. Render guide labels?
                    if (renderguidelabels)
                    {
                        renderer.RenderText(guidelabels);
                    }

                    // Render labels
                    renderer.RenderText(labels.ToArray());
                }

                // Determine point color
                color = snaptonearest ? stitchcolor : losecolor;

                // Render vertex at cursor
                renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);

                // Done
                renderer.Finish();
            }

            // Done
            renderer.Present();
        }
예제 #45
0
        public void CanNavigateRings()
        {
            var multilinestring = new MultiPolycurve(
                new[]
            {
                new Linestring(new[]
                {
                    new Pnt3D(0, 0, 9),
                    new Pnt3D(0, 100, 9),
                    new Pnt3D(100, 100, 9),
                    new Pnt3D(100, 0, 9),
                    new Pnt3D(0, 0, 9)
                }),
                new Linestring(new[]
                {
                    // interior ring
                    new Pnt3D(40, 40, 123),
                    new Pnt3D(60, 40, 123),
                    new Pnt3D(60, 60, 12),
                    new Pnt3D(40, 60, 12),
                    new Pnt3D(40, 40, 123)
                })
            });

            Assert.True(multilinestring.IsClosed);

            int partIdx;
            int localSegmentIdx = multilinestring.GetLocalSegmentIndex(5, out partIdx);

            Assert.AreEqual(6, multilinestring.GetSegmentStartPointIndex(5));

            Assert.AreEqual(1, partIdx);
            Assert.AreEqual(1, localSegmentIdx);

            Line3D previousSegment = multilinestring.PreviousSegment(5);

            Assert.AreEqual(multilinestring.GetSegment(4), previousSegment);
            Assert.AreEqual(multilinestring.GetSegment(1, 0), previousSegment);

            int?previousSegmentIdx = multilinestring.PreviousSegmentIndex(5);

            Assert.NotNull(previousSegmentIdx);
            Assert.AreEqual(4, previousSegmentIdx);

            previousSegmentIdx = multilinestring.PreviousSegmentIndex(previousSegmentIdx.Value);
            Assert.NotNull(previousSegmentIdx);
            Assert.AreEqual(7, previousSegmentIdx);

            int?nextSegmentIndex = multilinestring.NextSegmentIndex(previousSegmentIdx.Value);

            Assert.NotNull(nextSegmentIndex);
            Assert.AreEqual(4, nextSegmentIndex);

            Line3D nextSegment = multilinestring.NextSegment(previousSegmentIdx.Value);

            Assert.AreEqual(multilinestring.GetSegment(4), nextSegment);
            Assert.AreEqual(multilinestring.GetSegment(1, 0), nextSegment);
            Assert.AreEqual(5, multilinestring.GetSegmentStartPointIndex(4));

            // With the exterior ring:
            localSegmentIdx = multilinestring.GetLocalSegmentIndex(1, out partIdx);

            Assert.AreEqual(0, partIdx);
            Assert.AreEqual(1, localSegmentIdx);

            previousSegment = multilinestring.PreviousSegment(1);
            Assert.AreEqual(multilinestring.GetSegment(0), previousSegment);
            Assert.AreEqual(multilinestring.GetSegment(0, 0), previousSegment);

            previousSegmentIdx = multilinestring.PreviousSegmentIndex(1);
            Assert.NotNull(previousSegmentIdx);
            Assert.AreEqual(0, previousSegmentIdx);

            previousSegmentIdx = multilinestring.PreviousSegmentIndex(previousSegmentIdx.Value);
            Assert.NotNull(previousSegmentIdx);
            Assert.AreEqual(3, previousSegmentIdx);

            nextSegmentIndex = multilinestring.NextSegmentIndex(previousSegmentIdx.Value);
            Assert.NotNull(nextSegmentIndex);
            Assert.AreEqual(0, nextSegmentIndex);

            nextSegment = multilinestring.NextSegment(previousSegmentIdx.Value);

            Assert.AreEqual(multilinestring.GetSegment(0), nextSegment);
            Assert.AreEqual(multilinestring.GetSegment(0, 0), nextSegment);
        }
예제 #46
0
    internal void NextBullet(Game game, int bulletsshot)
    {
        float one = 1;
        bool left = game.mouseLeft;
        bool middle = game.mouseMiddle;
        bool right = game.mouseRight;

        bool IsNextShot = bulletsshot != 0;

        if (!game.leftpressedpicking)
        {
            if (game.mouseleftclick)
            {
                game.leftpressedpicking = true;
            }
            else
            {
                left = false;
            }
        }
        else
        {
            if (game.mouseleftdeclick)
            {
                game.leftpressedpicking = false;
                left = false;
            }
        }
        if (!left)
        {
            game.currentAttackedBlock = null;
        }

        Packet_Item item = game.d_Inventory.RightHand[game.ActiveMaterial];
        bool ispistol = (item != null && game.blocktypes[item.BlockId].IsPistol);
        bool ispistolshoot = ispistol && left;
        bool isgrenade = ispistol && game.blocktypes[item.BlockId].PistolType == Packet_PistolTypeEnum.Grenade;
        if (ispistol && isgrenade)
        {
            ispistolshoot = game.mouseleftdeclick;
        }
        //grenade cooking - TODO: fix instant explosion when closing ESC menu
        if (game.mouseleftclick)
        {
            game.grenadecookingstartMilliseconds = game.platform.TimeMillisecondsFromStart();
            if (ispistol && isgrenade)
            {
                if (game.blocktypes[item.BlockId].Sounds.ShootCount > 0)
                {
                    game.AudioPlay(game.platform.StringFormat("{0}.ogg", game.blocktypes[item.BlockId].Sounds.Shoot[0]));
                }
            }
        }
        float wait = ((one * (game.platform.TimeMillisecondsFromStart() - game.grenadecookingstartMilliseconds)) / 1000);
        if (isgrenade && left)
        {
            if (wait >= game.grenadetime && isgrenade && game.grenadecookingstartMilliseconds != 0)
            {
                ispistolshoot = true;
                game.mouseleftdeclick = true;
            }
            else
            {
                return;
            }
        }
        else
        {
            game.grenadecookingstartMilliseconds = 0;
        }

        if (ispistol && game.mouserightclick && (game.platform.TimeMillisecondsFromStart() - game.lastironsightschangeMilliseconds) >= 500)
        {
            game.IronSights = !game.IronSights;
            game.lastironsightschangeMilliseconds = game.platform.TimeMillisecondsFromStart();
        }

        IntRef pick2count = new IntRef();
        Line3D pick = new Line3D();
        GetPickingLine(game, pick, ispistolshoot);
        BlockPosSide[] pick2 = game.Pick(game.s, pick, pick2count);

        if (left)
        {
            game.handSetAttackDestroy = true;
        }
        else if (right)
        {
            game.handSetAttackBuild = true;
        }

        if (game.overheadcamera && pick2count.value > 0 && left)
        {
            //if not picked any object, and mouse button is pressed, then walk to destination.
            if (game.Follow == null)
            {
                //Only walk to destination when not following someone
                game.playerdestination = Vector3Ref.Create(pick2[0].blockPos[0], pick2[0].blockPos[1] + 1, pick2[0].blockPos[2]);
            }
        }
        bool pickdistanceok = (pick2count.value > 0); //&& (!ispistol);
        if (pickdistanceok)
        {
            if (game.Dist(pick2[0].blockPos[0] + one / 2, pick2[0].blockPos[1] + one / 2, pick2[0].blockPos[2] + one / 2,
                pick.Start[0], pick.Start[1], pick.Start[2]) > CurrentPickDistance(game))
            {
                pickdistanceok = false;
            }
        }
        bool playertileempty = game.IsTileEmptyForPhysics(
                  game.platform.FloatToInt(game.player.position.x),
                  game.platform.FloatToInt(game.player.position.z),
                  game.platform.FloatToInt(game.player.position.y + (one / 2)));
        bool playertileemptyclose = game.IsTileEmptyForPhysicsClose(
                  game.platform.FloatToInt(game.player.position.x),
                  game.platform.FloatToInt(game.player.position.z),
                  game.platform.FloatToInt(game.player.position.y + (one / 2)));
        BlockPosSide pick0 = new BlockPosSide();
        if (pick2count.value > 0 &&
            ((pickdistanceok && (playertileempty || (playertileemptyclose)))
            || game.overheadcamera)
            )
        {
            game.SelectedBlockPositionX = game.platform.FloatToInt(pick2[0].Current()[0]);
            game.SelectedBlockPositionY = game.platform.FloatToInt(pick2[0].Current()[1]);
            game.SelectedBlockPositionZ = game.platform.FloatToInt(pick2[0].Current()[2]);
            pick0 = pick2[0];
        }
        else
        {
            game.SelectedBlockPositionX = -1;
            game.SelectedBlockPositionY = -1;
            game.SelectedBlockPositionZ = -1;
            pick0.blockPos = new float[3];
            pick0.blockPos[0] = -1;
            pick0.blockPos[1] = -1;
            pick0.blockPos[2] = -1;
        }
        PickEntity(game, pick, pick2, pick2count);
        if (game.cameratype == CameraType.Fpp || game.cameratype == CameraType.Tpp)
        {
            int ntileX = game.platform.FloatToInt(pick0.Current()[0]);
            int ntileY = game.platform.FloatToInt(pick0.Current()[1]);
            int ntileZ = game.platform.FloatToInt(pick0.Current()[2]);
            if (game.IsUsableBlock(game.map.GetBlock(ntileX, ntileZ, ntileY)))
            {
                game.currentAttackedBlock = Vector3IntRef.Create(ntileX, ntileZ, ntileY);
            }
        }
        if (game.GetFreeMouse())
        {
            if (pick2count.value > 0)
            {
                OnPick_(pick0);
            }
            return;
        }

        if ((one * (game.platform.TimeMillisecondsFromStart() - lastbuildMilliseconds) / 1000) >= BuildDelay(game)
            || IsNextShot)
        {
            if (left && game.d_Inventory.RightHand[game.ActiveMaterial] == null)
            {
                game.SendPacketClient(ClientPackets.MonsterHit(game.platform.FloatToInt(2 + game.rnd.NextFloat() * 4)));
            }
            if (left && !fastclicking)
            {
                //todo animation
                fastclicking = false;
            }
            if ((left || right || middle) && (!isgrenade))
            {
                lastbuildMilliseconds = game.platform.TimeMillisecondsFromStart();
            }
            if (isgrenade && game.mouseleftdeclick)
            {
                lastbuildMilliseconds = game.platform.TimeMillisecondsFromStart();
            }
            if (game.reloadstartMilliseconds != 0)
            {
                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (ispistolshoot)
            {
                if ((!(game.LoadedAmmo[item.BlockId] > 0))
                    || (!(game.TotalAmmo[item.BlockId] > 0)))
                {
                    game.AudioPlay("Dry Fire Gun-SoundBible.com-2053652037.ogg");
                    PickingEnd(left, right, middle, ispistol);
                    return;
                }
            }
            if (ispistolshoot)
            {
                float toX = pick.End[0];
                float toY = pick.End[1];
                float toZ = pick.End[2];
                if (pick2count.value > 0)
                {
                    toX = pick2[0].blockPos[0];
                    toY = pick2[0].blockPos[1];
                    toZ = pick2[0].blockPos[2];
                }

                Packet_ClientShot shot = new Packet_ClientShot();
                shot.FromX = game.SerializeFloat(pick.Start[0]);
                shot.FromY = game.SerializeFloat(pick.Start[1]);
                shot.FromZ = game.SerializeFloat(pick.Start[2]);
                shot.ToX = game.SerializeFloat(toX);
                shot.ToY = game.SerializeFloat(toY);
                shot.ToZ = game.SerializeFloat(toZ);
                shot.HitPlayer = -1;

                for (int i = 0; i < game.entitiesCount; i++)
                {
                    if (game.entities[i] == null)
                    {
                        continue;
                    }
                    if (game.entities[i].drawModel == null)
                    {
                        continue;
                    }
                    Entity p_ = game.entities[i];
                    if (p_.networkPosition == null)
                    {
                        continue;
                    }
                    if (!p_.networkPosition.PositionLoaded)
                    {
                        continue;
                    }
                    float feetposX = p_.position.x;
                    float feetposY = p_.position.y;
                    float feetposZ = p_.position.z;
                    //var p = PlayerPositionSpawn;
                    Box3D bodybox = new Box3D();
                    float headsize = (p_.drawModel.ModelHeight - p_.drawModel.eyeHeight) * 2; //0.4f;
                    float h = p_.drawModel.ModelHeight - headsize;
                    float r = one * 35 / 100;

                    bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ - r);
                    bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ + r);
                    bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ - r);
                    bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ + r);

                    bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
                    bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
                    bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
                    bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

                    Box3D headbox = new Box3D();

                    headbox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
                    headbox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
                    headbox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
                    headbox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

                    headbox.AddPoint(feetposX - r, feetposY + h + headsize, feetposZ - r);
                    headbox.AddPoint(feetposX - r, feetposY + h + headsize, feetposZ + r);
                    headbox.AddPoint(feetposX + r, feetposY + h + headsize, feetposZ - r);
                    headbox.AddPoint(feetposX + r, feetposY + h + headsize, feetposZ + r);

                    float[] p;
                    float localeyeposX = game.EyesPosX();
                    float localeyeposY = game.EyesPosY();
                    float localeyeposZ = game.EyesPosZ();
                    p = Intersection.CheckLineBoxExact(pick, headbox);
                    if (p != null)
                    {
                        //do not allow to shoot through terrain
                        if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                            > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                        {
                            if (!isgrenade)
                            {
                                Entity entity = new Entity();
                                Sprite sprite = new Sprite();
                                sprite.positionX = p[0];
                                sprite.positionY = p[1];
                                sprite.positionZ = p[2];
                                sprite.image = "blood.png";
                                entity.sprite = sprite;
                                entity.expires = Expires.Create(one * 2 / 10);
                                game.EntityAddLocal(entity);
                            }
                            shot.HitPlayer = i;
                            shot.IsHitHead = 1;
                        }
                    }
                    else
                    {
                        p = Intersection.CheckLineBoxExact(pick, bodybox);
                        if (p != null)
                        {
                            //do not allow to shoot through terrain
                            if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                                > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                            {
                                if (!isgrenade)
                                {
                                    Entity entity = new Entity();
                                    Sprite sprite = new Sprite();
                                    sprite.positionX = p[0];
                                    sprite.positionY = p[1];
                                    sprite.positionZ = p[2];
                                    sprite.image = "blood.png";
                                    entity.sprite = sprite;
                                    entity.expires = Expires.Create(one * 2 / 10);
                                    game.EntityAddLocal(entity);
                                }
                                shot.HitPlayer = i;
                                shot.IsHitHead = 0;
                            }
                        }
                    }
                }
                shot.WeaponBlock = item.BlockId;
                game.LoadedAmmo[item.BlockId] = game.LoadedAmmo[item.BlockId] - 1;
                game.TotalAmmo[item.BlockId] = game.TotalAmmo[item.BlockId] - 1;
                float projectilespeed = game.DeserializeFloat(game.blocktypes[item.BlockId].ProjectileSpeedFloat);
                if (projectilespeed == 0)
                {
                    {
                        Entity entity = game.CreateBulletEntity(
                          pick.Start[0], pick.Start[1], pick.Start[2],
                          toX, toY, toZ, 150);
                        game.EntityAddLocal(entity);
                    }
                }
                else
                {
                    float vX = toX - pick.Start[0];
                    float vY = toY - pick.Start[1];
                    float vZ = toZ - pick.Start[2];
                    float vLength = game.Length(vX, vY, vZ);
                    vX /= vLength;
                    vY /= vLength;
                    vZ /= vLength;
                    vX *= projectilespeed;
                    vY *= projectilespeed;
                    vZ *= projectilespeed;
                    shot.ExplodesAfter = game.SerializeFloat(game.grenadetime - wait);

                    {
                        Entity grenadeEntity = new Entity();

                        Sprite sprite = new Sprite();
                        sprite.image = "ChemicalGreen.png";
                        sprite.size = 14;
                        sprite.animationcount = 0;
                        sprite.positionX = pick.Start[0];
                        sprite.positionY = pick.Start[1];
                        sprite.positionZ = pick.Start[2];
                        grenadeEntity.sprite = sprite;

                        Grenade_ projectile = new Grenade_();
                        projectile.velocityX = vX;
                        projectile.velocityY = vY;
                        projectile.velocityZ = vZ;
                        projectile.block = item.BlockId;
                        projectile.sourcePlayer = game.LocalPlayerId;

                        grenadeEntity.expires = Expires.Create(game.grenadetime - wait);

                        grenadeEntity.grenade = projectile;
                        game.EntityAddLocal(grenadeEntity);
                    }
                }
                Packet_Client packet = new Packet_Client();
                packet.Id = Packet_ClientIdEnum.Shot;
                packet.Shot = shot;
                game.SendPacketClient(packet);

                if (game.blocktypes[item.BlockId].Sounds.ShootEndCount > 0)
                {
                    game.pistolcycle = game.rnd.Next() % game.blocktypes[item.BlockId].Sounds.ShootEndCount;
                    game.AudioPlay(game.platform.StringFormat("{0}.ogg", game.blocktypes[item.BlockId].Sounds.ShootEnd[game.pistolcycle]));
                }

                bulletsshot++;
                if (bulletsshot < game.DeserializeFloat(game.blocktypes[item.BlockId].BulletsPerShotFloat))
                {
                    NextBullet(game, bulletsshot);
                }

                //recoil
                game.player.position.rotx -= game.rnd.NextFloat() * game.CurrentRecoil();
                game.player.position.roty += game.rnd.NextFloat() * game.CurrentRecoil() * 2 - game.CurrentRecoil();

                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (ispistol && right)
            {
                PickingEnd(left, right, middle, ispistol);
                return;
            }
            if (pick2count.value > 0)
            {
                if (middle)
                {
                    int newtileX = game.platform.FloatToInt(pick0.Current()[0]);
                    int newtileY = game.platform.FloatToInt(pick0.Current()[1]);
                    int newtileZ = game.platform.FloatToInt(pick0.Current()[2]);
                    if (game.map.IsValidPos(newtileX, newtileZ, newtileY))
                    {
                        int clonesource = game.map.GetBlock(newtileX, newtileZ, newtileY);
                        int clonesource2 = game.d_Data.WhenPlayerPlacesGetsConvertedTo()[clonesource];
                        bool gotoDone = false;
                        //find this block in another right hand.
                        for (int i = 0; i < 10; i++)
                        {
                            if (game.d_Inventory.RightHand[i] != null
                                && game.d_Inventory.RightHand[i].ItemClass == Packet_ItemClassEnum.Block
                                && game.d_Inventory.RightHand[i].BlockId == clonesource2)
                            {
                                game.ActiveMaterial = i;
                                gotoDone = true;
                            }
                        }
                        if (!gotoDone)
                        {
                            IntRef freehand = game.d_InventoryUtil.FreeHand(game.ActiveMaterial);
                            //find this block in inventory.
                            for (int i = 0; i < game.d_Inventory.ItemsCount; i++)
                            {
                                Packet_PositionItem k = game.d_Inventory.Items[i];
                                if (k == null)
                                {
                                    continue;
                                }
                                if (k.Value_.ItemClass == Packet_ItemClassEnum.Block
                                    && k.Value_.BlockId == clonesource2)
                                {
                                    //free hand
                                    if (freehand != null)
                                    {
                                        game.WearItem(
                                            game.InventoryPositionMainArea(k.X, k.Y),
                                            game.InventoryPositionMaterialSelector(freehand.value));
                                        break;
                                    }
                                    //try to replace current slot
                                    if (game.d_Inventory.RightHand[game.ActiveMaterial] != null
                                        && game.d_Inventory.RightHand[game.ActiveMaterial].ItemClass == Packet_ItemClassEnum.Block)
                                    {
                                        game.MoveToInventory(
                                            game.InventoryPositionMaterialSelector(game.ActiveMaterial));
                                        game.WearItem(
                                            game.InventoryPositionMainArea(k.X, k.Y),
                                            game.InventoryPositionMaterialSelector(game.ActiveMaterial));
                                    }
                                }
                            }
                        }
                        string[] sound = game.d_Data.CloneSound()[clonesource];
                        if (sound != null) // && sound.Length > 0)
                        {
                            game.AudioPlay(sound[0]); //todo sound cycle
                        }
                    }
                }
                if (left || right)
                {
                    BlockPosSide tile = pick0;
                    int newtileX;
                    int newtileY;
                    int newtileZ;
                    if (right)
                    {
                        newtileX = game.platform.FloatToInt(tile.Translated()[0]);
                        newtileY = game.platform.FloatToInt(tile.Translated()[1]);
                        newtileZ = game.platform.FloatToInt(tile.Translated()[2]);
                    }
                    else
                    {
                        newtileX = game.platform.FloatToInt(tile.Current()[0]);
                        newtileY = game.platform.FloatToInt(tile.Current()[1]);
                        newtileZ = game.platform.FloatToInt(tile.Current()[2]);
                    }
                    if (game.map.IsValidPos(newtileX, newtileZ, newtileY))
                    {
                        //Console.WriteLine(". newtile:" + newtile + " type: " + d_Map.GetBlock(newtileX, newtileZ, newtileY));
                        if (!(pick0.blockPos[0] == -1
                             && pick0.blockPos[1] == -1
                            && pick0.blockPos[2] == -1))
                        {
                            int blocktype;
                            if (left) { blocktype = game.map.GetBlock(newtileX, newtileZ, newtileY); }
                            else { blocktype = ((game.BlockInHand() == null) ? 1 : game.BlockInHand().value); }
                            if (left && blocktype == game.d_Data.BlockIdAdminium())
                            {
                                PickingEnd(left, right, middle, ispistol);
                                return;
                            }
                            string[] sound = left ? game.d_Data.BreakSound()[blocktype] : game.d_Data.BuildSound()[blocktype];
                            if (sound != null) // && sound.Length > 0)
                            {
                                game.AudioPlay(sound[0]); //todo sound cycle
                            }
                        }
                        //normal attack
                        if (!right)
                        {
                            //attack
                            int posx = newtileX;
                            int posy = newtileZ;
                            int posz = newtileY;
                            game.currentAttackedBlock = Vector3IntRef.Create(posx, posy, posz);
                            if (!game.blockHealth.ContainsKey(posx, posy, posz))
                            {
                                game.blockHealth.Set(posx, posy, posz, game.GetCurrentBlockHealth(posx, posy, posz));
                            }
                            game.blockHealth.Set(posx, posy, posz, game.blockHealth.Get(posx, posy, posz) - game.WeaponAttackStrength());
                            float health = game.GetCurrentBlockHealth(posx, posy, posz);
                            if (health <= 0)
                            {
                                if (game.currentAttackedBlock != null)
                                {
                                    game.blockHealth.Remove(posx, posy, posz);
                                }
                                game.currentAttackedBlock = null;
                                OnPick(game, game.platform.FloatToInt(newtileX), game.platform.FloatToInt(newtileZ), game.platform.FloatToInt(newtileY),
                                    game.platform.FloatToInt(tile.Current()[0]), game.platform.FloatToInt(tile.Current()[2]), game.platform.FloatToInt(tile.Current()[1]),
                                    tile.collisionPos,
                                    right);
                            }
                            PickingEnd(left, right, middle, ispistol);
                            return;
                        }
                        if (!right)
                        {
                            game.particleEffectBlockBreak.StartParticleEffect(newtileX, newtileY, newtileZ);//must be before deletion - gets ground type.
                        }
                        if (!game.map.IsValidPos(newtileX, newtileZ, newtileY))
                        {
                            game.platform.ThrowException("Error in picking - NextBullet()");
                        }
                        OnPick(game, game.platform.FloatToInt(newtileX), game.platform.FloatToInt(newtileZ), game.platform.FloatToInt(newtileY),
                            game.platform.FloatToInt(tile.Current()[0]), game.platform.FloatToInt(tile.Current()[2]), game.platform.FloatToInt(tile.Current()[1]),
                            tile.collisionPos,
                            right);
                        //network.SendSetBlock(new Vector3((int)newtile.X, (int)newtile.Z, (int)newtile.Y),
                        //    right ? BlockSetMode.Create : BlockSetMode.Destroy, (byte)MaterialSlots[activematerial]);
                    }
                }
            }
        }
        PickingEnd(left, right, middle, ispistol);
    }
예제 #47
0
 public static Line ToLine(this Line3D line)
 {
     return(new Line(line.From, line.To));
 }
예제 #48
0
 /// <summary>
 /// Warning: randomly returns incorrect hit position (back side of box).
 /// </summary>
 /// <param name="box"></param>
 /// <param name="line"></param>
 /// <param name="hit"></param>
 /// <returns></returns>
 public static bool CheckLineBox(Box3D box, Line3D line, float[] hit)
 {
     return CheckLineBox1(box.MinEdge, box.MaxEdge, line.Start, line.End, hit);
 }
예제 #49
0
        /// <summary>
        /// 将三维线段打断成最小的单元
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <Line3D> Decompose(List <Line3D> lines)
        {
            //获取原始的线集合
            List <Line3D> newLines = new List <Line3D>(lines);

            //获取线和分割点的字典表
            Dictionary <Line3D, List <Vector3D> > lineDIC = new Dictionary <Line3D, List <Vector3D> >();

            //循环所有的线的相交关系,得到字典表
            for (int i = 0; i < newLines.Count; i++)
            {
                for (int j = i; j < newLines.Count; j++)
                {
                    Vector3D IntersectP = newLines[i].Intersect(newLines[j]);

                    if (IntersectP != null)
                    {
                        if (!IntersectP.IsEndPoint(newLines[i]))
                        {
                            if (lineDIC[newLines[i]] == null)
                            {
                                lineDIC.Add(newLines[i], new List <Vector3D>()
                                {
                                    IntersectP
                                });
                            }
                            else
                            {
                                lineDIC[newLines[i]].Add(IntersectP);
                            }
                        }
                        if (!IntersectP.IsEndPoint(newLines[j]))
                        {
                            if (lineDIC[newLines[j]] == null)
                            {
                                lineDIC.Add(newLines[j], new List <Vector3D>()
                                {
                                    IntersectP
                                });
                            }
                            else
                            {
                                lineDIC[newLines[j]].Add(IntersectP);
                            }
                        }
                    }
                }
            }
            //变化所有线
            foreach (KeyValuePair <Line3D, List <Vector3D> > vetsInLine in lineDIC)
            {
                //移除原来线段
                newLines.Remove(vetsInLine.Key);

                vetsInLine.Value.Add(vetsInLine.Key.Start);
                vetsInLine.Value.Add(vetsInLine.Key.End);
                ///去掉重复的点
                var vets = vetsInLine.Value.Distinct <Vector3D>(new Vector3DEqualityComparer());


                //通过比较距离
                var orderVets = vets.OrderBy(x => x.Distance(vetsInLine.Key.Start));


                var count = orderVets.Count();
                for (int i = 0; i < count - 1; i++)
                {
                    newLines.Add(Line3D.Create(orderVets.ElementAt(i), orderVets.ElementAt(i + 1)));
                }
            }
            return(newLines);
        }
예제 #50
0
    void PickEntity(Game game, Line3D pick, BlockPosSide[] pick2, IntRef pick2count)
    {
        game.SelectedEntityId = -1;
        game.currentlyAttackedEntity = -1;
        float one = 1;
        for (int i = 0; i < game.entitiesCount; i++)
        {
            if (game.entities[i] == null)
            {
                continue;
            }
            if (i == game.LocalPlayerId)
            {
                continue;
            }
            if (game.entities[i].drawModel == null)
            {
                continue;
            }
            Entity p_ = game.entities[i];
            if (p_.networkPosition == null)
            {
                continue;
            }
            if (!p_.networkPosition.PositionLoaded)
            {
                continue;
            }
            if (!p_.usable)
            {
                continue;
            }
            float feetposX = p_.position.x;
            float feetposY = p_.position.y;
            float feetposZ = p_.position.z;

            float dist = game.Dist(feetposX, feetposY, feetposZ, game.player.position.x, game.player.position.y, game.player.position.z);
            if (dist > 5)
            {
                continue;
            }

            //var p = PlayerPositionSpawn;
            Box3D bodybox = new Box3D();
            float h = p_.drawModel.ModelHeight;
            float r = one * 35 / 100;

            bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ - r);
            bodybox.AddPoint(feetposX - r, feetposY + 0, feetposZ + r);
            bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ - r);
            bodybox.AddPoint(feetposX + r, feetposY + 0, feetposZ + r);

            bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ - r);
            bodybox.AddPoint(feetposX - r, feetposY + h, feetposZ + r);
            bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ - r);
            bodybox.AddPoint(feetposX + r, feetposY + h, feetposZ + r);

            float[] p;
            float localeyeposX = game.EyesPosX();
            float localeyeposY = game.EyesPosY();
            float localeyeposZ = game.EyesPosZ();
            p = Intersection.CheckLineBoxExact(pick, bodybox);
            if (p != null)
            {
                //do not allow to shoot through terrain
                if (pick2count.value == 0 || (game.Dist(pick2[0].blockPos[0], pick2[0].blockPos[1], pick2[0].blockPos[2], localeyeposX, localeyeposY, localeyeposZ)
                    > game.Dist(p[0], p[1], p[2], localeyeposX, localeyeposY, localeyeposZ)))
                {
                    game.SelectedEntityId = i;
                    if (game.cameratype == CameraType.Fpp || game.cameratype == CameraType.Tpp)
                    {
                        game.currentlyAttackedEntity = i;
                    }
                }
            }
        }
    }
예제 #51
0
 public void Draw(Line3D line, Color color)
 {
     DrawLine(line.P1, line.P2, color);
 }
예제 #52
0
        /// <summary>
        /// build polygons from given list of segments
        /// if want to represent arcs, add them as dummy lines to segs
        /// polys returned are ordered anticlockwise
        /// </summary>
        public static IEnumerable <IReadOnlyList <Vector3D> > ClosedPolys2D(this IEnumerable <Line3D> segs, double tolLen,
                                                                            int polyMaxPoints = 0)
        {
            var minCoord = new BBox3D(segs.SelectMany(r => new[] { r.From, r.To })).Min;

            var vcmp         = new Vector3DEqualityComparer(tolLen);
            var lcmp         = new Line3DEqualityComparer(tolLen);
            var segsDict     = segs.ToDictionary(k => k.ToString(tolLen), v => v);
            var segsFromDict = segs.GroupBy(g => g.From, v => v, vcmp).ToDictionary(k => k.Key, v => v.ToList(), vcmp);
            var segsToDict   = segs.GroupBy(g => g.To, v => v, vcmp).ToDictionary(k => k.Key, v => v.ToList(), vcmp);

            var segsLeft         = segs.OrderBy(w => w.MidPoint.Distance(minCoord)).ToList();
            var polys            = new List <List <Vector3D> >();
            var polyCentroidDone = new HashSet <Vector3D>(vcmp);

            while (segsLeft.Count > 0)
            {
                //Console.WriteLine($"segsLeft: {segsLeft.Count} polys:{polys.Count}");

                var seg = segsLeft.First();
                segsLeft.Remove(seg);
                var poly = new List <Vector3D>()
                {
                    seg.From, seg.To
                };
                var rotDir = 1.0; // 1=+Z, -1=-Z
                while (true)
                {
                    List <Line3D> segsNext = null;
                    {
                        var hs = new HashSet <Line3D>(lcmp);
                        {
                            List <Line3D> tmp = null;
                            if (segsFromDict.TryGetValue(seg.To, out tmp))
                            {
                                foreach (var x in tmp.Where(r => !r.EqualsTol(tolLen, seg)))
                                {
                                    hs.Add(x);
                                }
                            }
                            if (segsToDict.TryGetValue(seg.To, out tmp))
                            {
                                foreach (var x in tmp.Where(r => !r.EqualsTol(tolLen, seg)))
                                {
                                    hs.Add(x);
                                }
                            }
                        }
                        segsNext = hs.Select(w => w.EnsureFrom(tolLen, seg.To)).ToList();
                    }

                    Line3D segNext          = null;
                    var    force_close_poly = false;

                    if (polyMaxPoints > 0 && poly.Count > polyMaxPoints)
                    {
                        throw new Exception($"polygon [{poly.PolygonSegments(tolLen).ToCadScript()}] max point exceeded");
                    }

                    //#if DEBUG

                    //                    if (//poly.Count >= 2 &&
                    //                        poly.Any(r => r.EqualsTol(1e-2, 31.0626,-0.0018))
                    //                        //&&
                    //                        //poly.Any(r => r.EqualsTol(tolLen, -42.9561, 0))
                    //                        )
                    //                        ;
                    //#endif

                    if (poly.Count == 2)
                    {
                        if (segsNext.Count == 0)
                        {
                            throw new Exception($"check singular segment [{seg}] cadscript [{seg.CadScript}]");
                        }

                        segNext = segsNext
                                  .OrderBy(w => (-seg.V).AngleRad(tolLen, w.V))
                                  .First();
                        rotDir = seg.V.CrossProduct(segNext.V).Z > 0 ? 1 : -1;
                    }
                    else
                    {
                        var qSegsNext = segsNext
                                        .Select(w => new
                        {
                            arad = (seg.V).AngleToward(tolLen, w.V, Vector3D.ZAxis * rotDir),
                            seg  = w
                        })
                                        .Where(r => r.arad <= PI).ToList();

                        if (qSegsNext.Count == 0)
                        {
                            force_close_poly = true;
                        }
                        else
                        {
                            // retrieve next segment with current rotation direction w/acutest angle
                            segNext = qSegsNext
                                      .OrderByDescending(r => r.arad)
                                      .First().seg;
                        }
                    }

                    if (force_close_poly)
                    {
                        break;
                    }

                    segsLeft.Remove(segNext);
                    if (segNext.To.EqualsTol(tolLen, poly[0]))
                    {
                        break;
                    }
                    poly.Add(segNext.To);

                    seg = segNext;
                }

                if (poly.Count > 2)
                {
                    poly = poly.SortPoly(tolLen, Vector3D.ZAxis).ToList();

                    var polyCentroid = poly.Centroid(tolLen);
                    if (!polyCentroidDone.Contains(polyCentroid))
                    {
                        polys.Add(poly);
                        polyCentroidDone.Add(polyCentroid);
                    }
                }
                else
                {
                    // todo warning
                }
            }

            return(polys.OrderByDescending(w => w.Count));
        }
예제 #53
0
 /// <summary>
 /// retrieve perpendicular distance of this point from the given line
 /// </summary>
 public double Distance(double tol, Line3D other)
 {
     return(other.Perpendicular(tol, this).Length);
 }
예제 #54
0
 /// <summary>
 /// project this vector to the given line
 /// </summary>
 public Vector3D Project(Line3D line)
 {
     return((this - line.From).Project(line.V) + line.From);
 }
예제 #55
0
 public void XmlTests(string p1s, string p2s, string xml)
 {
     Point3D p1 = Point3D.Parse(p1s);
     Point3D p2 = Point3D.Parse(p2s);
     var l = new Line3D(p1, p2);
     AssertXml.XmlRoundTrips(l, xml, (e, a) => AssertGeometry.AreEqual(e, a));
 }
예제 #56
0
 /// <summary>
 /// mirror this point about given axis
 /// </summary>
 public Vector3D Mirror(Line3D axis)
 {
     return(this + 2 * (Project(axis) - this));
 }
예제 #57
0
            /// <summary>
            /// build 3d circle that tangent to lines t1,t2 and that intersects point p
            /// note: point p must contained in one of t1,t2
            /// circle will be inside region t1.V toward t2.V
            /// they are 4 circles
            /// </summary>
            public static IEnumerable <Circle3D> CirclesTan12P(double tol_len, Line3D t1, Line3D t2, Vector3D p)
            {
                foreach (var da in new double[] { 0, PI / 2 })
                {
                    var ip    = t1.Intersect(tol_len, t2);
                    var angle = t1.V.AngleRad(tol_len, t2.V);
                    var t3    = new Line3D(ip, t1.V.RotateAs(tol_len, t1.V, t2.V, .5, da), Line3DConstructMode.PointAndVector);

                    Line3D lp  = null;
                    Line3D lNp = null;
                    if (t1.LineContainsPoint(tol_len, p))
                    {
                        lp = t1; lNp = t2;
                    }
                    else if (t2.LineContainsPoint(tol_len, p))
                    {
                        lp = t2; lNp = t1;
                    }
                    else
                    {
                        throw new Exception($"circle 2 tan 1 point : pt must contained in one of given tan");
                    }

                    var lpp = new Line3D(p, lp.V.RotateAboutAxis(t1.V.CrossProduct(t2.V), PI / 2), Line3DConstructMode.PointAndVector);
                    var c   = lpp.Intersect(tol_len, t3);

                    var Radius = p.Distance(c);
                    var CS     = new CoordinateSystem3D(c, lpp.V, t2.V);

                    yield return(new Circle3D(tol_len, CS, Radius));

                    // mirrored addictional circle

                    var mc = c.Mirror(new Line3D(p, p.Project(lNp) - p, Line3DConstructMode.PointAndVector));

                    yield return(new Circle3D(tol_len, new CoordinateSystem3D(mc, lpp.V, t2.V), Radius));
                }
            }
예제 #58
0
 /// <summary>
 /// Berechnet die Entfernung von dieser Geraden zu einer anderen.
 /// </summary>
 /// <returns></returns>
 public double DistanceTo(Line3D other)
 {
     return Vector.DotProduct(P - other.P, Vector3.GetCrossProduct(V, other.V).Normalize());
 }
예제 #59
0
        public void run()
        {
            /* At first, we let the user select the driver type,
               then start up the engine, set a caption, and get a
               pointer to the video driver.
            */

            // ask user for driver
            DriverType driverType;

            // Ask user to select driver:
            StringBuilder sb = new StringBuilder();
            sb.Append("Please select the driver you want for this example:\n");
            sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5");
            sb.Append("\n(d) Software Renderer\n(e) Apfelbaum Software Renderer");
            sb.Append("\n(f) Null Device\n(otherKey) exit\n\n");

            // Get the user's input:
            TextReader tIn = Console.In;
            TextWriter tOut = Console.Out;
            tOut.Write(sb.ToString());
            string input = tIn.ReadLine();

            // Select device based on user's input:
            switch (input)
            {
                case "a":
                    driverType = DriverType.DIRECT3D9;
                    break;
                case "b":
                    driverType = DriverType.DIRECT3D8;
                    break;
                case "c":
                    driverType = DriverType.OPENGL;
                    break;
                case "d":
                    driverType = DriverType.SOFTWARE;
                    break;
                case "e":
                    driverType = DriverType.SOFTWARE2;
                    break;
                case "f":
                    driverType = DriverType.NULL_DRIVER;
                    break;
                default:
                    return;
            }

            // Create device and exit if creation fails:
            device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, false, true, true);

            if (device == null)
            {
                tOut.Write("Device creation failed.");
                return;
            }

            /*
            Get a pointer to the video driver and the SceneManager so that
            we do not always have to write device->getVideoDriver() and
            device->getSceneManager().
            */

            ISceneManager smgr=device.SceneManager;
            IVideoDriver driver=device.VideoDriver;

            device.FileSystem.AddZipFileArchive(path+"map-20kdm2.pk3");

            IAnimatedMesh q3levelmesh = smgr.GetMesh("20kdm2.bsp");
            ISceneNode q3node = null;
            if (q3levelmesh!=null)
                q3node=smgr.AddOctTreeSceneNode(q3levelmesh.GetMesh(0),null,0);

            /*So far so good, we've loaded the quake 3 level like in tutorial 2.
             Now, here comes something different: We create a triangle selector. A
             triangle selector is a class which can fetch the triangles from scene
             nodes for doing different things with them, for example collision
             detection. There are different triangle selectors, and all can be
             created with the ISceneManager. In this example, we create an
             OctTreeTriangleSelector, which optimizes the triangle output a little
             bit by reducing it like an octree. This is very useful for huge meshes
             like quake 3 levels.
             After we created the triangle selector, we attach it to the q3node.
             This is not necessary, but in this way, we do not need to care for the
             selector, for example dropping it after we do not need it anymore.*/

            ITriangleSelector selector = null;
            if (q3node!=null)
            {
                q3node.Position= new Vector3D(-1370,-130,-1400);
                selector=smgr.CreateOctTreeTriangleSelector(
                    q3levelmesh.GetMesh(0),q3node,128);
                // not implemented but not necessary
                //q3node.TriangleSelector=selector;
            }

            /*We add a first person shooter camera to the scene for being able to move in
              the quake 3 level like in tutorial 2. But this, time, we add a special
              animator to the camera: A Collision Response animator. This thing modifies
              the scene node to which it is attached to in that way, that it may no
              more move through walls and is affected by gravity. The only thing we have
              to tell the animator is how the world looks like, how big the scene node is,
              how gravity and so on. After the collision response animator is attached to
              the camera, we do not have to do anything more for collision detection,
              anything is done automaticly, all other collision detection code below is
              for picking. And please note another cool feature: The collsion response
              animator can be attached also to all other scene nodes, not only to cameras.
              And it can be mixed with other scene node animators. In this way, collision
              detection and response in the Irrlicht engine is really, really easy.
              Now we'll take a closer look on the parameters of
              createCollisionResponseAnimator(). The first parameter is the TriangleSelector,
              which specifies how the world, against collision detection is done looks like.
              The second parameter is the scene node, which is the object, which is affected
              by collision detection, in our case it is the camera. The third defines how big
              the object is, it is the radius of an ellipsoid. Try it out and change the radius
              to smaller values, the camera will be able to move closer to walls after this.
              The next parameter is the direction and speed of gravity. You could set it to
              (0,0,0) to disable gravity. And the last value is just a translation: Without
              this, the ellipsoid with which collision detection is done would be around
              the camera, and the camera would be in the middle of the ellipsoid. But as
              human beings, we are used to have our eyes on top of the body, with which
              we collide with our world, not in the middle of it. So we place the scene
              node 50 units over the center of the ellipsoid with this parameter. And
              that's it, collision detection works now.
             */
            ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null,100,300,0);
            camera.Position=new Vector3D(-100,50,-150);
            ISceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator(
                selector,camera,new Vector3D(30,50,30),
                new Vector3D(0,-3,0),new Vector3D(0,50,0),0);
            camera.AddAnimator(anim);

            /*Because collision detection is no big deal in irrlicht, I'll describe how
              to do two different types of picking in the next section. But before this,
              I'll prepare the scene a little. I need three animated characters which we
              could pick later, a dynamic light for lighting them, a billboard for drawing
              where we found an intersection, and, yes, I need to get rid of this mouse
              cursor. :)*/
            //disable mouse cursor
            device.CursorControl.Visible=false;

            // add billboard
            IBillboardSceneNode bill = smgr.AddBillboardSceneNode(
                null,new Dimension2Df(20,20),new Vector3D(),0);
            bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR);
            bill.SetMaterialTexture(0,driver.GetTexture(
                path+"particle.bmp"));
            bill.SetMaterialFlag(MaterialFlag.LIGHTING,false);
            bill.SetMaterialFlag(MaterialFlag.ZBUFFER,false);
            Material material = new Material();
            material.Texture1= driver.GetTexture(
                path+"faerie2.bmp");
            material.Lighting=true;

            IAnimatedMeshSceneNode node = null;
            IAnimatedMesh faerie = smgr.GetMesh(
                path+"faerie.md2");
            if (faerie!=null)
            {
                node=smgr.AddAnimatedMeshSceneNode(faerie,null,0);
                node.Position=new Vector3D(-70,0,-90);
                node.SetMD2Animation(MD2AnimationType.RUN);
                node.SetMaterial(0,material);

                node=smgr.AddAnimatedMeshSceneNode(faerie,null,0);
                node.Position=new Vector3D(-70,0,-30);
                node.SetMD2Animation(MD2AnimationType.SALUTE);
                node.SetMaterial(0,material);

                node=smgr.AddAnimatedMeshSceneNode(faerie,null,0);
                node.Position=new Vector3D(-70,0,-60);
                node.SetMD2Animation(MD2AnimationType.JUMP);
                node.SetMaterial(0,material);
            }

            material.Texture1=null;
            material.Lighting=false;

            //Add a light
            smgr.AddLightSceneNode(null,new Vector3D(-60,100,400),
                new Colorf(1.0f,1.0f,1.0f,1.0f),600,0);

            /*For not making it too complicated, I'm doing picking inside the drawing
              loop. We take two pointers for storing the current and the last selected
              scene node and start the loop.*/
            ISceneNode selectedSceneNode =null;
            ISceneNode lastSelectedSceneNode =null;

            int lastFPS=-1;

            while (device.Run())
            {
                if (device.WindowActive)
                {
                    device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200));
                    device.SceneManager.DrawAll();
                    /*After we've drawn the whole scene whit smgr->drawAll(), we'll do the
                      first picking: We want to know which triangle of the world we are
                      looking at. In addition, we want the exact point of the quake 3
                      level we are looking at. For this, we create a 3d line starting at
                      the position of the camera and going through the lookAt-target of it.
                      Then we ask the collision manager if this line collides with a
                      triangle of the world stored in the triangle selector. If yes, we draw
                      the 3d triangle and set the position of the billboard to the intersection
                      point.*/
                    Line3D line = new Line3D();
                    line.start=camera.Position;
                    line.end=line.start+
                        (camera.Target - line.start).Normalize() * 1000;
                    Vector3D intersection;
                    Triangle3D tri;
                    if (smgr.SceneCollisionManager.GetCollisionPoint(
                        line,selector,out intersection, out tri))
                    {
                        bill.Position=intersection;

                        driver.SetTransform(TransformationState.WORLD, new Matrix4());
                        driver.SetMaterial(material);
                        driver.Draw3DTriangle(tri,new Color(0,255,0,0));
                    }
                    /*Another type of picking supported by the Irrlicht Engine is scene node
                      picking based on bouding boxes. Every scene node has got a bounding box,
                      and because of that, it's very fast for example to get the scene node
                      which the camera looks at. Again, we ask the collision manager for this,
                      and if we've got a scene node, we highlight it by disabling Lighting in
                      its material, if it is not the billboard or the quake 3 level.*/
                    selectedSceneNode=smgr.SceneCollisionManager.
                        GetSceneNodeFromCameraBB(camera,0);

                    if (lastSelectedSceneNode!=null)
                        lastSelectedSceneNode.SetMaterialFlag(
                            MaterialFlag.LIGHTING, true);

                    if (selectedSceneNode==q3node||
                        selectedSceneNode==bill)
                        selectedSceneNode=null;

                    if(selectedSceneNode!=null)
                        selectedSceneNode.SetMaterialFlag(
                            MaterialFlag.LIGHTING,false);
                    lastSelectedSceneNode=selectedSceneNode;

                    /*That's it, we just have to finish drawing.*/

                    driver.EndScene();

                    int fps = device.VideoDriver.FPS;
                    if (lastFPS != fps)
                    {
                        device.WindowCaption = "Irrlicht Engine - Quake 3 Map example [" +
                            device.VideoDriver.Name + "] FPS:" + fps.ToString();
                        lastFPS = fps;
                    }
                }
            }
            /*
            In the end, delete the Irrlicht device.
            */
            // Instead of device->drop, we'll use:
            GC.Collect();
        }
예제 #60
0
 public static float[] CheckLineBoxExact(Line3D line, Box3D box)
 {
     float[] dir_ = new float[3];
     dir_[0] = line.End[0] - line.Start[0];
     dir_[1] = line.End[1] - line.Start[1];
     dir_[2] = line.End[2] - line.Start[2];
     float[] hit = new float[3];
     if (!Intersection.HitBoundingBox(box.MinEdge, box.MaxEdge, line.Start, dir_, hit))
     {
         return null;
     }
     return hit;
 }