示例#1
0
        public void ResetWheels()
        {
            if (rWheelInnerNode == null || lWheelInnerNode == null)
            {
                return;
            }
            rWheelInnerNode.ResetOrientation();
            lWheelInnerNode.ResetOrientation();
            rearWheelInnerNode.ResetOrientation();


            RotateNodeAnimation ra;

            animationMgr.switchTo(PlaneNodeAnimationManager.AnimationType.L_GEAR_UP);
            ra          = (animationMgr.CurrentAnimation as RotateNodeAnimation);
            ra.MaxAngle = Math.Abs(ra.MaxAngle);

            animationMgr.switchTo(PlaneNodeAnimationManager.AnimationType.R_GEAR_UP);
            ra          = (animationMgr.CurrentAnimation as RotateNodeAnimation);
            ra.MaxAngle = Math.Abs(ra.MaxAngle);

            animationMgr.switchTo(PlaneNodeAnimationManager.AnimationType.REAR_GEAR_UP);
            ra          = (animationMgr.CurrentAnimation as RotateNodeAnimation);
            ra.MaxAngle = Math.Abs(ra.MaxAngle);
        }
示例#2
0
        private void initNonCollisionTreesDiamond(SceneManager sceneMgr, SceneNode parent, float zMin, float zMax, float intensity, bool forceLowDetails)
        {
            int   c   = (int)Math.Abs(count);
            float max = -c * LevelView.TileWidth;

            initNonCollisionTreesDiamond(sceneMgr, parent, zMin, zMax, 0.1f * max, 0.9f * max, intensity, forceLowDetails);
        }
示例#3
0
 public bool isDegenerate()
 {
     if (Math.Abs((p(1) - p(0)).CrossProduct(p(2) - p(0))) < 1e-4)
     {
         return(true);
     }
     return(false);
 }
示例#4
0
        private void initNonCollisionTreesCircle(SceneManager sceneMgr, SceneNode parent, float radius, float intensity, bool forceLowDetails)
        {
            int c       = (int)Math.Abs(count);
            int count_l = (int)(c * 2 * intensity);

            for (int i = 0; i < count_l; i++)
            {
                initPalm2(sceneMgr, parent, new Vector3(Math.RangeRandom(-radius, radius), -0.5f, Math.RangeRandom(-radius, radius) - 25), forceLowDetails);
            }
        }
示例#5
0
 /// <summary>
 /// Czy hamowanie zosta³o zakoñczone
 /// </summary>
 private bool shouldStopReleasingPlane()
 {
     for (int i = 0; i < arrestingWiresH.Length; i++)
     {
         if (Math.Abs(arrestingWiresH[i]) > 0.01f)
         {
             return(false);
         }
     }
     return(true);
 }
 //
 //ORIGINAL LINE: bool operator ()(const Ogre::Vector2& one, const Ogre::Vector2& two) const
 //C++ TO C# CONVERTER TODO TASK: The () operator cannot be overloaded in C#:
 /// <summary>
 /// 是否相等????
 /// </summary>
 /// <param name="one"></param>
 /// <param name="two"></param>
 /// <returns></returns>
 public static bool Operator(Vector2 one, Vector2 two)
 {
     if ((one - two).SquaredLength < 1e-6)
     {
         return(false);
     }
     if (Math.Abs(one.x - two.x) > 1e-3)
     {
         return(one.x < two.x);
     }
     return(one.y < two.y);
 }
示例#7
0
        private void activateClosestArrestingWires(PlaneView p)
        {
            float diff;

            for (int i = 0; i < arrestingWires.Count; i++)
            {
                diff = p.RearWheelInnerNode._getDerivedPosition().x - arrestingWires[i]._getDerivedPosition().x;
                if (Math.Abs(diff) < 0.5f && diff > 0 && !activeArrestingWires.Contains(arrestingWires[i]))
                {
                    activeArrestingWires.Add(arrestingWires[i]);
                }
            }
        }
        /// <summary>
        /// Returns which side of the plane that the given box lies on.
        /// The box is defined as centre/half-size pairs for effectively.
        /// </summary>
        /// <param name="centre">The centre of the box.</param>
        /// <param name="halfSize">The half-size of the box.</param>
        /// <returns>
        /// Positive if the box complete lies on the "positive side" of the plane,
        /// Negative if the box complete lies on the "negative side" of the plane,
        /// and Both if the box intersects the plane.
        /// </returns>
        public PlaneSide GetSide(Vector3 centre, Vector3 halfSize)
        {
            // Calculate the distance between box centre and the plane
            var dist = GetDistance(centre);
            // Calculate the maximise allows absolute distance for
            // the distance between box centre and plane
            var maxAbsDist = Math.Abs(this.Normal.DotProduct(halfSize));

            if (dist < -maxAbsDist)
            {
                return(PlaneSide.NEGATIVE_SIDE);
            }
            if (dist > +maxAbsDist)
            {
                return(PlaneSide.POSITIVE_SIDE);
            }
            return(PlaneSide.NEGATIVE_SIDE | Mogre.Plane.Side.POSITIVE_SIDE);
        }
