private void UpdateFlowerAngle() { Vector3 rotationVector = stemPath.GetPoint(stemPath.NumPoints - 1) - stemPath.GetPoint(stemPath.NumPoints - 2); transform.Find("Flower").rotation = Quaternion.FromToRotation(Vector3.up, rotationVector); transform.Find("Flower").position = stemPath.GetPoint(stemPath.NumPoints - 1); }
void OnDrawGizmos() { if (_path == null) { return; } Gizmos.color = Color.green; const float resolution = 0.01f; int stepCount = Mathf.RoundToInt(1 / resolution); float percent = 0.0f; var previousPoint = _path.GetPoint(percent); for (int i = 1; i < stepCount; i++) { percent = i * resolution; var nextPoint = _path.GetPoint(percent); Gizmos.DrawLine(previousPoint, nextPoint); previousPoint = nextPoint; } if (_bezier != null) { for (int i = 0; i < _bezier.NumPoints; i++) { if (i % 4 == 0) { Gizmos.color = Color.red; Gizmos.DrawWireSphere(_bezier[i], 0.1f); } } } }
public void UpdateMesh(BezierPath bPath) { if (mesh == null) { AssignMeshComponents(); } Initalize(bPath); int vertIndex = 0; int triIndex = 0; // Vertices for the top of the road are layed out: // 0 1 // 2 3 // and so on... So the triangle map 0,8,1 for example, defines a triangle from top left to bottom left to bottom right. for (int i = 0; i < vPath.NumPoints; i++) { Vector3 localUp = vPath.up; Vector3 localRight = Vector3.Cross(localUp, vPath.GetTangent(i)); // Find position to left and right of current path vertex Vector3 vertSideA = vPath.GetPoint(i) - localRight * Mathf.Abs(pathWidth); Vector3 vertSideB = vPath.GetPoint(i) + localRight * Mathf.Abs(pathWidth); // Add top of road vertices verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; // Set uv on y axis to path time (0 at start of path, up to 1 at end of path) uvs[vertIndex + 0] = new Vector2(0, vPath.times[i]); uvs[vertIndex + 1] = new Vector2(1, vPath.times[i]); // Top of road normals normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; // Set triangle indices if (i < vPath.NumPoints - 1 || vPath.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; } } vertIndex += 2; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.SetTriangles(roadTriangles, 0); mesh.RecalculateBounds(); meshFilter.sharedMesh = mesh; UpdateMaterials(); }
public void MoveToCharJumpPathEnd() { VertexPath char_fly_path = path.path; // Debug.Log("x: " + char_fly_vertex_path.GetPoint(0.999f).x + "z: " + char_fly_vertex_path.GetPoint(0.999f).z); transform.position = char_fly_path.GetPoint(0.999f); }
public void Align() { VertexPath vertex_path = path.vertex_path; int objects_count = objects_golist.list.Count; float fraction = start_fraction; float fraction_step = (end_fraction - start_fraction) / (objects_count - 1); for (int i = 0; i < objects_count; i++) { if (i > 0) { fraction += fraction_step; } Vector3 object_pos = vertex_path.GetPoint(fraction); Vector3 object_dir = Vector3.Normalize(vertex_path.GetPoint(fraction + 0.01f) - object_pos); objects_golist.Get(i).transform.position = object_pos; objects_golist.Get(i).transform.forward = object_dir; } }
void Update() { if (currentPath != null) { CheckFront(); dstTravelled += CalculateSpeed() * Time.deltaTime; transform.position = currentPath.GetPointAtDistance(dstTravelled, EndOfPathInstruction.Stop); Quaternion newRot = currentPath.GetRotationAtDistance(dstTravelled, EndOfPathInstruction.Stop); transform.eulerAngles = new Vector3(0, newRot.eulerAngles.y - 180, 0); if (Vector3.Distance(transform.position, currentPath.GetPoint(.9999f)) <= .05f) { UpdateRoadAndPath(); } } }
public void CalcStartData() { if (!is_set_on_start && !corrupted_path) { calc_position = vertex_path.GetPoint(curr_fraction, end_of_path_instruction); // Debug.Log(" pos : " + calc_position + " curr_fraction: " + curr_fraction + " " + gameObject.name); path_forward = Vector3.Normalize(vertex_path.GetPoint(curr_fraction + 0.01f, end_of_path_instruction) - vertex_path.GetPoint(curr_fraction, end_of_path_instruction)); is_set_on_start = true; } // Debug.Log(vertex_path.GetPoint(curr_fraction, end_of_path_instruction) + " name: " + gameObject.name); }
public Mesh GenerateStemMesh() { vPath = GetVPath(); StemMesh.Clear(); //Debug.Log("Generating Stem Mesh: " + vPath.GetHashCode()); //Generate Vertex List List <Vector3> meshVertices = new List <Vector3>(); //Generate Triangle List List <int> meshTriangles = new List <int>(); //for each Vertex Path Generate 8 vertices for a circle for (int i = 0; i < vPath.NumPoints; i++) { Vector3 centerPoint = vPath.GetPoint(i); Vector3[] tempList = GenerateCircleVertices(centerPoint); meshVertices.AddRange(tempList); } //Generate triangles for Quads for (int i = 0; i < vPath.NumPoints - 1; i++) { int initialPoint = i * vertexCount; int[] tempList = GenerateCircleTriangles(initialPoint); meshTriangles.AddRange(tempList); } //assign vertices to mesh StemMesh.SetVertices(meshVertices); //assign triangles to mesh StemMesh.SetTriangles(meshTriangles, 0); //Recalculate stuff StemMesh.RecalculateNormals(); StemMesh.RecalculateBounds(); //meshTriangles.ForEach(temp => Debug.Log(temp)); return(StemMesh); }
public void RenderItems(VertexPath roadPath, RoadConfig roadConfig) { var startOffsetPosition = Mathf.Clamp01(roadConfig.ItemsStartOffset.Value / roadPath.length); var endOffsetPosition = Mathf.Clamp01(roadConfig.ItemsEndOffset.Value / roadPath.length); var innerPathPercent = Mathf.Clamp01(1 - endOffsetPosition - startOffsetPosition); for (var i = 0; i < roadConfig.Items.Length; i++) { var roadItem = roadConfig.Items[i]; var roadItemPosition = roadItem.Position.Value * innerPathPercent + startOffsetPosition; var pointPosition = roadPath.GetPoint(roadItemPosition); var pointRotationAngles = roadPath.GetRotation(roadItemPosition).eulerAngles; // instantiate var prefabName = roadItem.Type.Value.GetPrefabName(); var prefab = prefabs.First(x => x.name == prefabName); var roadItemGo = Instantiate(prefab); roadItemGo.name = "RoadItem_ " + i; roadItemGo.tag = roadItem.Type.ToString(); roadItemGo.layer = roadItem.Type.Value.GetLayerValue(); // position and rotation var side = (roadItem.Side == RoadItemSide.Left ? -1f : 0f) * 2 + (roadItem.Side == RoadItemSide.Right ? 1f : 0f) * 2; var position = pointPosition + Vector3.right * side + Vector3.up * 0.5f; var rotation = Quaternion.Euler(new Vector3(pointRotationAngles.x, pointRotationAngles.y, 0)); roadItemGo.transform.SetPositionAndRotation(position, rotation); // mesh var materialName = roadItem.Type.Value.GetMaterialName(); if (!string.IsNullOrEmpty(materialName)) { var meshRenderer = roadItemGo.GetComponent <MeshRenderer>(); var material = materials.First(x => x.name == materialName); meshRenderer.material = material; } } }
void DrawBezierPathSceneEditor() { bool displayControlPoints = data.displayControlPoints && (bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic || !globalDisplaySettings.hideAutoControls); Bounds bounds = bezierPath.CalculateBoundsWithTransform(creator.transform); if (Event.current.type == EventType.Repaint) { for (int i = 0; i < bezierPath.NumSegments; i++) { Vector3[] points = bezierPath.GetPointsInSegment(i); for (int j = 0; j < points.Length; j++) { points[j] = MathUtility.TransformPoint(points[j], creator.transform, bezierPath.Space); } if (data.showPerSegmentBounds) { Bounds segmentBounds = CubicBezierUtility.CalculateSegmentBounds(points[0], points[1], points[2], points[3]); Handles.color = globalDisplaySettings.segmentBounds; Handles.DrawWireCube(segmentBounds.center, segmentBounds.size); } // Draw lines between control points if (displayControlPoints) { Handles.color = (bezierPath.ControlPointMode == BezierPath.ControlMode.Automatic) ? globalDisplaySettings.handleDisabled : globalDisplaySettings.controlLine; Handles.DrawLine(points[1], points[0]); Handles.DrawLine(points[2], points[3]); } // Draw path bool highlightSegment = (i == selectedSegmentIndex && Event.current.shift && draggingHandleIndex == -1 && mouseOverHandleIndex == -1); Color segmentCol = (highlightSegment) ? globalDisplaySettings.highlightedPath : globalDisplaySettings.bezierPath; Handles.DrawBezier(points[0], points[3], points[1], points[2], segmentCol, null, 2); } if (data.showPathBounds) { Handles.color = globalDisplaySettings.bounds; Handles.DrawWireCube(bounds.center, bounds.size); } // Draw normals if (data.showNormals) { if (!hasUpdatedNormalsVertexPath) { normalsVertexPath = new VertexPath(bezierPath, creator.transform, normalsSpacing); hasUpdatedNormalsVertexPath = true; } if (editingNormalsOld != data.showNormals) { editingNormalsOld = data.showNormals; Repaint(); } Vector3[] normalLines = new Vector3[normalsVertexPath.NumPoints * 2]; Handles.color = globalDisplaySettings.normals; for (int i = 0; i < normalsVertexPath.NumPoints; i++) { normalLines[i * 2] = normalsVertexPath.GetPoint(i); normalLines[i * 2 + 1] = normalsVertexPath.GetPoint(i) + normalsVertexPath.GetNormal(i) * globalDisplaySettings.normalsLength; } Handles.DrawLines(normalLines); } } if (data.displayAnchorPoints) { for (int i = 0; i < bezierPath.NumPoints; i += 3) { DrawHandle(i); } } if (displayControlPoints) { for (int i = 1; i < bezierPath.NumPoints - 1; i += 3) { DrawHandle(i); DrawHandle(i + 1); } } }
public string GenerateCompleteStatus() { /* This funciton creates the general status of the map all the players need * and sends it to them * * Mapstatus should contain the following: * * 1) The Bezier definition of the track * 2) The Vertext definition of the walls of the track * 3) Placement of all the checkpoints * */ MapStatus mapStatus = new MapStatus(); TrackController tc = GameObject.FindObjectOfType <TrackController>(); RoadMeshCreator pst = GameObject.FindObjectOfType <RoadMeshCreator>(); List <Vector3Json> bezierPoints = new List <Vector3Json>(); foreach (Vector3 point in pst.pathCreator.bezierPath.points) { bezierPoints.Add(point); } mapStatus.bezierPoints = bezierPoints; mapStatus.roadWidth = pst.roadWidth; GameObject checkpointHolder = tc.checkpointHolder; List <Vector3Json> checkPointPos = new List <Vector3Json>(); List <Vector3Json> checkPointRot = new List <Vector3Json>(); Bounds checkPointBound = checkpointHolder.transform.GetChild(0).GetComponent <BoxCollider>().bounds; for (int i = 0; i < checkpointHolder.transform.childCount; i++) { Transform t = checkpointHolder.transform.GetChild(i); checkPointPos.Add(t.position); checkPointRot.Add(t.rotation.eulerAngles); } mapStatus.checkPointPos = checkPointPos; mapStatus.checkPointRot = checkPointRot; mapStatus.checkpointSize = checkPointBound.size; mapStatus.midpoint = new List <Vector3Json>(); mapStatus.wallLeft = new List <Vector3Json>(); mapStatus.wallRight = new List <Vector3Json>(); mapStatus.roadDirection = new List <Vector3Json>(); VertexPath vertexPath = pst.pathCreator.path; Vector3[] pathPoints = vertexPath.localPoints; for (int i = 0; i < vertexPath.localPoints.Length; i++) { Vector3 midPoint = pathPoints[i]; Vector3 localRight = Vector3.Cross(Vector3.up, vertexPath.GetTangent(i)); Vector3 vertSideA = vertexPath.GetPoint(i) - localRight * Mathf.Abs(pst.roadWidth); Vector3 vertSideB = vertexPath.GetPoint(i) + localRight * Mathf.Abs(pst.roadWidth); mapStatus.midpoint.Add(midPoint); mapStatus.wallLeft.Add(vertSideA); mapStatus.wallRight.Add(vertSideB); mapStatus.roadDirection.Add(vertexPath.GetTangent(i)); } string mapStatusJson = JsonConvert.SerializeObject(mapStatus); //Debug.Log(mapStatusJson); if (debug) { for (int i = 1; i < mapStatus.wallLeft.Count; i++) { // Left Vector3 point_l1 = mapStatus.wallRight[i - 1]; Vector3 point_l2 = mapStatus.wallRight[i]; Debug.DrawLine(point_l1, point_l2, Color.red); // Right Vector3 point_r1 = mapStatus.wallLeft[i - 1]; Vector3 point_r2 = mapStatus.wallLeft[i]; Debug.DrawLine(point_r1, point_r2, Color.blue); } } return(mapStatusJson); }
//Creates a mesh around the Bezier curve public static void CreateRoadMesh(VertexPath path, Mesh mesh, float roadWidth, float thickness, bool flattenSurface, bool useRotation) { Vector3[] verts = new Vector3[path.NumPoints * 8]; Vector2[] uvs = new Vector2[verts.Length]; Vector3[] normals = new Vector3[verts.Length]; int numTris = 2 * (path.NumPoints - 1) + ((path.isClosedLoop) ? 2 : 0); int[] roadTriangles = new int[numTris * 3]; int[] underRoadTriangles = new int[numTris * 3]; int[] sideOfRoadTriangles = new int[numTris * 2 * 3]; int vertIndex = 0; int triIndex = 0; int[] triangleMap = { 0, 8, 1, 1, 8, 9 }; int[] sidesTriangleMap = { 4, 6, 14, 12, 4, 14, 5, 15, 7, 13, 15, 5 }; bool usePathNormals = !(path.space == PathSpace.xyz && flattenSurface); for (int i = 0; i < path.NumPoints; i++) { Vector3 localUp = (usePathNormals) ? Vector3.Cross(path.GetTangent(i), path.GetNormal(i)) : path.up; Vector3 localRight = (usePathNormals) ? path.GetNormal(i) : Vector3.Cross(localUp, path.GetTangent(i)); Vector3 side = useRotation ? Vector3.right : localRight; Vector3 vertSideA = path.GetPoint(i) - side * Mathf.Abs(roadWidth); Vector3 vertSideB = path.GetPoint(i) + side * Mathf.Abs(roadWidth); verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; verts[vertIndex + 2] = vertSideA - localUp * thickness; verts[vertIndex + 3] = vertSideB - localUp * thickness; verts[vertIndex + 4] = verts[vertIndex + 0]; verts[vertIndex + 5] = verts[vertIndex + 1]; verts[vertIndex + 6] = verts[vertIndex + 2]; verts[vertIndex + 7] = verts[vertIndex + 3]; uvs[vertIndex + 0] = new Vector2(0, path.times[i]); uvs[vertIndex + 1] = new Vector2(1, path.times[i]); normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; normals[vertIndex + 2] = -localUp; normals[vertIndex + 3] = -localUp; normals[vertIndex + 4] = -localRight; normals[vertIndex + 5] = localRight; normals[vertIndex + 6] = -localRight; normals[vertIndex + 7] = localRight; // Set triangle indices if (i < path.NumPoints - 1 || path.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; // reverse triangle map for under road so that triangles wind the other way and are visible from underneath underRoadTriangles[triIndex + j] = (vertIndex + triangleMap[triangleMap.Length - 1 - j] + 2) % verts.Length; } for (int j = 0; j < sidesTriangleMap.Length; j++) { sideOfRoadTriangles[triIndex * 2 + j] = (vertIndex + sidesTriangleMap[j]) % verts.Length; } } vertIndex += 8; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.subMeshCount = 3; mesh.SetTriangles(roadTriangles, 0); mesh.SetTriangles(underRoadTriangles, 1); mesh.SetTriangles(sideOfRoadTriangles, 2); mesh.RecalculateBounds(); }
void CreateRoadMesh() { Vector3[] verts = new Vector3[VertexPath.NumPoints * 8]; Vector2[] uvs = new Vector2[verts.Length]; Vector3[] normals = new Vector3[verts.Length]; int numTris = 2 * (VertexPath.NumPoints - 1) + ((VertexPath.isClosedLoop) ? 2 : 0); int[] roadTriangles = new int[numTris * 3]; int[] underRoadTriangles = new int[numTris * 3]; int[] sideOfRoadTriangles = new int[numTris * 2 * 3]; int vertIndex = 0; int triIndex = 0; // Vertices for the top of the road are layed out: // 0 1 // 8 9 // and so on... So the triangle map 0,8,1 for example, defines a triangle from top left to bottom left to bottom right. int[] triangleMap = { 0, 8, 1, 1, 8, 9 }; int[] sidesTriangleMap = { 4, 6, 14, 12, 4, 14, 5, 15, 7, 13, 15, 5 }; bool usePathNormals = !(VertexPath.space == PathSpace.xyz && flattenSurface); for (int i = 0; i < VertexPath.NumPoints; i++) { Vector3 localUp = (usePathNormals) ? Vector3.Cross(VertexPath.GetTangent(i), VertexPath.GetNormal(i)) : VertexPath.up; Vector3 localRight = (usePathNormals) ? VertexPath.GetNormal(i) : Vector3.Cross(localUp, VertexPath.GetTangent(i)); // Find position to left and right of current VertexPath vertex Vector3 vertSideA = VertexPath.GetPoint(i) - localRight * Mathf.Abs(roadWidth); Vector3 vertSideB = VertexPath.GetPoint(i) + localRight * Mathf.Abs(roadWidth); // Add top of road vertices verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; // Add bottom of road vertices verts[vertIndex + 2] = vertSideA - localUp * thickness; verts[vertIndex + 3] = vertSideB - localUp * thickness; // Duplicate vertices to get flat shading for sides of road verts[vertIndex + 4] = verts[vertIndex + 0]; verts[vertIndex + 5] = verts[vertIndex + 1]; verts[vertIndex + 6] = verts[vertIndex + 2]; verts[vertIndex + 7] = verts[vertIndex + 3]; // Set uv on y axis to VertexPath time (0 at start of VertexPath, up to 1 at end of VertexPath) uvs[vertIndex + 0] = new Vector2(0, VertexPath.times[i]); uvs[vertIndex + 1] = new Vector2(1, VertexPath.times[i]); // Top of road normals normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; // Bottom of road normals normals[vertIndex + 2] = -localUp; normals[vertIndex + 3] = -localUp; // Sides of road normals normals[vertIndex + 4] = -localRight; normals[vertIndex + 5] = localRight; normals[vertIndex + 6] = -localRight; normals[vertIndex + 7] = localRight; // Set triangle indices if (i < VertexPath.NumPoints - 1 || VertexPath.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; // reverse triangle map for under road so that triangles wind the other way and are visible from underneath underRoadTriangles[triIndex + j] = (vertIndex + triangleMap[triangleMap.Length - 1 - j] + 2) % verts.Length; } for (int j = 0; j < sidesTriangleMap.Length; j++) { sideOfRoadTriangles[triIndex * 2 + j] = (vertIndex + sidesTriangleMap[j]) % verts.Length; } } vertIndex += 8; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.subMeshCount = 3; mesh.SetTriangles(roadTriangles, 0); mesh.SetTriangles(underRoadTriangles, 1); mesh.SetTriangles(sideOfRoadTriangles, 2); mesh.RecalculateBounds(); }