Пример #1
0
        private void Destruct()
        {
            Batch batch = new Batch(PicaVoxelVolume);

            Vector3 posZero = PicaVoxelVolume.transform.position +
                              (transform.rotation*
                               (-PicaVoxelVolume.Pivot + (Vector3.one*(PicaVoxelVolume.VoxelSize*0.5f))));
            Vector3 oneX = PicaVoxelVolume.transform.rotation*(new Vector3(PicaVoxelVolume.VoxelSize, 0, 0));
            Vector3 oneY = PicaVoxelVolume.transform.rotation*(new Vector3(0f, PicaVoxelVolume.VoxelSize, 0));
            Vector3 oneZ = PicaVoxelVolume.transform.rotation*(new Vector3(0, 0, PicaVoxelVolume.VoxelSize));

            Vector3 constructorPosition = transform.position;

            Frame frame = PicaVoxelVolume.GetCurrentFrame();

            //int numVox = 0;

            Vector3 checkPos = posZero;
            for (int x = 0; x < PicaVoxelVolume.XSize; x++)
            {
                Vector3 xmult = oneX*x;
                for (int y = 0; y < PicaVoxelVolume.YSize; y++)
                {
                    Vector3 ymult = oneY*y;
                    for (int z = 0; z < PicaVoxelVolume.ZSize; z++)
                    {
                        Vector3 zmult = oneZ*z;
                        checkPos.x = posZero.x + xmult.x + ymult.x + zmult.x;
                        checkPos.y = posZero.y + xmult.y + ymult.y + zmult.y;
                        checkPos.z = posZero.z + xmult.z + ymult.z + zmult.z;

                        if (frame.Voxels[x + PicaVoxelVolume.XSize*(y + PicaVoxelVolume.YSize*z)].Active &&
                            Vector3.Distance(constructorPosition, checkPos) <= radius)
                        {
                            //numVox++;
                            Voxel v = frame.Voxels[x + PicaVoxelVolume.XSize*(y + PicaVoxelVolume.YSize*z)];
                            v.Color *= PicaVoxelVolume.Material.GetColor("_Tint");
                            batch.Add(v, x, y, z, checkPos);
                            frame.Voxels[x + PicaVoxelVolume.XSize*(y + PicaVoxelVolume.YSize*z)] = new Voxel()
                            {
                                Active = false
                            };
                            frame.SetChunkAtVoxelPositionDirty(x, y, z);
                        }
                    }
                }
            }

            if (CreateParticles && batch.Voxels.Count > 0 && VoxelParticleSystem.Instance != null)
                VoxelParticleSystem.Instance.SpawnBatch(batch,
                    pos =>
                        ((transform.position - (pos + Random.insideUnitSphere))*
                         1f));

            batch.Dispose();
        }
Пример #2
0
 public void SpawnBatch(Batch batch, Func<Vector3, Vector3> velocityFunction)
 {
     int step = batch.Voxels.Count/(MaxBatchParticles >= 0 ? MaxBatchParticles : 100);
     if (step < 1) step = 1;
     for (int i = 0; i < batch.Voxels.Count; i += step)
     {
         SpawnSingle(batch.Voxels[i].WorldPosition, batch.Voxels[i].Voxel, batch.VoxelObject.VoxelSize,
             velocityFunction(batch.Voxels[i].WorldPosition));
     }
 }