示例#9
0
        private void initNonCollisionTreesDiamond(SceneManager sceneMgr1, SceneNode parent, float zMin, float zMax, float xMin, float xMax, float intensity, bool forceLowDetails)
        {
            int c       = (int)Math.Abs(count);
            int count_l = (int)(c * 2 * intensity);

            for (int i = 0; i < count_l; i++)
            {
                float z = Math.RangeRandom(zMin, zMax);

                if (i % 10 == 1) //Co dziesiata palma jest z wieksza iloscia trojkatow
                {
                    initPalm(sceneMgr1, parent, new Vector3(z, -0.5f, Math.RangeRandom(xMin, xMax)), forceLowDetails);
                }
                else
                {
                    initPalm2(sceneMgr1, parent, new Vector3(z, -0.5f, Math.RangeRandom(xMin, xMax)), forceLowDetails);
                }
            }
        }
        //--------------------------------------------------------------
        public void modify()
        {
            if (mInputTriangleBuffer == null)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__");
            }
            if (mHeight <= 0f)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Height must be strictly positive", "__FUNCTION__");
            }
            if (mRadius <= 0f)
            {
                OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Radius must be strictly positive", "__FUNCTION__");
            }
            ;

            float angleThreshold = Math.ATan(mHeight / mRadius).ValueRadians;

            //for (List<TriangleBuffer.Vertex>.Enumerator it = mInputTriangleBuffer.getVertices().begin(); it != mInputTriangleBuffer.getVertices().end(); ++it)
            foreach (var it in mInputTriangleBuffer.getVertices())
            {
                Vector2 nxz   = new Vector2(it.mNormal.x, it.mNormal.z);
                float   alpha = (Math.ATan(it.mNormal.y / nxz.Length).ValueRadians + Math.HALF_PI);
                if (Math.Abs(alpha) > angleThreshold)
                {
                    Vector2 vxz = new Vector2(it.mPosition.x, it.mPosition.z);
                    it.mUV = vxz / mRadius;
                }
                else
                {
                    Vector2 vxz = new Vector2(it.mPosition.x, it.mPosition.z);
                    it.mUV.x = Utils.angleTo(Vector2.UNIT_X, vxz).ValueRadians / Math.TWO_PI;
                    it.mUV.y = it.mPosition.y / mHeight - 0.5f;
                }
            }
        }
示例#11
0
        protected override void initOnScene()
        {
            BeginIslandTile tile;

            if (tileViews != null && tileViews.Count > 0 && tileViews[0].LevelTile is BeginIslandTile)
            {
                tile     = (tileViews[0].LevelTile as BeginIslandTile);
                meshName = tile.MeshName;
            }
            if (meshName == null)
            {
                return;
            }



            float margin;

            staticNode = sceneMgr.CreateSceneNode(mainNode.Name + "Static");

            if (!backgroundDummy)
            {
                count  = tileViews.Count;
                margin = 4.5f;
            }
            else
            {
                margin = 0.3f;
            }
            float maxX = -((Math.Abs(count) - 1) * LevelView.TileWidth);


            float dummyYPosition = 0;



            string meshFilename;

            switch (meshName)
            {
            case "Island1":     //5
                //ISLAND1
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, 0.7f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, 0.7f);
                break;

            case "Island1a":     //5
                //ISLAND1
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, 0.7f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, 0.7f);
                break;

            case "IslandRound":     //4
                //ISLAND ROUND
                initNonCollisionTreesCircle(sceneMgr, staticNode, 15.0f, 1.3f);
                break;

            case "Island2":     //6
                //ISLAND2
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, 0.7f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, 0.7f);
                break;

            case "Laguna":     //7
                //LAGUNA
                break;


            case "DoubleLaguna":     //8
                // DOUBLE LAGUNA
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -5.5f, 0.0f, maxX * 0.1f, maxX, 0.6f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -1.5f, 30.0f, maxX * 0.00f, maxX * 0.15f, 0.6f);

                initNonCollisionTreesDiamond(sceneMgr, staticNode, -1.5f, 30.0f, maxX * 0.85f, maxX * 1.00f, 0.6f);

                break;

            case "Island3":     //9
                //ISLAND3
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, 0.7f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, 0.7f);
                break;

            case "Island12u":     //12
                //ISLAND12u
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, maxX / 4.0f, maxX / 2.0f, 0.5f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, maxX / 4.0f, maxX / 2.0f, 0.5f);
                break;

            case "Island4":     //13
                //ISLAND4
                initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 5, 0.7f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -5, 0.7f);
                break;

            case "Island18u":     //18
                //ISLAND18u
                initNonCollisionTreesDiamond(sceneMgr, staticNode, 10, 14, maxX / 2.5f, maxX, 0.5f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -11, -13, maxX / 2.5f, maxX, 0.5f);

                // zwolnic pamiec
                EnemyFighterView epv = new EnemyFighterView(null, framework, staticNode);
                epv.PlaneNode.SetPosition(-3, 0.8f, -18 - 90);
                epv.PlaneNode.Yaw(new Radian(new Degree(60)));
                if (EngineConfig.DisplayingMinimap)
                {
                    epv.MinimapItem.Hide();
                }
                parkedPlanes.Add(epv);

                EnemyFighterView epv2 = new EnemyFighterView(null, framework, staticNode);
                epv2.PlaneNode.SetPosition(-3, 0.8f, -25 - 90);
                epv2.PlaneNode.Yaw(new Radian(new Degree(62)));
                if (EngineConfig.DisplayingMinimap)
                {
                    epv2.MinimapItem.Hide();
                }
                parkedPlanes.Add(epv2);

                initLampPosts(staticNode, -7, maxX * 0.55f, maxX * 0.95f, 12, new Radian(new Degree(0)));
                break;


            case "Island5":     //24
                //ISLAND5

                if (backgroundDummy)
                {
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, 1, 15, 0.7f);
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, -1, -15, 0.7f);
                }
                else
                {
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, margin, 15, 0.7f);
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, -margin, -15, 0.7f);
                }
                break;

            case "Island6":     //42
                //ISLAND6
                if (EngineConfig.LowDetails)
                {
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, 4.5f, 33, 0.5f);
                }
                else
                {
                    initNonCollisionTreesDiamond(sceneMgr, staticNode, 4.5f, 33, 0.9f);
                }

                initNonCollisionTreesDiamond(sceneMgr, staticNode, -4.5f, -60, 0.5f);
                initNonCollisionTreesDiamond(sceneMgr, staticNode, -4.5f, -30, 0.5f);
                break;

            case "RadarDome":
                dummyYPosition = 21;
                break;
            }

            if (EngineConfig.LowDetails && MeshManager.Singleton.ResourceExists(meshName + "_low" + ViewHelper.C_MESH_EXT))
            {
                meshFilename = "_low" + ViewHelper.C_MESH_EXT;
            }
            else
            {
                meshFilename = meshName + ViewHelper.C_MESH_EXT;
            }


            compositeModel             = sceneMgr.CreateEntity(name, meshFilename);
            compositeModel.CastShadows = false;// EngineConfig.ShadowsQuality > 0;

            //  compositeModel.SetMaterialName("Carrier");
            //      compositeModel.SetMaterialName("Carrier/Panels");

            /*
             * Mogre.Plane mPlane = new Mogre.Plane(Vector3.UNIT_Y, new Vector3(0,Mogre.Math.RangeRandom(0,1) ,0));
             *
             * MeshManager.Singleton.CreatePlane("Myplane"+this.GetHashCode(),
             *       ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, mPlane, 1000,1000,50,50,true,1,5,5,Vector3.UNIT_Z);
             *
             * Entity pPlaneEnt = sceneMgr.CreateEntity( "plane"+this.GetHashCode(), "Myplane"+this.GetHashCode() );
             *
             * compositeModel = pPlaneEnt;
             * compositeModel.SetMaterialName("Concrete");
             */
            try
            {
                if (LevelView.IsNightScene)
                {
                    ViewHelper.ReplaceMaterial(compositeModel, "Island", "IslandNight");
                }
            }
            catch (Exception)
            {
            }



            if (!backgroundDummy)
            {
                staticNode.Translate(new Vector3(UnitConverter.LogicToWorldUnits(firstTileIndex), 1.00f, 0));
                staticNode.SetDirection(Vector3.UNIT_X);
            }
            else
            {
                float angle;

                if (meshName.Equals("Island6"))
                {
                    float X = (islandCounter % 5 * 250) - 650;
                    float Z = Math.RangeRandom(-4, 0) * 70;
                    staticNode.Translate(new Vector3(-250 + Z, dummyYPosition, Math.RangeRandom(-120, 120) + X));
                    staticNode.SetDirection(Vector3.UNIT_X);
                    angle = Math.RangeRandom(0, 2 * Math.PI);
                }
                else
                {
                    staticNode.Translate(new Vector3(-450 + Math.RangeRandom(-150, 150), dummyYPosition, Math.RangeRandom(-200, 200)));
                    staticNode.SetDirection(Vector3.UNIT_X);
                    angle = Math.HALF_PI;
                }

                staticNode.Yaw(angle);
            }
            //  StaticGeometry sg;
            staticNode.AttachObject(compositeModel);

            /*
             * if (sceneMgr.HasStaticGeometry(this.name + "_StaticGeometry"))
             * {
             *  sceneMgr.DestroyStaticGeometry(this.name + "_StaticGeometry");
             * }
             * sg = new StaticGeometry(sceneMgr, this.name + "_StaticGeometry");
             * sg.Reset();
             * Vector3 sgSize = compositeModel.BoundingBox.Size;
             * sg.RegionDimensions = sgSize;
             * sg.AddSceneNode(staticNode);
             * sg.Build();
             */

            //  mainNode.SetDirection(Vector3.UNIT_X);
            //  mainNode.Position = staticNode.Position;
            mainNode.AddChild(staticNode);


            //   mainNode.AttachObject(compositeModel);
            // elementy na wyspie sa animowalne wiec nie beda w static geometry
            if (!backgroundDummy)
            {
                for (int i = 0; i < count; i++)
                {
                    tileViews[i].initOnScene(staticNode, i + 1, count);
                }

                // minimapa
                if (EngineConfig.DisplayingMinimap)
                {
                    minimapItem =
                        new MinimapItem(staticNode, framework.MinimapMgr, "Cube.mesh",
                                        new ColourValue(1, 0.9137f, 0.29f), compositeModel);
                    minimapItem.Entity.SetMaterialName("Minimap/Island");
                    minimapItem.ScaleOverride = new Vector2(count * 10.0f, 3); // stala wysokosc wyspy, niezale¿na od bounding box
                    //   minimapItem.MinimapNode.Translate(0,0,50);
                    minimapItem.Refresh();
                }
            }
        }
