protected virtual void OnFlexUpdate(FlexContainer.ParticleData _particleData) { UpdateDrawParticles(); if (transform.hasChanged && Application.isPlaying) { MoveFixedParticles(_particleData); //if (Application.isPlaying) MoveFixedParticles(_particleData); //else { m_recreateActor = 1; Recreate(); } transform.hasChanged = false; } if (m_teleport > 0) { TeleportParticles(_particleData); --m_teleport; } if (m_impulses.Count > 0) { ApplyImpulses(_particleData); m_impulses.Clear(); } UpdateBounds(_particleData); if (onFlexUpdate != null) { onFlexUpdate(_particleData); } }
void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (m_actor && m_actor.container) { m_actor.container.AddFluidIndices(m_actor.indices, m_actor.indexCount); } }
void TeleportParticles(FlexContainer.ParticleData _particleData) { Matrix4x4 offset = Matrix4x4.TRS(m_teleportPosition, Quaternion.identity, Vector3.one) * Matrix4x4.TRS(Vector3.zero, m_teleportRotation, Vector3.one) * Matrix4x4.TRS(Vector3.zero, Quaternion.Inverse(transform.rotation), Vector3.one) * Matrix4x4.TRS(-transform.position, Quaternion.identity, Vector3.one); if (m_currentAsset && m_instanceHandle) { FlexExt.Instance instance = m_instanceHandle.instance; int[] indices = new int[instance.numParticles]; FlexUtils.FastCopy(instance.particleIndices, indices); foreach (var index in indices) { Vector4 particle = _particleData.GetParticle(index); float storeW = particle.w; particle = offset.MultiplyPoint3x4(particle); particle.w = storeW; _particleData.SetParticle(index, particle); _particleData.SetVelocity(index, Vector3.zero); } } transform.position = m_teleportPosition; transform.rotation = m_teleportRotation; transform.hasChanged = false; }
void ApplyImpulses(FlexContainer.ParticleData _particleData) { if (m_currentAsset && m_instanceHandle) { FlexExt.Instance instance = m_instanceHandle.instance; int[] indices = new int[instance.numParticles]; FlexUtils.FastCopy(instance.particleIndices, indices); foreach (var info in m_impulses) { if (info.impulse.sqrMagnitude < float.Epsilon) { continue; } float mass = 0; foreach (var index in indices) { if (info.particle == -1 || info.particle == index) { Vector4 particle = _particleData.GetParticle(index); mass += 1.0f / particle.w; } } if (mass < float.Epsilon) { continue; } Vector3 velocityChange = info.impulse / mass; foreach (var index in indices) { _particleData.SetVelocity(index, _particleData.GetVelocity(index) + velocityChange); } } } }
void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (Application.isPlaying) { UpdateClothDeformation(_particleData); } }
void MoveFixedParticles(FlexContainer.ParticleData _particleData) { if (Application.isPlaying) { if (m_currentAsset && m_currentAsset.fixedParticles.Length > 0 && m_instanceHandle) { FlexExt.Instance instance = m_instanceHandle.instance; Vector4[] particles = m_currentAsset.particles; foreach (var index in m_currentAsset.fixedParticles) { if (index < particles.Length) { Vector4 particle = transform.TransformPoint(particles[index]); particle.w = 0.0f; _particleData.SetParticle(indices[index], particle); } } } } else { if (m_currentAsset && m_instanceHandle) { FlexExt.Instance instance = m_instanceHandle.instance; Vector4[] particles = m_currentAsset.particles; for (int i = 0; i < particles.Length; ++i) { Vector4 particle = transform.TransformPoint(particles[i]); particle.w = _particleData.GetParticle(indices[i]).w; _particleData.SetParticle(indices[i], particle); } } } }
void UpdateParticles(FlexContainer.ParticleData _particleData) { if (m_container != null && m_indices != null && m_indices.Length > 0) { _particleData.GetParticles(m_indices[0], m_indices.Length, m_particles); _particleData.GetVelocities(m_indices[0], m_indices.Length, m_velocities); } }
public void UpdateMesh(FlexContainer.ParticleData _particleData) { transform.rotation = Quaternion.identity; if (m_scene && m_scene.container && m_fluidMaterial) { int[] indices = m_scene.container.fluidIndices; int indexCount = m_scene.container.fluidIndexCount; if (indices.Length <= 0) { return; } if (m_indexBuffer != null && indexCount != m_indexBuffer.count) // @@@ { m_indexBuffer.Release(); m_indexBuffer = null; } if (m_indexBuffer == null && indexCount > 0) { m_indexBuffer = new ComputeBuffer(indexCount, sizeof(int)); m_mesh.SetIndices(new int[indexCount], MeshTopology.Points, 0); } if (m_indexBuffer != null) { m_indexBuffer.SetData(indices); } Vector3 boundsMin = Vector3.one * 1e10f, boundsMax = Vector3.one * 1e10f; if (indexCount > 0) { int maxParticles = m_scene.container.maxParticles; Flex.GetParticles(m_scene.container.solver, m_positionBuffer0); Flex.GetAnisotropy(m_scene.container.solver, m_anisotropy1Buffer0, m_anisotropy2Buffer0, m_anisotropy3Buffer0); CopyBufferContent(m_positionBuffer0, m_positionBuffer); CopyBufferContent(m_anisotropy1Buffer0, m_anisotropy1Buffer); CopyBufferContent(m_anisotropy2Buffer0, m_anisotropy2Buffer); CopyBufferContent(m_anisotropy3Buffer0, m_anisotropy3Buffer); m_fluidMaterial.SetBuffer("_Points", m_positionBuffer); m_fluidMaterial.SetBuffer("_Anisotropy1", m_anisotropy1Buffer); m_fluidMaterial.SetBuffer("_Anisotropy2", m_anisotropy2Buffer); m_fluidMaterial.SetBuffer("_Anisotropy3", m_anisotropy3Buffer); m_fluidMaterial.SetBuffer("_Indices", m_indexBuffer); FlexUtils.ComputeBounds(_particleData.particleData.particles, ref indices[0], indices.Length, ref boundsMin, ref boundsMax); } Vector3 center = (boundsMin + boundsMax) * 0.5f; Vector3 size = boundsMax - boundsMin; m_bounds.center = Vector3.zero; m_bounds.size = size; m_bounds.Expand(m_scene.container.radius); m_mesh.bounds = m_bounds; transform.position = center; } }
protected virtual void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (!m_actor || !m_actor.container) { return; } m_actor.container.AddFluidIndices(m_actor.indices, m_actor.indexCount); }
void UpdateBounds(FlexContainer.ParticleData _particleData) { Vector3 boundsMin = Vector3.one * float.MaxValue, boundsMax = Vector3.one * float.MaxValue; if (m_container != null && m_indices != null && m_indices.Length > 0) { FlexUtils.ComputeBounds(_particleData.particleData.particles, ref m_indices[0], m_indices.Length, ref boundsMin, ref boundsMax); } m_bounds.SetMinMax(boundsMin, boundsMax); }
protected void SetIndices(int[] _indices, int _count, FlexContainer.ParticleData _particleData) { m_indexCount = Mathf.Min(_count, m_currentAsset.maxParticles); Array.Copy(_indices, m_indices, m_indexCount); FlexExt.Instance instance = m_instanceHandle.instance; instance.numParticles = m_indexCount; if (m_indexCount > 0) { FlexUtils.FastCopy(ref m_indices[0], 0, instance.particleIndices, 0, sizeof(int) * m_indexCount); } m_instanceHandle.instance = instance; }
void UpdateClothDeformation(FlexContainer.ParticleData _particleData) { if (m_deformationTarget && m_actor.handle) { Matrix4x4 xform = transform.worldToLocalMatrix; FlexUtils.UpdateClothVertices(ref m_particles[0], ref m_vertices[0], m_particles.Length, ref m_actor.indices[0], _particleData.particleData.particles, _particleData.particleData.normals, ref xform, ref m_meshVertices[0], ref m_meshNormals[0]); m_mesh.vertices = m_meshVertices; m_mesh.normals = m_meshNormals; m_mesh.RecalculateBounds(); } }
//This function is to set the initial velocity of the fluid bool PresetVelocities(FlexContainer.ParticleData _particleData) { Vector3 initVelocity = new Vector3(0, 0, -2.0f); //Change the Vector to adjust the intial velocity FlexExt.Instance instance = m_instanceHandle.instance; int[] indices = new int[instance.numParticles]; FlexUtils.FastCopy(instance.particleIndices, indices); foreach (var index in indices) { _particleData.SetVelocity(index, initVelocity); } return(true); }
void UpdateParticles(FlexContainer.ParticleData _particleData) { if (handle && m_indices != null && m_indices.Length > 0) { float dT = Application.isPlaying ? Time.fixedDeltaTime : 0; int newCount = FlexUtils.UpdateSourceParticles(ref m_indices[0], ref m_ages[0], m_count, _particleData.particleData.particles, dT, massScale); if (newCount != m_count) { m_currentContainer.FreeParticles(m_indices, newCount, m_count - newCount); m_count = newCount; } if (m_isActive && m_startSpeed > 0) { m_spawnTime += dT; while (m_spawnTime > 0) { int spawnCount = Mathf.Min(m_asset.nozzleCount, m_asset.maxParticles - m_count); if (spawnCount > 0) { newCount += m_currentContainer.AllocParticles(m_indices, m_count, spawnCount); for (int i = m_count; i < newCount; ++i) { int index = m_indices[i]; int nozzle = i - m_count; _particleData.SetPhase(index, m_phase); Vector3 direction = transform.TransformDirection(m_asset.nozzleDirections[nozzle]); Vector3 velocity = direction * m_startSpeed; _particleData.SetVelocity(index, velocity); Vector3 position = transform.TransformPoint(m_asset.nozzlePositions[nozzle]); position -= velocity * (2.0f * dT - m_spawnTime); Vector4 particle = position; particle.w = 0.000001f;//1.0f / massScale;// _particleData.SetParticle(index, particle); _particleData.SetRestParticle(index, Vector3.zero); m_ages[i] = m_lifeTime; } m_count = newCount; } float dist = /*fluid ? m_currentContainer.fluidRest :*/ m_currentContainer.solidRest; m_spawnTime -= dist / m_startSpeed; } } SetIndices(m_indices, m_count); } }
protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (Application.isPlaying && handle) { FlexExt.Instance instance = handle.instance; Vector3 position = Vector3.zero; FlexUtils.FastCopy(instance.shapeTranslations, 0, ref position, 0, 12); Quaternion rotation = Quaternion.identity; FlexUtils.FastCopy(instance.shapeRotations, 0, ref rotation, 0, 16); transform.position = position - rotation * m_asset.shapeCenters[0]; transform.rotation = rotation; transform.hasChanged = false; } base.OnFlexUpdate(_particleData); }
protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (Application.isPlaying && m_referencePoints != null && m_referencePoints.Length >= 3) { Vector3 p0 = _particleData.GetParticle(m_referencePoints[0]); Vector3 p1 = _particleData.GetParticle(m_referencePoints[1]); Vector3 p2 = _particleData.GetParticle(m_referencePoints[2]); Vector3 clothZ = Vector3.Cross(p1 - p0, p2 - p0).normalized, clothY = Vector3.Cross(clothZ, p1 - p0).normalized; Quaternion globalRotation = Quaternion.LookRotation(clothZ, clothY) * Quaternion.Inverse(m_localRotation); Vector3 globalPosition = (p0 + p1 + p2) / 3 - globalRotation * m_localPosition; transform.position = globalPosition; transform.rotation = globalRotation; transform.hasChanged = false; } base.OnFlexUpdate(_particleData); }
void OnFlexUpdate(FlexContainer.ParticleData _particleData) { if (m_actor && m_actor.handle && m_skinningBones.Length > 0) { FlexExt.Instance instance = m_actor.handle.instance; int boneCount = m_skinningBones.Length; Vector3 bonePosition = Vector3.zero; Quaternion boneRotation = Quaternion.identity; for (int i = 0; i < boneCount; ++i) { FlexUtils.FastCopy(instance.shapeTranslations, sizeof(float) * 3 * i, ref bonePosition, 0, sizeof(float) * 3); m_skinningBones[i].position = bonePosition; FlexUtils.FastCopy(instance.shapeRotations, sizeof(float) * 4 * i, ref boneRotation, 0, sizeof(float) * 4); m_skinningBones[i].rotation = boneRotation; } } }
//This function is to get the velocity of 40 frames //And then call the CalcAcceleration function to calculate the accelerations bool CoutAccelerations(FlexContainer.ParticleData _particleData) { FlexExt.Instance instance = m_instanceHandle.instance; int[] indices = new int[instance.numParticles]; FlexUtils.FastCopy(instance.particleIndices, indices); float totalzVelocity = 0; foreach (var index in indices) { totalzVelocity += _particleData.GetVelocity(index).z; } frameVelocity.Add(totalzVelocity / indices.Length); if (frameVelocity.Count >= 40) //Change the 40 to other numbers to adjust the time of data collections { return(CalcAcceleration()); } else { return(false); } }
void OnFlexUpdate(FlexContainer.ParticleData _particleData) { FlexActor actor = GetComponent <FlexActor>(); if (actor is FlexSourceActor) { FlexSourceActor sourceActor = actor as FlexSourceActor; var main = m_particleSystem.main; float time = Time.time - Time.fixedTime; int[] indices = sourceActor.indices; int indexCount = sourceActor.indexCount; float[] ages = sourceActor.ages; m_particleSystem.Clear(); m_particleSystem.Emit(indices.Length); if (m_particles.Length != indexCount) { m_particles = new ParticleSystem.Particle[indexCount]; } float startLifetime = main.startLifetime.Evaluate(0); Color32 startColor = main.startColor.Evaluate(0); float startSize = main.startSize.Evaluate(0); for (int i = 0; i < indexCount; ++i) { ParticleSystem.Particle p = m_particles[i]; p.velocity = _particleData.GetVelocity(indices[i]);; p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime); p.remainingLifetime = ages[i] - time; p.startLifetime = startLifetime; p.startColor = startColor; p.startSize = startSize; m_particles[i] = p; } //m_particleSystem.SetParticles(m_particles, m_particles.Length); } else if (actor) { var main = m_particleSystem.main; float time = Time.time - Time.fixedTime; int[] indices = actor.indices; int indexCount = actor.indexCount; //m_particleSystem.Clear(); //m_particleSystem.Emit(indices.Length); if (m_particles.Length != indexCount) { m_particles = new ParticleSystem.Particle[indexCount]; } Color32 startColor = main.startColor.Evaluate(0); float startSize = main.startSize.Evaluate(0); for (int i = 0; i < indexCount; ++i) { ParticleSystem.Particle p = m_particles[i]; p.velocity = _particleData.GetVelocity(indices[i]); p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime); p.remainingLifetime = m_particleSystem.main.startLifetime.Evaluate(0); p.startLifetime = p.remainingLifetime; p.startColor = startColor; p.startSize = startSize; m_particles[i] = p; } //m_particleSystem.SetParticles(m_particles, m_particles.Length); } m_particleSystem.SetParticles(m_particles, m_particles.Length); }
public void UpdateShapes(FlexContainer.ParticleData _particleData) { int colliderCount = 0; foreach (var item in m_colliders) { Collider collider = item.Key; if (!(collider is SphereCollider) && !(collider is CapsuleCollider) && !(collider is BoxCollider) && !(collider is MeshCollider)) { continue; } ++colliderCount; } if (colliderCount > 0) { if (m_geometryBuffer == null || colliderCount > m_geometryBuffer.count) { if (m_geometryBuffer != null) { m_geometryBuffer.Release(); m_shapePositionBuffer.Release(); m_shapeRotationBuffer.Release(); m_shapePrevPositionBuffer.Release(); m_shapePrevRotationBuffer.Release(); m_shapeFlagsBuffer.Release(); } m_geometryBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4); m_shapePositionBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4); m_shapeRotationBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4); m_shapePrevPositionBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4); m_shapePrevRotationBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(float) * 4); m_shapeFlagsBuffer = new FlexBuffer(FlexContainer.library, colliderCount, sizeof(int)); } int shapeIndex = 0; foreach (var item in m_colliders) { Collider collider = item.Key; ShapeData shapeData = item.Value; if (!(collider is SphereCollider) && !(collider is CapsuleCollider) && !(collider is BoxCollider) && !(collider is MeshCollider)) { continue; } m_geometryBuffer.Set(shapeIndex, shapeData.geometry); m_shapeFlagsBuffer.Set(shapeIndex, shapeData.flags); m_shapePositionBuffer.Set(shapeIndex, (Vector4)(collider.transform.position + collider.transform.rotation * shapeData.shapeCenter)); m_shapeRotationBuffer.Set(shapeIndex, collider.transform.rotation * shapeData.shapePreRotation); m_shapePrevPositionBuffer.Set(shapeIndex, (Vector4)shapeData.shapePrevPosition); m_shapePrevRotationBuffer.Set(shapeIndex, shapeData.shapePrevRotation); shapeData.shapePrevPosition = collider.transform.position + collider.transform.rotation * shapeData.shapeCenter; shapeData.shapePrevRotation = collider.transform.rotation * shapeData.shapePreRotation; ++shapeIndex; } Flex.SetShapes(m_scene.container.solver, m_geometryBuffer.handle, m_shapePositionBuffer.handle, m_shapeRotationBuffer.handle, m_shapePrevPositionBuffer.handle, m_shapePrevRotationBuffer.handle, m_shapeFlagsBuffer.handle, colliderCount); } else { Flex.SetShapes(m_scene.container.solver, default(Flex.Buffer), default(Flex.Buffer), default(Flex.Buffer), default(Flex.Buffer), default(Flex.Buffer), default(Flex.Buffer), 0); } Vector3 lower = Vector3.zero, upper = Vector3.zero; FlexUtils.FastCopy(_particleData.particleData.lower, 0, ref lower, 0, sizeof(float) * 3); FlexUtils.FastCopy(_particleData.particleData.upper, 0, ref upper, 0, sizeof(float) * 3); if (lower.x < upper.x && lower.y < upper.y && lower.z < upper.z) { m_trigger.transform.position = (upper + lower) * 0.5f; m_trigger.size = upper - lower; } }
//Wrapper of the CoutAccelerations function public bool CoutAcceleration(FlexContainer.ParticleData _particleData) { return(CoutAccelerations(_particleData)); }
//Wrapper of the PresetVelocities function public bool PresetVelocity(FlexContainer.ParticleData _particleData) { return(PresetVelocities(_particleData)); }
protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData) { base.OnFlexUpdate(_particleData); UpdateParticles(_particleData); }