public override void ReadBlueprintPositions(ContourBlueprint blueprint) { // Read contour positions only (assumes only modification on contour is some point moved) if (blueprint != null && blueprint is ContourMeshBlueprint && blueprint.material is ContourLineMaterial) { // Get positions Vector2[] positions = blueprint.Positions; // Check if blueprint matches reader mesh's length int positionCount = positions != null ? positions.Length : 0; int vertexCount = Vertices.Count; if (vertexCount == positionCount * 2) { if (vertexCount > 0) { ContourLineMaterial contourMaterial = blueprint.material as ContourLineMaterial; GenerateVertices(positions, contourMaterial.zOffset, contourMaterial.width); GenerateUVs(positions, contourMaterial.uvScale); } } else { throw new Exception("Blueprint and reader mismatch"); } } // Notify if there's a problem with the blueprint else { throw new Exception("Can't read blueprint"); } }
public override void ReadBlueprintPositions(ContourBlueprint blueprint) { // Read contour positions only (assumes only modification on contour is some point moved) if (blueprint != null && blueprint is ContourMeshBlueprint && blueprint.material is ContourFaceMaterial) { // Get positions Vector2[] positions = blueprint.Positions; // Check if blueprint matches reader mesh's length int positionCount = positions != null ? positions.Length : 0; int vertexCount = Vertices != null ? Vertices.Count : 0; if (vertexCount == positionCount - 1) { if (vertexCount > 0) { // Update vertices for (int i = 0; i < vertexCount; i++) { Vertices[i] = new Vector3(positions[i].x, positions[i].y, Vertices[i].z); } // Update uvs (to avoid texture stretching) for (int i = 0; i < vertexCount; i++) { UVs[i] = Vertices[i]; } } } } // Notify if there's a problem with the blueprint else { throw new Exception("Can't read blueprint"); } }
public static ContourReader NewReader(ContourBlueprint blueprint) { if (blueprint == null || blueprint.material == null) { return(null); } ContourReader newReader = null; if (blueprint.material is ContourFaceMaterial) { newReader = new ContourFaceReader(); } else if (blueprint.material is ContourLineMaterial) { newReader = new ContourLineReader(); } else if (blueprint.material is ContourColliderMaterial) { newReader = new ContourColliderReader(); } else if (blueprint.material is ContourAnimationMaterial) { newReader = new ContourAnimationReader(); } if (newReader == null) { throw new Exception(newReader.ToString() + " creation error. " + blueprint.material.ToString() + " reading not implemented"); } newReader.TryReadBlueprint(blueprint); // Return created reader //newReader.blueprint = blueprint; return(newReader); }
public virtual void Build() { // Default update // can be further optimized in children classes if (blueprints != null) { int blueprintCount = blueprints.Count; if (readers == null || readers.Count != blueprintCount) { ResetReaders(); } bool rebuild = false; bool updatePositions = false; for (int bpi = 0; bpi < blueprintCount; bpi++) { ContourBlueprint bp = blueprints[bpi]; if (bp == null) { readers[bpi] = null; } else if (readers[bpi] == null) { readers[bpi] = ContourReader.NewReader(bp); } else if (bp.blueprintChanges != ContourBlueprint.BlueprintChange.None) { if (bp.blueprintChanges.HasFlag(ContourBlueprint.BlueprintChange.MaterialChanged)) { rebuild = true; } if (bp.blueprintChanges.HasFlag(ContourBlueprint.BlueprintChange.ParameterChanged)) { OnChangeBlueprintParameters(bpi); } } else if (bp.ShapeChanges != ContourShape.ShapeChanged.None) { if (bp.ShapeChanges.HasFlag(ContourShape.ShapeChanged.LengthChanged)) { rebuild = true; } else if (bp.ShapeChanges.HasFlag(ContourShape.ShapeChanged.PositionMoved)) { readers[bpi].ReadBlueprintPositions(bp); updatePositions = true; } } } if (rebuild) { RebuildAll(); } if (updatePositions) { UpdatePositions(); } } }
public override bool TryReadBlueprint(ContourBlueprint blueprint) { // Read if possible if (blueprint != null && blueprint.material is ContourColliderMaterial) { // Check blueprint for positions and material Vector2[] positions = blueprint.Positions; if (positions == null || positions.Length < 2 || blueprint.material == null) { Clear(); return(false); } int positionCount = positions.Length; // Get material ContourColliderMaterial contourMaterial = blueprint.material as ContourColliderMaterial; // Set collider type ColliderType = null; switch (contourMaterial.type) { // Edge is always possible case ContourColliderMaterial.ColliderType.Edge: ColliderType = typeof(EdgeCollider2D); break; // Polygon is possible if contour is a loop case ContourColliderMaterial.ColliderType.Polygon: if (positions.Length > 2 && positions[0] == positions[positionCount - 1]) { ColliderType = typeof(PolygonCollider2D); } break; case ContourColliderMaterial.ColliderType.Auto: ColliderType = (positionCount > 2 && positions[0] == positions[positionCount - 1]) ? typeof(PolygonCollider2D) : typeof(EdgeCollider2D); break; } if (ColliderType == null) { Clear(); return(false); } // Get positions Positions = new List <Vector2>(blueprint.Positions); if (ColliderType == typeof(PolygonCollider2D)) { Positions.RemoveAt(positionCount - 1); } // Get collider parameters IsTrigger = contourMaterial.isTrigger; PhysicsMaterial = contourMaterial.physicsMaterial; // Success return(true); } // Failed return(false); }
public override bool TryAddBlueprint(ContourBlueprint bp) { if (base.TryAddBlueprint(bp)) { UpdateColliderComponent(); return(collider2D != null); } else { return(false); } }
public static ContourBuilder NewBuilder(ContourBlueprint blueprint, Transform setParent = null) { // Create new gameobject GameObject builderGO = new GameObject("Contour builder"); builderGO.transform.SetParent(setParent, false); // Add builder component according to reader type and return it ContourBuilder newBuilder = null; if (blueprint != null) { ContourReader reader = ContourReader.NewReader(blueprint); builderGO.name = reader.BuilderName; newBuilder = builderGO.AddComponent(reader.BuilderType) as ContourMeshBuilder; //if (reader is ContourMeshReader) //{ // builderGO.name = "Mesh builder"; // newBuilder = builderGO.AddComponent<ContourMeshBuilder>(); //} //else if (reader is ContourColliderReader) //{ // builderGO.name = "Collider builder"; // newBuilder = builderGO.AddComponent<ContourColliderBuilder>(); //} //else if (reader is ContourAnimationReader) //{ // builderGO.name = "Animation builder"; // newBuilder = builderGO.AddComponent<ContourAnimationBuilder>(); //} } // If add component has failed, cancel gameobject creation and return null if (newBuilder == null) { DestroyImmediate(builderGO); } else { newBuilder.TryAddBlueprint(blueprint); } return(newBuilder); }
public virtual bool TryAddBlueprint(ContourBlueprint bp) { if (bp == null) { return(false); } ContourReader newReader = ContourReader.NewReader(bp); if (CanBuildFrom(newReader)) { // Add blueprint to existing list if not already in the list and if it is readable or create a new list if (blueprints == null) { blueprints = new List <ContourBlueprint>() { bp } } ; else if (!blueprints.Contains(bp)) { blueprints.Add(bp); } // Update readers accordingly int bpCount = blueprints.Count; if (readers != null && readers.Count == bpCount - 1) { readers.Add(newReader); } else { ResetReaders(); } return(true); } else { return(false); } }
public override bool TryReadBlueprint(ContourBlueprint blueprint) { // Read if possible if (blueprint != null && blueprint.material is ContourAnimationMaterial) { contour = blueprint.shape; ReadBlueprintPositions(blueprint); ContourAnimationMaterial animationMaterial = blueprint.material as ContourAnimationMaterial; radius = animationMaterial.amplitude / 2f; freq = (animationMaterial.cycleDuration != 0f ? 1f / animationMaterial.cycleDuration : 0f) * 2f * Mathf.PI; phase = animationMaterial.phase * Mathf.Deg2Rad; if (contour != null && contour.Length > 2) { contourIsLoop = contour.GetPosition(0) == contour.GetPosition(contour.Length - 1); } else { contourIsLoop = false; } return(true); } return(false); }
public override void ReadBlueprintPositions(ContourBlueprint blueprint) { // Read contour positions only (assumes only modification on contour is some point moved) if (blueprint != null && blueprint.material is ContourColliderMaterial) { // Get positions Vector2[] positions = blueprint.Positions; // Check if blueprint matches reader mesh's length int colliderLength = Positions != null ? Positions.Count : 0; bool lengthCheck; if (ColliderType == typeof(PolygonCollider2D)) { lengthCheck = positions.Length == colliderLength + 1; } else { lengthCheck = positions.Length == colliderLength; } if (lengthCheck) { for (int i = 0; i < colliderLength; i++) { Positions[i] = blueprint.Positions[i]; } } else { throw new Exception("Blueprint and reader mismatch"); } } // Notify if there's a problem with the blueprint else { throw new Exception("Can't read blueprint"); } }
public override bool TryReadBlueprint(ContourBlueprint blueprint) { // Read if possible if (blueprint != null && blueprint is ContourMeshBlueprint && blueprint.material is ContourFaceMaterial) { ContourMeshBlueprint meshBlueprint = blueprint as ContourMeshBlueprint; // Get positions Vector2[] positions = blueprint.Positions; if (positions == null) { return(false); } // Get material ContourFaceMaterial contourMaterial = blueprint.material as ContourFaceMaterial; if (contourMaterial == null) { return(false); } MeshMaterial = contourMaterial.meshMaterial; // To build a face, there must be enough positions and contour must be a loop int positionCount = positions != null ? positions.Length : 0; if (positionCount < 3 || positions[0] != positions[positionCount - 1]) { Clear(); return(false); } // Set vertices: copy positions x,y and set z to value in contourMaterial (last position is ignored because of loop) int vertexCount = positionCount - 1; Vector3 zOffset = contourMaterial.zOffset * Vector3.forward; Vertices = new List <Vector3>(vertexCount); for (int i = 0; i < vertexCount; i++) { Vertices.Add((Vector3)positions[i] + zOffset); } // Set triangles: simple convex triangulation int triangleCount = Mathf.Max(vertexCount - 2, 0); Triangles = new List <int>(triangleCount * 3); for (int i = 0; i < triangleCount; i++) { Triangles.AddRange(new int[] { 0, i + 1, i + 2 }); } // Set uvs: since it's 2D, use vertex positions UVs = new List <Vector2>(vertexCount); for (int i = 0; i < vertexCount; i++) { UVs.Add(Vertices[i]); } // Set normals: fetch value in blueprint Normals = new List <Vector3>(vertexCount); Vector3 normal = meshBlueprint.Normal; for (int i = 0; i < vertexCount; i++) { Normals.Add(normal); } // Set colors: fetch color in blueprint Color color = meshBlueprint.Color; Colors = new List <Color>(vertexCount); for (int i = 0; i < vertexCount; i++) { Colors.Add(color); } return(true); } // If not, return false return(false); }
private void ContourListInspectorGUI() { // Adjust inspector capacity to contour count int ctCount = targetBuilder.ContourCount; if (contourInspectors == null) { contourInspectors = new ContourInspector[ctCount]; } else { Array.Resize(ref contourInspectors, ctCount); } // Display each contour with expandable inspector string[] paletteOptions = targetBuilder.GetPaletteOptionNames(); for (int cti = 0; cti < ctCount; cti++) { // Minimal inspector: palette option name EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout); foldoutStyle.focused.textColor = Color.blue; bool expand = EditorGUILayout.Foldout(contourInspectors[cti].inspectorState.HasFlag(ContourInspector.State.Expand), "Contour " + cti, foldoutStyle); if (EditorGUI.EndChangeCheck()) { if (expand) { contourInspectors[cti].inspectorState |= ContourInspector.State.Expand; } else { contourInspectors[cti].inspectorState &= ~ContourInspector.State.Expand; } SceneView.RepaintAll(); // Apply modifications in inspector EditorUtility.SetDirty(targetBuilder); return; } if (targetBuilder.palette != null) { EditorGUI.BeginChangeCheck(); int paletteIndex = EditorGUILayout.Popup(targetBuilder.GetPaletteIndex(cti), paletteOptions); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(targetBuilder, "Set contour material"); targetBuilder.SetPaletteIndex(cti, paletteIndex); // Apply modifications in inspector EditorUtility.SetDirty(targetBuilder); } } EditorGUILayout.EndHorizontal(); //Expanded inspector: contour blueprints ContourBlueprint[] blueprints = targetBuilder.contours[cti].blueprints; foreach (ContourBlueprint bp in blueprints) { bp.hideFlags = expand ? HideFlags.None : HideFlags.HideInInspector; //EditorUtility.SetDirty(bp); } if (expand) { // Adjust inspector to blueprint count int bpCount = blueprints.Length; if (contourInspectors[cti].blueprintEditors == null) { contourInspectors[cti].blueprintEditors = new Editor[bpCount]; } else { Array.Resize(ref contourInspectors[cti].blueprintEditors, bpCount); } // Show editor for each blueprint of this contour EditorGUI.indentLevel++; if (bpCount > 0) { for (int bpi = 0; bpi < bpCount; bpi++) { EditorGUILayout.BeginVertical("box"); ContourBlueprint bp = blueprints[bpi]; if (bp == null) { EditorGUILayout.HelpBox("Null blueprint", MessageType.Error); } else { EditorGUILayout.LabelField(bpi.ToString(), bp.GetType().Name); Editor[] bpEditors = contourInspectors[cti].blueprintEditors; CreateCachedEditor(bp, typeof(ContourBlueprintEditor), ref bpEditors[bpi]); ContourBlueprintEditor bpEditor = (bpEditors[bpi] as ContourBlueprintEditor); bpEditor.positionsDisplay = ContourBlueprintEditor.FieldDisplay.Hidden; bpEditor.materialDisplay = ContourBlueprintEditor.FieldDisplay.ReadOnly; bpEditor.OnInspectorGUI(); } EditorGUILayout.EndVertical(); } } else { EditorGUILayout.HelpBox("This contour doesn't generate blueprints", MessageType.Info); } EditorGUI.indentLevel--; } } }
public override void ReadBlueprintPositions(ContourBlueprint blueprint) { animationPositions = new Vector2[blueprint.Positions.Length]; }
public override bool TryReadBlueprint(ContourBlueprint blueprint) { // Read if possible if (blueprint != null && blueprint is ContourMeshBlueprint && blueprint.material is ContourLineMaterial) { ContourMeshBlueprint meshBlueprint = blueprint as ContourMeshBlueprint; // Get positions Vector2[] positions = blueprint.Positions; if (positions == null) { return(false); } // Get material ContourLineMaterial contourMaterial = blueprint.material as ContourLineMaterial; if (contourMaterial == null) { return(false); } MeshMaterial = contourMaterial.meshMaterial; // Check if enough points to build at least one segment int positionCount = positions != null ? positions.Length : 0; if (positionCount < 2) { Clear(); return(false); } // Set vertices: two vertices per point int vertexCount = positionCount * 2; Vertices = new List <Vector3>(new Vector3[vertexCount]); GenerateVertices(positions, contourMaterial.zOffset, contourMaterial.width); // Set triangles: one quad per segment, two triangles per quad int quadCount = positionCount - 1; Triangles = new List <int>(quadCount * 6); for (int i = 0; i < quadCount; i++) { int q = i * 2; // First half of a quad Triangles.AddRange(new int[] { q, q + 1, q + 3 }); // Second half Triangles.AddRange(new int[] { q, q + 3, q + 2 }); } // Set normals: fetch value in blueprint Normals = new List <Vector3>(vertexCount); Vector3 normal = meshBlueprint.Normal; for (int i = 0; i < vertexCount; i++) { Normals.Add(normal); } // Set uvs: repeat texture along segments GenerateUVs(positions, contourMaterial.uvScale); // Set colors: fetch value in blueprint Color color = meshBlueprint.Color; Colors = new List <Color>(vertexCount); for (int i = 0; i < vertexCount; i++) { Colors.Add(color); } return(true); } // If not, return false return(false); }
public abstract bool TryReadBlueprint(ContourBlueprint blueprint);
public abstract void ReadBlueprintPositions(ContourBlueprint blueprint);