示例#12
0
        /// Tells whether a point is located inside that multishape
        /// It assumes that all of the shapes in that multishape are closed,
        /// and that they don't contradict each other,
        /// ie a point cannot be outside and inside at the same time
        //
        //ORIGINAL LINE: bool isPointInside(const Ogre::Vector2& point) const;
        //C++ TO C# CONVERTER TODO TASK: The implementation of the following method could not be found:
        //	bool isPointInside(Ogre::Vector2 point);
        public bool isPointInside(Vector2 point)
        {
            // Draw a horizontal lines that goes through "point"
            // Using the closest intersection, find whether the point is actually inside
            int     closestSegmentIndex        = -1;
            float   closestSegmentDistance     = float.MaxValue; //std.numeric_limits<float>.max();
            Vector2 closestSegmentIntersection = new Vector2();
            Shape   closestSegmentShape        = null;

            for (int k = 0; k < mShapes.size(); k++)
            {
                Shape shape = mShapes[k];
                for (int i = 0; i < shape.getSegCount(); i++)
                {
                    Vector2 A = shape.getPoint(i);
                    Vector2 B = shape.getPoint(i + 1);
                    if (A.y != B.y && (A.y - point.y) * (B.y - point.y) <= 0.0f)
                    {
                        Vector2 intersect = new Vector2(A.x + (point.y - A.y) * (B.x - A.x) / (B.y - A.y), point.y);
                        float   dist      = Math.Abs(point.x - intersect.x);
                        if (dist < closestSegmentDistance)
                        {
                            closestSegmentIndex    = i;
                            closestSegmentDistance = dist;
                            //
                            //ORIGINAL LINE: closestSegmentIntersection = intersect;
                            closestSegmentIntersection = (intersect);
                            closestSegmentShape        = shape;
                        }
                    }
                }
            }
            if (closestSegmentIndex != -1)
            {
                int edgePoint = -1;
                if ((closestSegmentIntersection - closestSegmentShape.getPoint(closestSegmentIndex)).SquaredLength < 1e-8)
                {
                    edgePoint = closestSegmentIndex;
                }
                else if ((closestSegmentIntersection - closestSegmentShape.getPoint(closestSegmentIndex + 1)).SquaredLength < 1e-8)
                {
                    edgePoint = closestSegmentIndex + 1;
                }
                if (edgePoint > -1)
                {
                    Radian alpha1 = Utils.angleBetween(point - closestSegmentShape.getPoint(edgePoint), closestSegmentShape.getDirectionAfter((uint)edgePoint));
                    Radian alpha2 = Utils.angleBetween(point - closestSegmentShape.getPoint(edgePoint), -closestSegmentShape.getDirectionBefore((uint)edgePoint));
                    if (alpha1 < alpha2)
                    {
                        closestSegmentIndex = edgePoint;
                    }
                    else
                    {
                        closestSegmentIndex = edgePoint - 1;
                    }
                }
                return(closestSegmentShape.getNormalAfter((uint)closestSegmentIndex).x *(point.x - closestSegmentIntersection.x) < 0f);
            }
            // We're in the case where the point is on the "float outside" of the multishape
            // So, if the float outside == user defined outside, then the point is "user-defined outside"
            return(!isOutsideRealOutside());
        }
