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); }
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); }
public bool isDegenerate() { if (Math.Abs((p(1) - p(0)).CrossProduct(p(2) - p(0))) < 1e-4) { return(true); } return(false); }
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); } }
/// <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); }
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); }
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; } } }
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(); } } }
/// 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()); }
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(); } } } }
// //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); }
// * // * 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); } }
protected override float animationFunction(float x) { return(Math.Abs(Math.Sin(x))); }
/// 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++; } } }