public static Vector3 Interp(Path pts, float t, EasingType ease = EasingType.Linear, bool easeIn = true, bool easeOut = true) { t = Ease(t, ease, easeIn, easeOut); if (pts.Length == 0) { return(Vector3.zero); } else if (pts.Length == 1) { return(pts[0]); } else if (pts.Length == 2) { return(Vector3.Lerp(pts[0], pts[1], t)); } else if (pts.Length == 3) { return(QuadBez.Interp(pts[0], pts[2], pts[1], t)); } else if (pts.Length == 4) { return(CubicBez.Interp(pts[0], pts[3], pts[1], pts[2], t)); } else { return(CRSpline.Interp(Wrap(pts), t)); } }
public static Vector3 Interp(Path pts, float t, Easing.EaseType easeType = Easing.EaseType.linear) { t = Easing.ease(easeType, t); if (pts.Length == 0) { return(Vector3.zero); } else if (pts.Length == 1) { return(pts[0]); } else if (pts.Length == 2) { return(Vector3.Lerp(pts[0], pts[1], t)); } else if (pts.Length == 3) { return(QuadBez.Interp(pts[0], pts[2], pts[1], t)); } else if (pts.Length == 4) { return(CubicBez.Interp(pts[0], pts[3], pts[1], pts[2], t)); } else { return(CRSpline.Interp(Wrap(pts), t)); } }
public static void GizmoDraw(Vector3[] pts, float t) { Gizmos.color = Color.white; Vector3 to = CRSpline.Interp(pts, 0f); for (int i = 1; i <= 20; i++) { float t2 = (float)i / 20f; Vector3 vector = CRSpline.Interp(pts, t2); Gizmos.DrawLine(vector, to); to = vector; } Gizmos.color = Color.blue; Vector3 vector2 = CRSpline.Interp(pts, t); Gizmos.DrawLine(vector2, vector2 + CRSpline.Velocity(pts, t)); }
public void DistributeNodes() { int numNodes = path.Count; //if (numNodes<5) return; Vector3[] newpositions = new Vector3[numNodes]; Vector3[] positions = new Vector3[numNodes]; for(int i=0; i<positions.Length; i++) { if( path[i] != null ) positions[i] = path[i].position; } CRSpline posSpline = new CRSpline( positions ); for (int a=1; a<positions.Length-1; a++) { float p = (1.0f / ((float)numNodes-3.0f)) * (a-1); //Debug.Log(p+","+getT( splineLenght*p )); newpositions[a] = posSpline.Interp(getT( splineLenght*p )); } for (int a=1; a<positions.Length-1; a++) path[a].position = newpositions[a]; }
void generateMesh() { if(meshPrefab==null) return; List<Vector3> vertices=new List<Vector3>(); List<int>[] triangles=new List<int>[3]; triangles[0]=new List<int>(); triangles[1]=new List<int>(); triangles[2]=new List<int>(); List<Vector2> uv=new List<Vector2>(); List<Vector3> normals=new List<Vector3>(); List<Vector4> tangents=new List<Vector4>(); CRSpline posSpline = new CRSpline( path.getPositions() ); //CRSpline rotSpline = new CRSpline( path.getRotations() ); Mesh[] mesh=new Mesh[3]; mesh[0]=meshPrefab.FindChild("start").GetComponent<MeshFilter>().sharedMesh; mesh[1]=meshPrefab.FindChild("middle").GetComponent<MeshFilter>().sharedMesh; mesh[2]=meshPrefab.FindChild("end").GetComponent<MeshFilter>().sharedMesh; Vector3[][] meshVertices=new Vector3[3][]; int[][] meshTriangles=new int[3][]; Vector2[][] meshUv=new Vector2[3][]; Vector3[][] meshNormals=new Vector3[3][]; Vector4[][] meshTangents=new Vector4[3][]; float[] max=new float[3]; for(int i=0;i<3;i++) { meshVertices[i]=mesh[i].vertices; meshTriangles[i]=mesh[i].GetTriangles(0); meshUv[i]=mesh[i].uv; meshNormals[i]=mesh[i].normals; meshTangents[i]=mesh[i].tangents; for(int vi=0;vi<meshTriangles[i].Length;vi++) { if(meshVertices[i][meshTriangles[i][vi]].x>max[i]) max[i]=meshVertices[i][meshTriangles[i][vi]].x; } } float cursor=0; int vertI=0; int meshI=0; if(path.round) meshI=1; bool last=false; //float scale=1; while(true) { if(meshI==2) break; if(getT(cursor+max[meshI])<1.0f || last) { if(last) { //scale=1.0f/(getT(cursor+max[meshI])-getT(cursor))*(1.0f-getT(cursor)); } if(getT(cursor+max[meshI]+max[2])>1.0f && !path.round) meshI=2; for(int i=0;i<meshTriangles[meshI].Length;i++) { triangles[meshI].Add(vertI+meshTriangles[meshI][i]); } vertI+=mesh[meshI].vertexCount; for(int i=0;i<meshVertices[meshI].Length;i++) { float vertexCursor=cursor+Mathf.Max(meshVertices[meshI][i].x,0); float t=getT(vertexCursor); Vector3 vPos=posSpline.Interp(t); Vector3 look=posSpline.Velocity(t).normalized; Quaternion r=Quaternion.LookRotation(look); r=Quaternion.Euler(0,-90,0)*Quaternion.Euler(r.eulerAngles.z,(r.eulerAngles.y),-r.eulerAngles.x); Vector3 localVert=meshVertices[meshI][i]; localVert.x=0; Vector3 vert=(r*localVert)+(vPos-transform.position); //vert.x-=middleVertices[i].x; //Debug.Log(t); vertices.Add(vert); uv.Add(meshUv[meshI][i]); normals.Add(r*meshNormals[meshI][i]); tangents.Add(r*meshTangents[meshI][i]); } //Debug.Log(max); cursor+=max[meshI]; if(meshI==0) meshI=1; if(last) break; } else { if(!last) last=true; else break; } } Mesh finalMesh=new Mesh(); finalMesh.vertices=vertices.ToArray(); finalMesh.subMeshCount=3; finalMesh.SetTriangles(triangles[0].ToArray(),0); finalMesh.SetTriangles(triangles[1].ToArray(),1); finalMesh.SetTriangles(triangles[2].ToArray(),2); finalMesh.uv=uv.ToArray(); finalMesh.normals=normals.ToArray(); finalMesh.tangents=tangents.ToArray(); GetComponent<MeshFilter>().sharedMesh=finalMesh; Material[] sharedMaterials=new Material[3]; sharedMaterials[0]=meshPrefab.FindChild("start").GetComponent<MeshRenderer>().sharedMaterial; sharedMaterials[1]=meshPrefab.FindChild("middle").GetComponent<MeshRenderer>().sharedMaterial; sharedMaterials[2]=meshPrefab.FindChild("end").GetComponent<MeshRenderer>().sharedMaterial; GetComponent<Renderer>().sharedMaterials=sharedMaterials; }
//通用运动驱动函数 public void Move(float current_time, float speed_rate, float delta_time) //接口方法 { if (TimeRate(current_time) > 1.001f || current_time > EndTime) { return; } else { lastFrameTime = current_time; } if (CurrentMotion == MotionType.MoveOnly) { //匀速直线运动 ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.Self); } else if (CurrentMotion == MotionType.WorldMove) { //在世界坐标内移动 ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.World); } else if (CurrentMotion == MotionType.AccelerateMove) { //匀加速直线运动 ParentTrans.localPosition = StartPos + SpeedVector * (current_time - StartTime) * speed_rate + 0.5f * AccelerateVec * ((current_time - StartTime) * speed_rate) * ((current_time - StartTime) * speed_rate); } else if (CurrentMotion == MotionType.RotateOnly) { //旋转运动 ParentTrans.RotateAround(RotateCenter, RotateAxis, RotateSpeed * delta_time * speed_rate); } else if (CurrentMotion == MotionType.MoveRotateSingle) { //平移+旋转,围绕某一个 if (SpeedVector != Vector3.zero) { EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World); } EmptyObj.transform.Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self); } else if (CurrentMotion == MotionType.MoveRotateEvery) { //平移+旋转,围绕各自 if (SpeedVector != Vector3.zero) { EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World); } for (int i = 0; i < ChildList.Count; i++) { ChildList[i].Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self); } } else if (CurrentMotion == MotionType.RandomMotion) { //任意移动 if (SpeedVector != Vector3.zero) { ParentTrans.position = StartPos + SpeedVector * (current_time - StartTime) * speed_rate; } if (AngleVector != Vector3.zero) { ParentTrans.eulerAngles = StartEurler + AngleVector * (current_time - StartTime) * speed_rate; } } else if (CurrentMotion == MotionType.VisualPath) { //可视化路径移动 ParentTrans.position = crSpline.Interp(TimeRate(current_time)); ParentTrans.eulerAngles = crSpline.EulerAngleLerp(TimeRate(current_time), ref currentIndex, ref viewTimeRate); } }
//运动 public void Move(float current_time, float speed_rate, float delta_time) { if (TimeRate(current_time) > 1.001f || current_time > EndTime) { return; } else { lastFrameTime = current_time; } if (CurrentMotion == CameraMotionType.Line) //直线 { CurrentCamera.transform.position = StartPos + SpeedVector * (current_time - StartTime) * speed_rate; if (HasSizeChange) { SetCameraPortValue(StartSize + SizeSpeed * (current_time - StartTime) * speed_rate); } if (needExcess) { if (TimeRate(current_time) <= 0.1f) { CurrentCamera.transform.eulerAngles = Vector3.Lerp(diffVector[0], diffVector[1], TimeRate(current_time) * 10f); } else { CurrentCamera.transform.LookAt(TargetTrans); } } else { CurrentCamera.transform.LookAt(TargetTrans); } } else if (CurrentMotion == CameraMotionType.Circular) //圆弧 { CurrentCamera.transform.RotateAround(RotateCenter, RotateAxis, RotateSpeed * delta_time * speed_rate); if (HasSizeChange) { SetCameraPortValue(StartSize + SizeSpeed * (current_time - StartTime) * speed_rate); } CurrentCamera.transform.LookAt(TargetTrans); } else //可视化路径运动 { CurrentCamera.transform.position = crSpline.Interp(TimeRate(current_time)); if (TargetTrans != null) { if (needExcess) { if (TimeRate(current_time) <= 0.1f) { CurrentCamera.transform.eulerAngles = Vector3.Lerp(diffVector[0], diffVector[1], TimeRate(current_time) * 10f); } else { CurrentCamera.transform.LookAt(TargetTrans); } } else { CurrentCamera.transform.LookAt(TargetTrans); } SetCameraPortValue(crSpline.ViewLerp(TimeRate(current_time))); } else { CurrentCamera.transform.eulerAngles = crSpline.EulerAngleLerp(TimeRate(current_time), ref currentIndex, ref viewTimeRate); //二分法查找算一次 SetCameraPortValue(Mathf.Lerp(crSpline.cameraViewList[currentIndex], crSpline.cameraViewList[currentIndex + 1], viewTimeRate)); } } }
protected void easePath( ) { positionSpline = new CRSpline( path.getPositions() ); rotationSpline = new CRSpline( path.getRotations() ); float startI=(1.0f/(positionSpline.pts.Length-3))*(pathStartNode-1); float endI=(1.0f/(positionSpline.pts.Length-3))*(pathEndNode-1); float i=startI+ ((endI-startI)*normalizedTime); Vector3 newPos = positionSpline.Interp( i ); if (transform==null) { Debug.Log("EasePath error: "+easingGroup + " " + animationCurveName); return; } if(space==Space.World) transform.position = newPos; else transform.localPosition = newPos; if( lookAtTransform!= null ) { transform.LookAt( lookAtTransform, vectorUp ); } else if( pathAlignWithSpeed ) { Vector3 velVector = positionSpline.Velocity( i); if(space==Space.World) transform.rotation = Quaternion.LookRotation( velVector ); else transform.localRotation = Quaternion.LookRotation( velVector ); } else { Vector3 newRot = rotationSpline.Interp( i ); if(space==Space.World) transform.rotation = Quaternion.Euler( newRot ); else transform.localRotation = Quaternion.Euler( newRot ); } }