示例#13
0
        public void updateTime(float timeSinceLastFrameUpdate)
        {
            aerialAnimation1.updateTime(timeSinceLastFrameUpdate);
            aerialAnimation1.animate();

            aerialAnimation2.updateTime(timeSinceLastFrameUpdate);
            aerialAnimation2.animate();

            if (backgroundDummy)
            {
                japanFlagState.AddTime(timeSinceLastFrameUpdate);
            }
            else
            {
                for (int i = 0; i < storagePlanes.Count; i++)
                {
                    storagePlanes[i].updateTime(timeSinceLastFrameUpdate);
                    if (storagePlanes[i].AnimationState.AnimationName == "die" && storagePlanes[i].AnimationState.HasEnded)
                    {
                        storagePlanes[i].MinimapItem.Hide();
                        storagePlanes.Remove(storagePlanes[i]);
                    }
                }

                for (int i = 0; i < crewAnimationStates.Length; i++)
                {
                    crewAnimationStates[i].AddTime(timeSinceLastFrameUpdate);
                }

                // hangar
                if (isHangaringPlane)
                {
                    float targetDepth = hangarDepth * hangaringDirection;
                    float progress    = 1 - (targetDepth - carrierHangarNode.Position.y) / targetDepth;
                    float step        = 3.0f * timeSinceLastFrameUpdate * hangaringDirection; //* Math.Cos(Math.HALF_PI * progress);

                    progress = Math.Abs(progress);
                    step    *= 1 / (1 + (float)System.Math.Pow((-1.5f + 3.0f * progress), 2)) * 0.75f; // p³ynne przyspieszenie i hamowanie wg. pochodniej arctan ktora wynosi 1 / (1 + x^2)

                    carrierHangarNode.Position = carrierHangarNode.Position + new Vector3(0, step, 0);
                    hangarPlane.Plane.Bounds.Move(0, step);

                    if (hangaringDirection == -1)
                    {
                        // opuszczanie
                        if (carrierHangarNode.Position.y < targetDepth)
                        {
                            hangarPlane.Plane.Bounds.Move(0, carrierHangarNode.Position.y - targetDepth);
                            carrierHangarNode.SetPosition(0, targetDepth, 0);
                            isHangaringPlane = false;
                        }
                    }
                    else
                    {
                        // podnoszenie
                        if (carrierHangarNode.Position.y >= 0)
                        {
                            carrierHangarNode.SetPosition(0, 0, 0);
                            hangarPlane.Plane.Bounds.Move(0, -carrierHangarNode.Position.y);
                            isHangaringFinished = true;
                            isHangaringPlane    = false;
                        }
                    }
                }



                if (isCatchingPlane)
                {
                    activateClosestArrestingWires(planeBeingCaught); // zaczepiaj samolot o kolejne liny
                    for (int i = 0; i < activeArrestingWires.Count; i++)
                    {
                        arrestingWiresH[i] =
                            animateArrestingWire(activeArrestingWires[i],
                                                 planeBeingCaught.RearWheelInnerNode._getDerivedPosition().x);
                    }
                }
                if (isReleasingPlane)
                {
                    if (!shouldStopReleasingPlane())
                    {
                        for (int i = 0; i < activeArrestingWires.Count; i++)
                        {
                            animateArrestingWire(
                                activeArrestingWires[i],
                                activeArrestingWires[i]._getDerivedPosition().x - arrestingWiresH[i]
                                );
                            arrestingWiresH[i] *= (1 - 10 * timeSinceLastFrameUpdate);
                            // 0.99f; - wymuszamy zmniejszenie wysokosci trojkatow
                        }
                    }
                    else
                    {
                        // koniec
                        finishReleasingPlane();
                    }
                }
            }
        }