Пример #3
0
        /// <summary>
        /// Adds particles to the PicaVoxel Particle System (if available) representing the shape of this volume
        /// Use it before destroying/deactivating the volume to leave particles behind
        /// </summary>
        /// <param name="particleVelocity">Initial velocity of the created particles (outward from center of volume)</param>
        /// <param name="actuallyDestroyVoxels">If true, will set all the voxels to inactive</param>
        public void Destruct(float particleVelocity, bool actuallyDestroyVoxels)
        {
            Batch batch = new Batch(this);

            Vector3 posZero = transform.position + (transform.rotation * (-Pivot + (Vector3.one * (VoxelSize * 0.5f))));
            Vector3 oneX = transform.rotation * (new Vector3(VoxelSize, 0, 0));
            Vector3 oneY = transform.rotation * (new Vector3(0f, VoxelSize, 0));
            Vector3 oneZ = transform.rotation * (new Vector3(0, 0, VoxelSize));

            Vector3 partPos = posZero;
            for (int x = 0; x < XSize; x++)
            {
                Vector3 xmult = oneX * x;
                for (int y = 0; y < YSize; y++)
                {
                    Vector3 ymult = oneY * y;
                    for (int z = 0; z < ZSize; z++)
                    {
                        Vector3 zmult = oneZ * z;
                        partPos.x = posZero.x + xmult.x + ymult.x + zmult.x;
                        partPos.y = posZero.y + xmult.y + ymult.y + zmult.y;
                        partPos.z = posZero.z + xmult.z + ymult.z + zmult.z;

                        if (Frames[CurrentFrame].Voxels[x + XSize * (y + YSize * z)].Active)
                        {
                            Voxel v = Frames[CurrentFrame].Voxels[x + XSize * (y + YSize * z)];
                            v.Color *= Material.GetColor("_Tint");
                            batch.Add(v, x, y, z, partPos);
                            if(actuallyDestroyVoxels) SetVoxelAtArrayPosition(x, y, z, new Voxel() { State = VoxelState.Hidden });
                        }
                    }
                }
            }

            if (batch.Voxels.Count > 0 && VoxelParticleSystem.Instance != null)
                VoxelParticleSystem.Instance.SpawnBatch(batch,
                    pos => (pos - transform.position).normalized * Random.Range(0f, particleVelocity * 2f));

            batch.Dispose();
        }
Пример #4
0
        /// <summary>
        /// Deactivates all particles in the current frame, within a supplied radius of a world position
        /// </summary>
        /// <param name="position">The world position of the centre of the explosion</param>
        /// <param name="explosionRadius">The radius of the explosion</param>
        /// <returns>A Batch of voxels that were destroyed by the explosion</returns>
        public Batch Explode(Vector3 position, float explosionRadius, int valueFilter, Exploder.ExplodeValueFilterOperation valueFilterOperation)
        {
            Batch batch = new Batch(this);

            Color tint = Material.GetColor("_Tint");

            Matrix4x4 transformMatrix = transform.worldToLocalMatrix;

            position += (transform.rotation * (Pivot));

            for (float x = position.x - explosionRadius; x <= position.x + explosionRadius; x += VoxelSize * 0.5f)
                for (float y = position.y - explosionRadius; y <= position.y + explosionRadius; y += VoxelSize * 0.5f)
                    for (float z = position.z - explosionRadius; z <= position.z + explosionRadius; z += VoxelSize * 0.5f)
                    {
                        Vector3 checkPos = new Vector3(x, y, z);
                        if (Vector3.Distance(checkPos, position) <= explosionRadius)
                        {
                            Vector3 localPos = transformMatrix.MultiplyPoint3x4(checkPos); //transform.InverseTransformPoint(pos);

                            //if (!Frames[CurrentFrame].IsLocalPositionInBounds(localPos)) continue;

                            int testX = (int)(localPos.x / VoxelSize);
                            int testY = (int)(localPos.y / VoxelSize);
                            int testZ = (int)(localPos.z / VoxelSize);
                            if (testX < 0 || testY < 0 || testZ < 0 || testX >= XSize || testY >= YSize || testZ >= ZSize) continue;

                            if (Frames[CurrentFrame].Voxels[testX + XSize * (testY + YSize * testZ)].Active &&
                            FilterExplosion(Frames[CurrentFrame].Voxels[testX + XSize * (testY + YSize * testZ)].Value, valueFilter, valueFilterOperation) &&
                            Vector3.Distance(position, checkPos) <= explosionRadius)
                            {
                                Voxel v = Frames[CurrentFrame].Voxels[testX + XSize * (testY + YSize * testZ)];
                                v.Color *= tint;
                                batch.Add(v, testX, testY, testZ, checkPos - (transform.rotation * (Pivot)));
                                SetVoxelStateAtArrayPosition(testX, testY, testZ, VoxelState.Hidden);
                            }
                        }
                    }

           

            return batch;
        }