123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- using UnityEngine;
- using System.Collections.Generic;
- // Beta modifier
- [AddComponentMenu("Modifiers/Deformable")]
- public class MegaDeformable : MegaModifier
- {
- public override string ModName() { return "Deformable"; }
- public override void ModStart(MegaModifiers mc)
- {
- Vector3 s = mc.mesh.bounds.size;
- sizeFactor = Mathf.Min(s.x, s.y, s.z);
- if ( mc.mesh.colors != null )
- baseColors = mc.mesh.colors;
- LoadMap(mc);
- }
- public override bool ModLateUpdate(MegaModContext mc)
- {
- return Prepare(mc);
- }
- public override bool Prepare(MegaModContext mc)
- {
- if ( offsets == null || offsets.Length != mc.mod.verts.Length )
- offsets = new Vector3[mc.mod.verts.Length];
- return true;
- }
- public override MegaModChannel ChannelsReq() { return MegaModChannel.Verts | MegaModChannel.Col; }
- public override MegaModChannel ChannelsChanged() { return MegaModChannel.Verts | MegaModChannel.Col; }
- public float Hardness = 0.5f; // Impact resistance to calculate amount of deformation applied to the mesh
- public bool DeformMeshCollider = true; // Configure if the mesh at collider must also be deformed (only works if a MeshCollider is in use)
- public float UpdateFrequency = 0.0f; // Configure the mesh (and mesh collider) update frequency in times per second. 0 for real time (high CPU usage)
- public float MaxVertexMov = 0.0f; // Maximum movement allowed for a vertex from its original position (0 means no limit)
- public Color32 DeformedVertexColor = Color.gray; // Color to be applied at deformed vertices (only works for shaders that handle vertices colors)
- public Texture2D HardnessMap; // Texture to modulate maximum movement allowed (uses alpha channel)
- public bool usedecay = false;
- public float decay = 0.999f;
- public Color[] baseColors; // Backup of original mesh vertices colors
- public float sizeFactor; // Size factor of mesh
- public float[] map;
- public Vector3[] offsets;
- public float impactFactor = 0.1f;
- public float ColForce = 0.5f;
- private void LoadMesh()
- {
- }
- public void LoadMap()
- {
- MegaModifiers mc = GetComponent<MegaModifyObject>();
- if ( mc )
- {
- LoadMap(mc);
- }
- }
- private void LoadMap(MegaModifiers mc)
- {
- // Load hardness map
- if ( HardnessMap )
- {
- Vector2[] uvs = mc.mesh.uv;
- map = new float[uvs.Length];
- for ( int c = 0; c < uvs.Length; c++ )
- {
- Vector2 uv = uvs[c];
- map[c] = HardnessMap.GetPixelBilinear(uv.x, uv.y).a;
- }
- }
- else
- map = null;
- }
- public override void Modify(MegaModifiers mc)
- {
- // Calc collision force
- float colForce = ColForce;//Mathf.Min(1, collision.impactForceSum.sqrMagnitude / 1000);
- sizeFactor = mc.bbox.size.magnitude;
- // distFactor is the amount of deforming in local coordinates
- float distFactor = colForce * (sizeFactor * (impactFactor / Mathf.Max(impactFactor, Hardness)));
- // Deform process
- if ( colpoints != null )
- {
- for ( int c = 0; c < colpoints.Length; c++ )
- {
- ContactPoint contact = colpoints[c];
- for ( int i = 0; i < verts.Length; i++ )
- {
- // Apply deformation only on vertex inside "blast area"
- Vector3 vp = verts[i] + offsets[i];
- Vector3 p = transform.InverseTransformPoint(contact.point);
- float d = (vp - p).sqrMagnitude;
- if ( d <= distFactor )
- {
- // Deformation is the collision normal with local deforming ratio
- // Vertices near the impact point must also be more deformed
- Vector3 n = transform.InverseTransformDirection(contact.normal * (1.0f - (d / distFactor)) * distFactor);
- // Apply hardness map if any
- if ( map != null )
- n *= 1.0f - map[i];
- // Deform vertex
- //vertices[i] += n;
- offsets[i] += n;
- // Apply max vertex movement if configured
- // Here the deformed vertex position is just scaled down to keep the best deformation while respecting limits
- if ( MaxVertexMov > 0.0f )
- {
- float max = MaxVertexMov;
- n = offsets[i]; //vertices[i] - baseVertices[i];
- d = n.magnitude;
- if ( d > max )
- offsets[i] = (n * (max / d));
- // Apply vertex color deformation
- // Deform color is applied in proportional amount with vertex distance and max deform
- if ( baseColors.Length > 0 )
- {
- d = (d / MaxVertexMov);
- mc.cols[i] = Color.Lerp(baseColors[i], DeformedVertexColor, d);
- }
- }
- else
- {
- if ( mc.cols.Length > 0 )
- {
- // Apply vertex color deformation
- // Deform color is applied in proportional amount with vertex distance and mesh distance factor
- mc.cols[i] = Color.Lerp(baseColors[i], DeformedVertexColor, offsets[i].magnitude / (distFactor * 10.0f));
- }
- }
- }
- }
- }
- }
- colpoints = null;
- if ( !usedecay )
- {
- for ( int i = 0; i < verts.Length; i++ )
- {
- sverts[i].x = verts[i].x + offsets[i].x;
- sverts[i].y = verts[i].y + offsets[i].y;
- sverts[i].z = verts[i].z + offsets[i].z;
- }
- }
- else
- {
- for ( int i = 0; i < verts.Length; i++ )
- {
- offsets[i].x *= decay;
- offsets[i].y *= decay;
- offsets[i].z *= decay;
- sverts[i].x = verts[i].x + offsets[i].x;
- sverts[i].y = verts[i].y + offsets[i].y;
- sverts[i].z = verts[i].z + offsets[i].z;
- }
- }
- }
- // We could find the megamod comp
- public void Repair(float repair, MegaModifiers mc)
- {
- Repair(repair, Vector3.zero, 0.0f, mc);
- }
- public void Repair(float repair, Vector3 point, float radius, MegaModifiers mc)
- {
- // Check mesh assigned
- if ( (!mc.mesh) ) //|| (!meshFilter) )
- return;
- // Transform world point to mesh local
- point = transform.InverseTransformPoint(point);
- // Repairing is done returning vertices position and color to original positions by requested amount
- //int i = 0;
- for ( int i = 0; i < mc.verts.Length; i++ )
- {
- // Check for repair inside radius
- if ( radius > 0.0f )
- {
- if ( (point - mc.sverts[i]).magnitude >= radius )
- continue;
- }
- // Repair
- Vector3 n = offsets[i]; //vertices[i] - baseVertices[i];
- offsets[i] = n * (1.0f - repair);
- if ( baseColors.Length > 0 )
- mc.cols[i] = Color.Lerp(mc.cols[i], baseColors[i], repair);
- }
- }
- //public bool doDeform = false;
- public MegaModifyObject modobj;
- ContactPoint[] colpoints;
- void OnCollisionEnter(Collision collision)
- {
- if ( modobj == null )
- modobj = GetComponent<MegaModifyObject>();
- if ( modobj )
- modobj.Enabled = true;
- colpoints = collision.contacts;
- //doDeform = true;
- }
- void OnCollisionStay(Collision collision)
- {
- colpoints = collision.contacts;
- //doDeform = true;
- }
- void OnCollisionExit(Collision collision)
- {
- if ( modobj )
- {
- if ( !usedecay )
- modobj.Enabled = false;
- }
- }
- }
|