private GameObject FindOrCreate(string name) { var childTransform = generated.transform.Find(name); GameObject res; if (childTransform == null) { res = UOUtility.Create(name, generated, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender), typeof(MeshCollider)); res.isStatic = true; } else { res = childTransform.gameObject; } res.GetComponent <MeshRenderer>().material = material; res.GetComponent <MeshCollider>().material = physicMaterial; MeshBender mb = res.GetComponent <MeshBender>(); mb.Source = SourceMesh.Build(mesh) .Translate(translation) .Rotate(Quaternion.Euler(rotation)) .Scale(scale); mb.Mode = mode; return(res); }
private ref SourceMesh GetCurrentRepeatSource(int repeatStep, int repetitionCount) { UnityEngine.Random.InitState(repeatStep); if (null != extraSources && 0 < extraSources.Length) { for (int i = 0; i < extraSources.Length; ++i) { ref SourceMesh extraSource = ref extraSources[i]; switch (extraSource.placeType) { case MeshPlaceType.Sequence: { int seqIndex = Mathf.RoundToInt(extraSource.placeWeight); if (0 <= Mathf.Sign(extraSource.placeWeight) && seqIndex == repeatStep) { return(ref extraSource); } if (-0 >= Mathf.Sign(extraSource.placeWeight) && seqIndex == (repeatStep - (repetitionCount - 1))) { return(ref extraSource); } } break; case MeshPlaceType.Random: if (UnityEngine.Random.value <= extraSource.placeWeight) { return(ref extraSource); } break; } } }
private void Init() { string generatedName = "generated by " + GetType().Name; var generatedTranform = transform.Find(generatedName); generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender)); generated.GetComponent <MeshRenderer>().material = material; if (generated.GetComponent <DecrepitEffect>() == null) { generated.AddComponent <DecrepitEffect>(); } meshBender = generated.GetComponent <MeshBender>(); spline = GetComponent <Spline>(); meshBender.Source = SourceMesh.Build(mesh) .Rotate(Quaternion.Euler(rotation)) .Scale(scale); meshBender.Mode = MeshBender.FillingMode.StretchToInterval; meshBender.SetInterval(spline, 0, 0.01f); }
/// <summary> /// copy constructor /// </summary> /// <param name="other"></param> private SourceMesh(SourceMesh other) { mesh = other.mesh; translation = other.translation; rotation = other.rotation; scale = other.scale; }
private GameObject FindOrCreate(string name) { var childTransform = generated.transform.Find(name); GameObject res; if (childTransform == null) { res = UOUtility.Create(name, generated, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender), typeof(MeshCollider)); res.isStatic = !updateInPlayMode; } else { res = childTransform.gameObject; } res.GetComponent <MeshRenderer>().material = material; res.GetComponent <MeshCollider>().material = physicMaterial; MeshBender mb = res.GetComponent <MeshBender>(); mb.Source = SourceMesh.Build(mesh) .Translate(translation) .Rotate(Quaternion.Euler(rotation)) .Scale(scale); if (null != extraMeshes && 0 < extraMeshes.Length) { List <Material> materials = new List <Material>(); materials.Add(material); SourceMesh[] extraSourceMeshes = new SourceMesh[extraMeshes.Length]; for (int i = 0; i < extraMeshes.Length; ++i) { var T = translation; var R = rotation; var S = scale; if (extraMeshes[i].useCustomTRS) { T = extraMeshes[i].customTranslation; R = extraMeshes[i].customRotation; } extraSourceMeshes[i] = SourceMesh.Build(extraMeshes[i].mesh) .Translate(T) .Rotate(Quaternion.Euler(R)) .Scale(S); extraSourceMeshes[i].placeType = extraMeshes[i].placeType; extraSourceMeshes[i].placeWeight = extraMeshes[i].placeWeight; materials.Add(extraMeshes[i].material); } Array.Sort(extraSourceMeshes, (x, y) => (int)x.placeType - (int)y.placeType); mb.ExtraSources = extraSourceMeshes; res.GetComponent <MeshRenderer>().materials = materials.ToArray(); } mb.Mode = mode; return(res); }
public SourceMesh Scale(Vector3 scale) { var res = new SourceMesh(this) { scale = scale }; return(res); }
public SourceMesh Rotate(Quaternion rotation) { var res = new SourceMesh(this) { rotation = rotation }; return(res); }
public SourceMesh Translate(Vector3 translation) { var res = new SourceMesh(this) { translation = translation }; return(res); }
public void CreateMeshes() { List <GameObject> used = new List <GameObject>(); for (int i = 0; i < spline.GetCurves().Count; i++) { var curve = spline.GetCurves()[i]; foreach (var tm in segments[i].transformedMeshes) { if (tm.mesh == null) { // if there is no mesh specified for this segment, we ignore it. continue; } // we try to find a game object previously generated. this avoids destroying/creating // game objects at each update, wich is faster. var childName = "segment " + i + " mesh " + segments[i].transformedMeshes.IndexOf(tm); var childTransform = generated.transform.Find(childName); GameObject go; if (childTransform == null) { go = UOUtility.Create(childName, generated, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender), typeof(MeshCollider)); go.isStatic = true; } else { go = childTransform.gameObject; } go.GetComponent <MeshRenderer>().material = tm.material; go.GetComponent <MeshCollider>().material = tm.physicMaterial; // we update the data in the bender. It will decide itself if the bending must be recalculated. MeshBender mb = go.GetComponent <MeshBender>(); mb.Source = SourceMesh.Build(tm.mesh) .Translate(tm.translation) .Rotate(Quaternion.Euler(tm.rotation)) .Scale(tm.scale); mb.SetInterval(curve); mb.ComputeIfNeeded(); used.Add(go); } } // finally, we destroy the unused objects foreach (var go in generated.transform .Cast <Transform>() .Select(child => child.gameObject).Except(used)) { UOUtility.Destroy(go); } }
/// <summary> /// copy constructor /// </summary> /// <param name="other"></param> private SourceMesh(SourceMesh other) { Mesh = other.Mesh; translation = other.translation; rotation = other.rotation; scale = other.scale; vertices = null; triangles = null; minX = 0; length = 0; }
private void Init() { for (int i = 0; i < meshes.Count; i++) { string generatedName = i + ". generated by " + GetType().Name; var generatedTranform = transform.Find(generatedName); GameObject generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender)); // some harmless bug TODO if (generatedList.Count < i + 1) { generatedList.Add(generated); } else { generatedList[i] = generated; } generatedList[i].GetComponent <MeshRenderer>().material = materials[i]; MeshBender meshBender = generatedList[i].GetComponent <MeshBender>(); if (meshBenders.Count < i + 1) { meshBenders.Add(meshBender); } else { meshBenders[i] = meshBender; } meshBenders[i] = generatedList[i].GetComponent <MeshBender>(); spline = GetComponent <Spline>(); meshBenders[i].Source = SourceMesh.Build(meshes[i]) .Translate(translations[i]) .Rotate(Quaternion.Euler(rotations[i])) .Scale(scales[i]); meshBenders[i].Mode = MeshBender.FillingMode.Repeat; meshBenders[i].SetInterval(spline, 0); } // First mesh determines lenght of generation contortionLength = meshBenders[0].Source.Length * ((float)(Repeat) + 0.1f); }
private void UpdateSourceMeshes() { if (null == sourceMeshes || sourceMeshes.Length != meshInfos.Length) { sourceMeshes = new SourceMesh[meshInfos.Length]; } for (int i = 0; i < meshInfos.Length; ++i) { var newSourceMesh = SourceMesh.Build(meshInfos[i].mesh) .Translate(meshInfos[i].translation) .Rotate(Quaternion.Euler(meshInfos[i].rotation)) .Scale(meshInfos[i].scale); if (false == sourceMeshes[i].Equals(newSourceMesh)) { sourceMeshes[i] = newSourceMesh; } } }
private GameObject FindOrCreateRender(string parentName, string name) { var childTransform = generated.transform.Find(name); if (collider) { var parentTransform = generated.transform.Find(parentName); childTransform = parentTransform.Find(name); } GameObject res; if (childTransform == null) { res = UOUtility.Create(name, generated, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender)); res.isStatic = true; } else { res = childTransform.gameObject; } res.GetComponent <MeshRenderer>().material = material; MeshBender mb = res.GetComponent <MeshBender>(); mb.Source = SourceMesh.Build(mesh) .Translate(translation) .Rotate(Quaternion.Euler(rotation)) .Scale(scale); if (mode == MeshBender.FillingMode.CustomIntervals) { mb.SetCustomInterval(customIntervalStart, customIntervalEnd); } mb.Mode = mode; return(res); }
public void CreateMeshes() { if (null == spline || null == meshInfos || 0 == meshInfos.Length) { return; } UpdateSourceMeshes(); UpdateDecisionParts(); string generatedName = "generated by " + GetType().Name; var generatedTranform = transform.Find(generatedName); generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject); generated.isStatic = false == updateInPlayMode; generated.layer = gameObject.layer; var generatedChildren = generated.transform.Cast <Transform>().ToList(); foreach (var child in generatedChildren) { if (null == child) { continue; } var meshCollider = child.GetComponent <MeshCollider>(); if (meshCollider) { meshCollider.enabled = false; } } var meshChunkDict = new Dictionary <Material, List <MeshChunk> >(); var sampleCache = new Dictionary <float, CurveSample>(); float offset = 0; for (int i = 0; i < decisionParts.Count; ++i) { int index = decisionParts[i]; if (false == meshChunkDict.ContainsKey(meshInfos[index].material)) { meshChunkDict.Add(meshInfos[index].material, new List <MeshChunk>()); } var meshChunkList = meshChunkDict[meshInfos[index].material]; int vertexCount = meshInfos[index].mesh.vertices.Length; bool isReachedMaxVertices = 0 < meshChunkList.Count && PerChunkMaxVertices < (meshChunkList.Last().bentVertices.Count + vertexCount); bool isReachedMaxLength = 0 < meshChunkList.Count && PerChunkMaxLength < meshChunkList.Last().length; if (0 == meshChunkList.Count || isReachedMaxVertices || isReachedMaxLength) { meshChunkList.Add(new MeshChunk() { bentVertices = new List <MeshVertex>(vertexCount), triangles = new List <int>(vertexCount / 3), uv = new List <Vector2> [8], length = 0 }); } var meshChunk = meshChunkList.Last(); ref SourceMesh sourceMesh = ref sourceMeshes[index]; meshChunk.triangles.AddRange(sourceMesh.Triangles.Select(idx => idx + meshChunk.bentVertices.Count)); List <Vector2> UV = new List <Vector2>(); for (int channel = 0; channel < 8; ++channel) { UV.Clear(); sourceMesh.Mesh.GetUVs(channel, UV); if (0 < UV.Count) { if (null == meshChunk.uv[channel]) { meshChunk.uv[channel] = new List <Vector2>(); } int fillCount = Mathf.Max(0, (meshChunk.bentVertices.Count - UV.Count) - meshChunk.uv[channel].Count); if (0 < fillCount) { meshChunk.uv[channel].AddRange(Enumerable.Repeat(Vector2.zero, fillCount)); } meshChunk.uv[channel].AddRange(UV); } } foreach (var vertex in sourceMesh.Vertices) { var vert = new MeshVertex(vertex.position, vertex.normal, vertex.uv); vert.position.x *= partsScale; float distance = vert.position.x - sourceMesh.MinX * partsScale + offset; distance = Mathf.Clamp(distance, 0, spline.Length); CurveSample sample; if (false == sampleCache.TryGetValue(distance, out sample)) { sample = spline.GetSampleAtDistance(distance); if (heightSync) { var sampleLocationWS = spline.transform.TransformPoint(sample.location); RaycastHit hitInfo; if (Physics.Raycast(sampleLocationWS + Vector3.up * heightSyncTraceRange, -Vector3.up, out hitInfo, heightSyncTraceRange * 2, heightSyncLayerMask)) { var newSampleLocation = spline.transform.InverseTransformPoint(hitInfo.point); var newSampleUp = heightNormalSync ? spline.transform.InverseTransformDirection(hitInfo.normal) : sample.up; sample = new CurveSample(newSampleLocation, sample.tangent, newSampleUp, sample.scale, sample.roll, sample.distanceInCurve, sample.timeInCurve, sample.curve); } } sampleCache.Add(distance, sample); } MeshVertex bentVertex = sample.GetBent(vert); meshChunk.bentVertices.Add(bentVertex); } offset += sourceMeshes[index].Length * partsScale; meshChunk.length += sourceMeshes[index].Length * partsScale; }