示例#14
0
        //
        //ORIGINAL LINE: void delaunay(List<Ogre::Vector2>& pointList, LinkedList<Triangle>& tbuffer) const
        void delaunay(PointList pointList, ref DelaunayTriangleBuffer tbuffer)
        {
            // Compute super triangle or insert manual super triangle
            if (mManualSuperTriangle != null)
            {
                float maxTriangleSize = 0.0f;
                //for (PointList::iterator it = pointList.begin(); it!=pointList.end(); ++it)
                foreach (Vector2 it in pointList)
                {
                    maxTriangleSize = max(maxTriangleSize, Math.Abs(it.x));
                    maxTriangleSize = max(maxTriangleSize, Math.Abs(it.y));
                }
                pointList.push_back(new Vector2(-3f * maxTriangleSize, -3f * maxTriangleSize));
                pointList.push_back(new Vector2(3f * maxTriangleSize, -3f * maxTriangleSize));
                pointList.push_back(new Vector2(0.0f, 3 * maxTriangleSize));

                int      maxTriangleIndex = pointList.size() - 3;
                Triangle superTriangle    = new Triangle(pointList);
                superTriangle.i[0] = maxTriangleIndex;
                superTriangle.i[1] = maxTriangleIndex + 1;
                superTriangle.i[2] = maxTriangleIndex + 2;
                tbuffer.push_back(superTriangle);
            }

            // Point insertion loop
            for (int i = 0; i < pointList.size() - 3; i++)
            {
                //Utils::log("insert point " + StringConverter::toString(i));
                //std::list<std::list<Triangle>::iterator> borderlineTriangles;
                std_list <Triangle> borderlineTriangles = new std_list <Triangle>();
                // Insert 1 point, find all triangles for which the point is in circumcircle
                Vector2 p = pointList[i];
                //std::set<DelaunaySegment> segments;
                std_set <DelaunaySegment> segments = new std_set <DelaunaySegment>();
                IEnumerator <Triangle>    et       = tbuffer.GetEnumerator();
                //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                List <Triangle> need_erase = new List <Triangle>();
                while (et.MoveNext())
                {
                    Triangle            it       = et.Current;
                    Triangle.InsideType isInside = it.isPointInsideCircumcircle(p);
                    if (isInside == Triangle.InsideType.IT_INSIDE)
                    {
                        if (!it.isDegenerate())
                        {
                            //Utils::log("tri insie" + it->debugDescription());
                            for (int k = 0; k < 3; k++)
                            {
                                DelaunaySegment d1 = new DelaunaySegment(it.i[k], it.i[(k + 1) % 3]);
                                if (segments.find(d1) != segments.end())
                                {
                                    segments.erase(d1);
                                }
                                else if (segments.find(d1.inverse()) != segments.end())
                                {
                                    segments.erase(d1.inverse());
                                }
                                else
                                {
                                    segments.insert(d1);
                                }
                            }
                        }
                        //it=tbuffer.erase(it);
                        need_erase.Add(it);
                    }
                    else if (isInside == Triangle.InsideType.IT_BORDERLINEOUTSIDE)
                    {
                        //Utils::log("tri borer " + it->debugDescription());
                        borderlineTriangles.push_back(it);
                        //++it;
                    }
                    else
                    {
                        //++it;
                    }
                }
                //do delete
                foreach (var v in need_erase)
                {
                    tbuffer.Remove(v);
                }

                // Robustification of the standard algorithm : if one triangle's circumcircle was borderline against the new point,
                // test whether that triangle is intersected by new segments or not (normal situation : it should not)
                // If intersected, the triangle is considered having the new point in its circumc
                std_set <DelaunaySegment> copySegment = segments;
                IEnumerator <Triangle>    be          = borderlineTriangles.GetEnumerator();
                //for (std::list<std::list<Triangle>::iterator>::iterator itpTri = borderlineTriangles.begin(); itpTri!=borderlineTriangles.end(); itpTri++ )
                while (be.MoveNext())
                {
                    Triangle itpTri = be.Current;
                    //DelaunayTriangleBuffer::iterator itTri = *itpTri;
                    Triangle itTri      = itpTri;
                    bool     triRemoved = false;
                    //for (std::set<DelaunaySegment>::iterator it = copySegment.begin(); it!=copySegment.end() && !triRemoved; ++it)
                    IEnumerator <DelaunaySegment> cse = copySegment.GetEnumerator();
                    while (cse.MoveNext() && !triRemoved)
                    {
                        DelaunaySegment it = cse.Current;
                        bool            isTriangleIntersected = false;
                        for (int k = 0; k < 2; k++)
                        {
                            int i1 = (k == 0) ? it.i1 : it.i2;
                            int i2 = i;
                            for (int l = 0; l < 3; l++)
                            {
                                //Early out if 2 points are in fact the same
                                if (itTri.i[l] == i1 || itTri.i[l] == i2 || itTri.i[(l + 1) % 3] == i1 || itTri.i[(l + 1) % 3] == i2)
                                {
                                    continue;
                                }
                                Segment2D seg2 = new Segment2D(itTri.p(l), itTri.p((l + 1) % 3));
                                Segment2D seg1 = new Segment2D(pointList[i1], pointList[i2]);
                                if (seg1.intersects(seg2))
                                {
                                    isTriangleIntersected = true;
                                    break;
                                }
                            }
                        }
                        if (isTriangleIntersected)
                        {
                            if (!itTri.isDegenerate())
                            {
                                //Utils::log("tri inside" + itTri->debugDescription());
                                for (int m = 0; m < 3; m++)
                                {
                                    DelaunaySegment d1 = new DelaunaySegment(itTri.i[m], itTri.i[(m + 1) % 3]);
                                    if (segments.find(d1) != segments.end())
                                    {
                                        segments.erase(d1);
                                    }
                                    else if (segments.find(d1.inverse()) != segments.end())
                                    {
                                        segments.erase(d1.inverse());
                                    }
                                    else
                                    {
                                        segments.insert(d1);
                                    }
                                }
                            }
                            //tbuffer.erase(itTri);
                            need_erase.Clear();
                            need_erase.Add(itTri);
                            triRemoved = true;
                        }
                    }
                }
                //do delete
                foreach (var v in need_erase)
                {
                    tbuffer.Remove(v);
                }
                // Find all the non-interior edges
                IEnumerator <DelaunaySegment> seg_ie = segments.GetEnumerator();
                //for (std::set<DelaunaySegment>::iterator it = segments.begin(); it!=segments.end(); ++it)
                while (seg_ie.MoveNext())
                {
                    DelaunaySegment it = seg_ie.Current;
                    //Triangle dt(&pointList);
                    Triangle dt = new Triangle(pointList);
                    dt.setVertices(it.i1, it.i2, i);
                    dt.makeDirectIfNeeded();
                    //Utils::log("Add tri " + dt.debugDescription());
                    tbuffer.push_back(dt);
                }
            }

            // NB : Don't remove super triangle here, because all outer triangles are already removed in the addconstraints method.
            //      Uncomment that code if delaunay triangulation ever has to be unconstrained...

            /*TouchSuperTriangle touchSuperTriangle(maxTriangleIndex, maxTriangleIndex+1,maxTriangleIndex+2);
             * tbuffer.remove_if(touchSuperTriangle);
             * pointList.pop_back();
             * pointList.pop_back();
             * pointList.pop_back();*/
        }
        //
        //ORIGINAL LINE: bool findIntersect(const Triangle3D& STLAllocator<U, AllocPolicy>, Segment3D& intersection) const
        public bool findIntersect(Triangle3D triangle3d, ref Segment3D intersection)
        {
            // Compute plane equation of first triangle
            Vector3 e1 = mPoints[1] - mPoints[0];
            Vector3 e2 = mPoints[2] - mPoints[0];
            Vector3 n1 = e1.CrossProduct(e2);
            float   d1 = -n1.DotProduct(mPoints[0]);

            // Put second triangle in first plane equation to compute distances to the plane
            float[] du = new float[3];
            for (short i = 0; i < 3; i++)
            {
                du[i] = n1.DotProduct(triangle3d.mPoints[i]) + d1;
                if (Math.Abs(du[i]) < 1e-6)
                {
                    du[i] = 0.0f;
                }
            }

            float du0du1 = du[0] * du[1];
            float du0du2 = du[0] * du[2];

            if (du0du1 > 0.0f && du0du2 > 0.0f) // same sign on all of them + not equal 0 ?
            {
                return(false);                  // no intersection occurs
            }
            // Compute plane equation of first triangle
            e1 = triangle3d.mPoints[1] - triangle3d.mPoints[0];
            e2 = triangle3d.mPoints[2] - triangle3d.mPoints[0];
            Vector3 n2 = e1.CrossProduct(e2);
            float   d2 = -n2.DotProduct(triangle3d.mPoints[0]);

            // Put first triangle in second plane equation to compute distances to the plane
            float[] dv = new float[3];
            for (short i = 0; i < 3; i++)
            {
                dv[i] = n2.DotProduct(mPoints[i]) + d2;
                if (Math.Abs(dv[i]) < 1e-6)
                {
                    dv[i] = 0.0f;
                }
            }

            float dv0dv1 = dv[0] * dv[1];
            float dv0dv2 = dv[0] * dv[2];

            if (dv0dv1 > 0.0f && dv0dv2 > 0.0f) // same sign on all of them + not equal 0 ?
            {
                return(false);                  // no intersection occurs
            }
            //Compute the direction of intersection line
            Vector3 d = n1.CrossProduct(n2);

            // We don't do coplanar triangles
            if (d.SquaredLength < 1e-6)
            {
                return(false);
            }

            // Project triangle points onto the intersection line

            // compute and index to the largest component of D
            float max   = Math.Abs(d[0]);
            int   index = 0;
            float b     = Math.Abs(d[1]);
            float c     = Math.Abs(d[2]);

            if (b > max)
            {
                max   = b;
                index = 1;
            }
            if (c > max)
            {
                max   = c;
                index = 2;
            }
            // this is the simplified projection onto L
            float vp0 = mPoints[0][index];
            float vp1 = mPoints[1][index];
            float vp2 = mPoints[2][index];

            float up0 = triangle3d.mPoints[0][index];
            float up1 = triangle3d.mPoints[1][index];
            float up2 = triangle3d.mPoints[2][index];

            float[] isect1 = new float[2];
            float[] isect2 = new float[2];
            // compute interval for triangle 1
            GlobalMembers.computeIntervals(vp0, vp1, vp2, dv[0], dv[1], dv[2], dv0dv1, dv0dv2, ref isect1[0], ref isect1[1]);

            // compute interval for triangle 2
            GlobalMembers.computeIntervals(up0, up1, up2, du[0], du[1], du[2], du0du1, du0du2, ref isect2[0], ref isect2[1]);

            if (isect1[0] > isect1[1])
            {
                std_array_swap <float>(isect1, 0, 1);
            }
            if (isect2[0] > isect2[1])
            {
                std_array_swap <float>(isect2, 0, 1);
            }

            if (isect1[1] < isect2[0] || isect2[1] < isect1[0])
            {
                return(false);
            }

            // Deproject segment onto line
            float r1 = System.Math.Max(isect1[0], isect2[0]);
            float r2 = System.Math.Min(isect1[1], isect2[1]);

            Plane pl1       = new Plane(n1.x, n1.y, n1.z, d1);
            Plane pl2       = new Plane(n2.x, n2.y, n2.z, d2);
            Line  interLine = new Line();

            pl1.intersect(pl2, ref interLine);
            Vector3 p = interLine.mPoint;

            //d.Normalise();
            d = d.NormalisedCopy;
            Vector3 v1 = p + (r1 - p[index]) / d[index] * d;
            Vector3 v2 = p + (r2 - p[index]) / d[index] * d;

            intersection.mA = v1;
            intersection.mB = v2;


            return(true);
        }
