/// <summary>
        /// Called when a shot has a collision.
        /// Checks all registered hittables with the provided shot data to see which one was hit.
        /// </summary>
        /// <param name="shot"></param>
        public void OnShotHit(HitData hitData, Color color)
        {
            //combine removing with adding
            Vector3?hitToOverwrite = (!hitLimitReached)? (Vector3?)null : hits[hitIndex];

            //global resultant - sum of all normalized resultants per hittable
            //resultant per hittable = sum of all triangles' (intersecting and not culled) normals
            Vector3 hitResultant;

            //if we have hits
            if (CheckAndStartSetup(hitData, out hitResultant, hitToOverwrite))
            {
/*				//get a random color
 *                              Color color = new Color(Random.Range(0f, .9f), Random.Range(0f, .9f), Random.Range(0f, .9f), 1f);*/


                //get transform matrix
                Matrix4x4 shotSpaceTRS = GetShotSpaceTRSMatrix(hitData, -hitResultant);

                foreach (Hittable hittable in hittables)
                {
                    //set rest of data
                    hittable.EndHitSetup(shotSpaceTRS, color);

                    //check again for removal - non-hit ones were not checked
                    if (hitLimitReached)
                    {
                        hittable.Clear(hitToOverwrite.Value);
                    }
                }

                //store current hit
                hits[hitIndex++] = hitData.Position;

                //check if limit reached
                if (hitIndex == MAX_MARKS)
                {
                    hitIndex        = 0;
                    hitLimitReached = true;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Starts the setup for a new hit:
        /// - culls the detected triangles according to the current cull angle.
        /// - if any left, ads a new submesh and assigns culled triangles to it (or replaces an old one in case limit of hits was reached).
        /// - creates the hit material which will be have the data set in EndHitSetup.
        /// </summary>
        /// <param name="hitData">Current shot data.</param>
        /// <param name="hitToReplace">Hit location which will be overwritten by the new hit.</param>
        /// <returns>Resultant vector from non-culled triangles.</returns>
        public Vector3 StartHitSetup(HitData hitData, Vector3?hitToReplace)
        {
            //submesh triangles
            int[] submeshTris;

            //cull triangles based on hit direction and get resultant of rest of triangles' normal
            Vector3 resultant = FilterTris(hitData.Direction, out submeshTris);;

            //everything got culled
            if (submeshTris.Length == 0)
            {
                return(resultant);                //Vector3.zero
            }
            //check if we 'have' the hit to replace
            int subMeshIndex = (hitToReplace.HasValue)? GetHitSubMeshIndex(hitToReplace.Value) : -1;

            //search for free slot
            if (subMeshIndex == -1 && emptySlots > 0)
            {
                subMeshIndex = materials.IndexOf(null);

                material = MaterialPooler.Instance.GetRandomBulletMaterial(renderer, this, hitData.Position);

/*				material = new Material(hitData.Mark);*/
                materials[subMeshIndex] = material;

                hits[subMeshIndex - subMeshCountInitial] = hitData.Position;

                emptySlots--;
            }
            else
            {
                //if we have a hit to replace
                if (subMeshIndex != -1)
                {
                    material = materials[subMeshIndex];
                    hits[subMeshIndex - subMeshCountInitial] = hitData.Position;

                    hitOverwritten = true;
                }
                else                 //no hit to replace, create new
                {
                    //save index
                    subMeshIndex = mesh.subMeshCount;

                    //make room fornew submesh
                    mesh.subMeshCount++;


                    material = MaterialPooler.Instance.GetRandomBulletMaterial(renderer, this, hitData.Position);

/*					//create mark material
 *                                      material = new Material(hitData.Mark);*/

                    materials.Add(material);

                    //store hit
                    hits.Add(hitData.Position);
                }
            }

            //set the triangles of the new mark's submesh
            mesh.SetTriangles(submeshTris, subMeshIndex, false);

            return(resultant);
        }