示例#16
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            std_vector <Vector3> vertices = new  std_vector <Vector3>();
            int offset = 0;

            /// Step 1 : Generate icosahedron
            float phi     = 0.5f * (1.0f + Math.Sqrt(5.0f));
            float invnorm = 1f / Math.Sqrt(phi * phi + 1f);

            vertices.push_back(invnorm * new Vector3(-1f, phi, 0f));  //0
            vertices.push_back(invnorm * new Vector3(1f, phi, 0f));   //1
            vertices.push_back(invnorm * new Vector3(0f, 1f, -phi));  //2
            vertices.push_back(invnorm * new Vector3(0f, 1f, phi));   //3
            vertices.push_back(invnorm * new Vector3(-phi, 0f, -1f)); //4
            vertices.push_back(invnorm * new Vector3(-phi, 0f, 1f));  //5
            vertices.push_back(invnorm * new Vector3(phi, 0f, -1f));  //6
            vertices.push_back(invnorm * new Vector3(phi, 0f, 1f));   //7
            vertices.push_back(invnorm * new Vector3(0f, -1f, -phi)); //8
            vertices.push_back(invnorm * new Vector3(0f, -1f, phi));  //9
            vertices.push_back(invnorm * new Vector3(-1f, -phi, 0f)); //10
            vertices.push_back(invnorm * new Vector3(1f, -phi, 0f));  //11

            int[] firstFaces = { 0,   1,  2,
                                 0,   3,  1,
                                 0,   4,  5,
                                 1,   7,  6,
                                 1,   6,  2,
                                 1,   3,  7,
                                 0,   2,  4,
                                 0,   5,  3,
                                 2,   6,  8,
                                 2,   8,  4,
                                 3,   5,  9,
                                 3,   9,  7,
                                 11,  6,  7,
                                 10,  5,  4,
                                 10,  4,  8,
                                 10,  9,  5,
                                 11,  8,  6,
                                 11,  7,  9,
                                 10,  8, 11,
                                 10, 11, 9 };

            //C++ TO C# CONVERTER WARNING: This 'sizeof' ratio was replaced with a direct reference to the array length:
            //ORIGINAL LINE: std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces));
            // 定义一个容纳100个int型数据的容器,初值赋为0
            //vector<int> vecMyHouse(100,0);
            std_vector <int> faces = new  std_vector <int>(firstFaces);//(firstFaces, firstFaces + firstFaces.Length);

            int size = 60;

            /// Step 2 : tessellate
            for (ushort iteration = 0; iteration < mNumIterations; iteration++)
            {
                size *= 4;
                std_vector <int> newFaces = new std_vector <int>();
                newFaces.Clear();
                //newFaces.resize(size);
                for (int i = 0; i < size / 12; i++)
                {
                    int     i1  = faces[i * 3];
                    int     i2  = faces[i * 3 + 1];
                    int     i3  = faces[i * 3 + 2];
                    int     i12 = vertices.Count;
                    int     i23 = i12 + 1;
                    int     i13 = i12 + 2;
                    Vector3 v1  = vertices[i1];
                    Vector3 v2  = vertices[i2];
                    Vector3 v3  = vertices[i3];
                    //make 1 vertice at the center of each edge and project it onto the sphere
                    vertices.push_back((v1 + v2).NormalisedCopy);
                    vertices.push_back((v2 + v3).NormalisedCopy);
                    vertices.push_back((v1 + v3).NormalisedCopy);
                    //now recreate indices
                    newFaces.push_back(i1);
                    newFaces.push_back(i12);
                    newFaces.push_back(i13);
                    newFaces.push_back(i2);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i3);
                    newFaces.push_back(i13);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i23);
                    newFaces.push_back(i13);
                }
                //faces.swap(newFaces);
                faces = newFaces;
            }

            /// Step 3 : generate texcoords
            std_vector <Vector2> texCoords = new std_vector <Vector2>();

            for (ushort i = 0; i < vertices.size(); i++)
            {
                Vector3 vec   = vertices[i];
                float   u     = 0f;
                float   v     = 0f;
                float   r0    = sqrtf(vec.x * vec.x + vec.z * vec.z);
                float   alpha = 0f;
                alpha = atan2f(vec.z, vec.x);
                u     = alpha / Math.TWO_PI + .5f;
                v     = atan2f(vec.y, r0) / Math.PI + .5f;
                texCoords.push_back(new Vector2(u, v));
            }

            /// Step 4 : fix texcoords
            // find vertices to split
            std_vector <int> indexToSplit = new  std_vector <int>();

            for (int i = 0; i < faces.size() / 3; i++)
            {
                Vector2 t0 = texCoords[faces[i * 3 + 0]];
                Vector2 t1 = texCoords[faces[i * 3 + 1]];
                Vector2 t2 = texCoords[faces[i * 3 + 2]];
                if (Math.Abs(t2.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
                if (Math.Abs(t1.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                }
                if (Math.Abs(t2.x - t1.x) > 0.5)
                {
                    if (t1.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
            }

            //split vertices
            for (ushort i = 0; i < indexToSplit.size(); i++)
            {
                int index = indexToSplit[i];
                //duplicate vertex
                Vector3 v = vertices[index];
                Vector2 t = texCoords[index] + Vector2.UNIT_X;
                vertices.push_back(v);
                texCoords.push_back(t);
                int newIndex = vertices.size() - 1;
                //reassign indices
                for (ushort j = 0; j < faces.size(); j++)
                {
                    if (faces[j] == index)
                    {
                        int index1 = faces[(j + 1) % 3 + (j / 3) * 3];
                        int index2 = faces[(j + 2) % 3 + (j / 3) * 3];
                        if ((texCoords[index1].x > 0.5f) || (texCoords[index2].x > 0.5f))
                        {
                            faces[j] = newIndex;
                        }
                    }
                }
            }

            /// Step 5 : realize
            buffer.rebaseOffset();
            buffer.estimateVertexCount((uint)vertices.size());
            buffer.estimateIndexCount((uint)size);

            for (ushort i = 0; i < vertices.size(); i++)
            {
                addPoint(ref buffer, mRadius * vertices[i], vertices[i], new Vector2(texCoords[i].x, texCoords[i].y));
            }
            for (ushort i = 0; i < size; i++)
            {
                buffer.index(offset + faces[i]);
            }
            offset += vertices.size();
        }
        //-----------------------------------------------------------------------
        //typedef std::vector<PathCoordinate> PathIntersection;
        public static void _extrudeIntersectionImpl(ref TriangleBuffer buffer, std_vector <MultiPath.PathCoordinate> intersection, MultiPath multiPath, Shape shape, Track shapeTextureTrack)
        {
            Vector3    intersectionLocation = multiPath.getPath((int)intersection[0].pathIndex).getPoint((int)intersection[0].pointIndex);
            Quaternion firstOrientation     = Utils._computeQuaternion(multiPath.getPath((int)intersection[0].pathIndex).getDirectionBefore((int)intersection[0].pointIndex));
            Vector3    refX = firstOrientation * Vector3.UNIT_X;
            Vector3    refZ = firstOrientation * Vector3.UNIT_Z;

            std_vector <Vector2> v2s = new std_vector <Vector2>();
            std_vector <MultiPath.PathCoordinate> coords = new std_vector <MultiPath.PathCoordinate>();
            std_vector <float> direction = new std_vector <float>();

            for (int i = 0; i < intersection.size(); ++i)
            {
                Path path       = multiPath.getPath((int)intersection[i].pathIndex);
                int  pointIndex = (int)intersection[i].pointIndex;
                if (pointIndex > 0 || path.isClosed())
                {
                    Vector3 vb  = path.getDirectionBefore(pointIndex);
                    Vector2 vb2 = new Vector2(vb.DotProduct(refX), vb.DotProduct(refZ));
                    v2s.push_back(vb2);
                    coords.push_back(intersection[i]);
                    direction.push_back(1);
                }
                if (pointIndex < path.getSegCount() || path.isClosed())
                {
                    Vector3 va  = -path.getDirectionAfter(pointIndex);
                    Vector2 va2 = new Vector2(va.DotProduct(refX), va.DotProduct(refZ));
                    v2s.push_back(va2);
                    coords.push_back(intersection[i]);
                    direction.push_back(-1);
                }
            }

            std_map <Radian, int> angles = new std_map <Radian, int>();

            for (int i = 1; i < v2s.Count; ++i)
            {
                //angles[Utils.angleTo(v2s[0], v2s[i])] = i;
                angles.insert(Utils.angleTo(v2s[0], v2s[i]), i);
            }
            std_vector <int> orderedIndices = new std_vector <int>();

            orderedIndices.push_back(0);
            //for (std_map<Radian, int>.Enumerator it = angles.begin(); it != angles.end(); ++it)
            foreach (var it in angles)
            {
                orderedIndices.push_back(it.Value);
            }
            for (int i = 0; i < orderedIndices.size(); ++i)
            {
                int    idx         = orderedIndices[i];
                int    idxBefore   = orderedIndices[Utils.modulo(i - 1, orderedIndices.Count)];
                int    idxAfter    = orderedIndices[Utils.modulo(i + 1, orderedIndices.Count)];
                Radian angleBefore = (Utils.angleBetween(v2s[idx], v2s[idxBefore]) - (Radian)Math.PI) / 2;
                Radian angleAfter  = ((Radian)Math.PI - Utils.angleBetween(v2s[idx], v2s[idxAfter])) / 2;

                int  pointIndex = (int)((int)coords[idx].pointIndex - direction[idx]);
                Path path       = multiPath.getPath((int)coords[idx].pathIndex);

                Quaternion qStd      = Utils._computeQuaternion(path.getAvgDirection(pointIndex) * direction[idx]);
                float      lineicPos = 0f;
                float      uTexCoord = path.getLengthAtPoint(pointIndex) / path.getTotalLength();

                // Shape making the joint with "standard extrusion"
                _extrudeShape(ref buffer, shape, path.getPoint(pointIndex), qStd, qStd, 1.0f, 1.0f, 1.0f, shape.getTotalLength(), uTexCoord, true, shapeTextureTrack);

                // Modified shape at the intersection
                Quaternion q = new Quaternion();
                if (direction[idx] > 0f)
                {
                    q = Utils._computeQuaternion(path.getDirectionBefore((int)coords[idx].pointIndex));
                }
                else
                {
                    q = Utils._computeQuaternion(-path.getDirectionAfter((int)coords[idx].pointIndex));
                }
                Quaternion qLeft      = q * new Quaternion(angleBefore, Vector3.UNIT_Y);
                Quaternion qRight     = q * new Quaternion(angleAfter, Vector3.UNIT_Y);
                float      scaleLeft  = 1.0f / Math.Abs(Math.Cos(angleBefore));
                float      scaleRight = 1.0f / Math.Abs(Math.Cos(angleAfter));

                uTexCoord = path.getLengthAtPoint((int)coords[idx].pointIndex) / path.getTotalLength();
                _extrudeShape(ref buffer, shape, path.getPoint((int)coords[idx].pointIndex), qLeft, qRight, 1.0f, scaleLeft, scaleRight, shape.getTotalLength(), uTexCoord, false, shapeTextureTrack);
            }
        }
示例#18
0
 protected override float animationFunction(float x)
 {
     return(Math.Abs(Math.Sin(x)));
 }
示例#19
0
        /// Internal. Builds an "edge" of the rounded box, ie a quarter cylinder

        //*
        // * xPos,yPos,zPos : 1 => positive
        //					-1 => negative
        //					0 => undefined
        //
        //
        //ORIGINAL LINE: void _addEdge(TriangleBuffer& buffer, short xPos, short yPos, short zPos) const
        private void _addEdge(ref TriangleBuffer buffer, short xPos, short yPos, short zPos)
        {
            int offset = 0;

            Vector3 centerPosition = 0.5f * xPos * mSizeX * Vector3.UNIT_X + .5f * yPos * mSizeY * Vector3.UNIT_Y + .5f * zPos * mSizeZ * Vector3.UNIT_Z;
            Vector3 vy0            = (1.0f - Math.Abs(xPos)) * Vector3.UNIT_X + (1.0f - Math.Abs(yPos)) * Vector3.UNIT_Y + (1.0f - Math.Abs(zPos)) * Vector3.UNIT_Z; //extrusion direction

            Vector3 vx0 = Utils.vectorAntiPermute(vy0);
            Vector3 vz0 = Utils.vectorPermute(vy0);

            if (vx0.DotProduct(centerPosition) < 0.0)
            {
                vx0 = -vx0;
            }
            if (vz0.DotProduct(centerPosition) < 0.0)
            {
                vz0 = -vz0;
            }
            if (vx0.CrossProduct(vy0).DotProduct(vz0) < 0.0)
            {
                vy0 = -vy0;
            }

            float   height         = (1 - Math.Abs(xPos)) * mSizeX + (1 - Math.Abs(yPos)) * mSizeY + (1 - Math.Abs(zPos)) * mSizeZ;
            Vector3 offsetPosition = centerPosition - .5f * height * vy0;
            int     numSegHeight   = 1;

            if (xPos == 0)
            {
                numSegHeight = mNumSegX;
            }
            else if (yPos == 0)
            {
                numSegHeight = mNumSegY;
            }
            else if (zPos == 0)
            {
                numSegHeight = mNumSegZ;
            }

            float deltaAngle  = (Math.HALF_PI / mChamferNumSeg);
            float deltaHeight = height / (float)numSegHeight;


            buffer.rebaseOffset();
            buffer.estimateIndexCount((uint)(6 * numSegHeight * mChamferNumSeg));
            buffer.estimateVertexCount((uint)((numSegHeight + 1) * (mChamferNumSeg + 1)));

            for (ushort i = 0; i <= numSegHeight; i++)
            {
                for (ushort j = 0; j <= mChamferNumSeg; j++)
                {
                    float x0 = mChamferSize * cosf(j * deltaAngle);
                    float z0 = mChamferSize * sinf(j * deltaAngle);
                    //addPoint(ref buffer, new Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition), (x0 * vx0 + z0 * vz0).NormalisedCopy, new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight));


                    //addPoint(buffer, Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition),
                    // (x0 * vx0 + z0 * vz0).normalisedCopy(),
                    // Vector2(j / (Real)mChamferNumSeg, i / (Real)numSegHeight));

                    addPoint(ref buffer,
                             (x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition),
                             (x0 * vx0 + z0 * vz0).NormalisedCopy,
                             new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight)
                             );
                    if (i != numSegHeight && j != mChamferNumSeg)
                    {
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset);
                        buffer.index(offset + mChamferNumSeg + 1);
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }
        }