private void SetSwarmerTransformForRandomSetup( ref SwarmShaderSwarmerState inoutSwarmerState) { inoutSwarmerState.Position = Vector3.Scale(new Vector3(3.0f, 0.5f, 3.0f), UnityEngine.Random.insideUnitSphere); Vector3 randomForward = UnityEngine.Random.onUnitSphere; Vector3 randomUp = UnityEngine.Random.onUnitSphere; Vector3.OrthoNormalize(ref randomForward, ref randomUp); inoutSwarmerState.LocalForward = randomForward; inoutSwarmerState.LocalUp = randomUp; }
private void SetSwarmerTransformForPinwheelTiledFloor( int swarmerIndex, ref SwarmShaderSwarmerState inoutSwarmerState) { int swarmersPerTile = 6; // NOTE: The pinwheels-clusters tile as a hexagon. int tileIndex = (swarmerIndex / swarmersPerTile); int patternIndex = (swarmerIndex % swarmersPerTile); int tilingStride = Mathf.CeilToInt(Mathf.Sqrt(SwarmerCount / (float)swarmersPerTile)); int tileRowIndex = ((tileIndex / tilingStride) - (tilingStride / 2)); int tileColumnIndex = ((tileIndex % tilingStride) - (tilingStride / 2)); Vector3 swarmerCenterToRightWingtip = (SwarmerModelScale * swarmerModel.SwarmerCenterToRightWingtip); Matrix4x4 patternTransform = Matrix4x4.identity; patternTransform = ( Matrix4x4.TRS( (-1.0f * swarmerCenterToRightWingtip), Quaternion.identity, Vector3.one) * patternTransform); patternTransform = ( Matrix4x4.TRS( Vector3.zero, Quaternion.AngleAxis((90.0f + (60.0f * patternIndex)), Vector3.up), Vector3.one) * patternTransform); Vector3 tileSize = new Vector3( (6.0f * (swarmerCenterToRightWingtip.x * Mathf.Sin(60.0f * Mathf.Deg2Rad))), 0.0f, (3.0f * swarmerCenterToRightWingtip.x)); Vector3 tilePosition = Vector3.Scale( tileSize, new Vector3( (tileColumnIndex / 2.0f), 0.0f, tileRowIndex + (0.5f * (tileColumnIndex % 2)))); inoutSwarmerState.Position = (tilePosition + patternTransform.MultiplyPoint(Vector3.zero)); inoutSwarmerState.LocalForward = patternTransform.MultiplyVector(Vector3.forward); inoutSwarmerState.LocalUp = patternTransform.MultiplyVector(Vector3.up); }
private bool TryAllocateBuffers() { bool result = false; if (!SystemInfo.supportsComputeShaders) { Debug.LogError("Compute shaders are not supported on this machine. Is DX11 or later installed?"); } else if ((BehaviorComputeShader != null) && (CommonSwarmComputeShader != null)) { advanceSwarmersKernel = BehaviorComputeShader.FindKernel("kernel_advance_swarmer_states"); kernelForExtractSwarmerPositions = CommonSwarmComputeShader.FindKernel("kernel_extract_swarmer_positions"); if (forcefieldsBufferQueue == null) { forcefieldsBufferQueue = new Queue <TypedComputeBuffer <SwarmShaderForcefieldState> >(ForcefieldsComputeBufferCount); while (forcefieldsBufferQueue.Count < ForcefieldsComputeBufferCount) { forcefieldsBufferQueue.Enqueue( new TypedComputeBuffer <SwarmShaderForcefieldState>(MaxForcefieldCount)); } // NOTE: There's no need to immediately initialize the buffers, since they will be populated per-frame. } if (swarmerStateBuffers.IsInitialized == false) { var initialSwarmers = new List <SwarmShaderSwarmerState>(SwarmerCount); for (int swarmerIndex = 0; swarmerIndex < SwarmerCount; ++swarmerIndex) { var newSwarmerState = new SwarmShaderSwarmerState(); SetSwarmerTransformForHexLaceTiledFloor(swarmerIndex, ref newSwarmerState); //SetSwarmerTransformForPinwheelTiledFloor(swarmerIndex, ref newSwarmerState); //SetSwarmerTransformForRandomSetup(ref newSwarmerState); //SetSwarmerTransformForTripletTiledFloor(swarmerIndex, ref newSwarmerState); newSwarmerState.Speed = SwarmerSpeedIdle; initialSwarmers.Add(newSwarmerState); } swarmerStateBuffers.TryAllocateComputeBuffersWithValues(initialSwarmers.ToArray()); } if ((advanceSwarmersKernel != -1) && (kernelForExtractSwarmerPositions != -1) && (forcefieldsBufferQueue != null) && swarmerStateBuffers.IsInitialized) { result = true; } else { // Abort any partial-allocations. ReleaseBuffers(); } } if (DebugEnabled) { Debug.LogFormat("Compute buffer allocation attempted. [Success={0}]", result); } return(result); }
private void SetSwarmerTransformForTripletTiledFloor( int swarmerIndex, ref SwarmShaderSwarmerState inoutSwarmerState) { int swarmersPerTile = 6; // NOTE: For simplicity the tiles are pairs of triplets (forming a parallelogram). int tileIndex = (swarmerIndex / swarmersPerTile); int patternIndex = (swarmerIndex % swarmersPerTile); int tilingStride = Mathf.CeilToInt(Mathf.Sqrt(SwarmerCount / (float)swarmersPerTile)); int tileRowIndex = ((tileIndex / tilingStride) - (tilingStride / 2)); int tileColumnIndex = ((tileIndex % tilingStride) - (tilingStride / 2)); Vector3 swarmerCenterToRightWingtip = (SwarmerModelScale * swarmerModel.SwarmerCenterToRightWingtip); Matrix4x4 patternTransform = Matrix4x4.identity; if (patternIndex < 3) { patternTransform = ( Matrix4x4.TRS( (-1.0f * swarmerCenterToRightWingtip), Quaternion.identity, Vector3.one) * patternTransform); patternTransform = ( Matrix4x4.TRS( Vector3.zero, Quaternion.AngleAxis((90.0f + (120.0f * patternIndex)), Vector3.up), Vector3.one) * patternTransform); } else { Vector3 swarmerCenterToLeftWingtip = swarmerCenterToRightWingtip; swarmerCenterToLeftWingtip.x *= -1.0f; patternTransform = ( Matrix4x4.TRS( (-1.0f * swarmerCenterToLeftWingtip), Quaternion.identity, Vector3.one) * patternTransform); patternTransform = ( Matrix4x4.TRS( Vector3.zero, Quaternion.AngleAxis((-90.0f + (120.0f * patternIndex)), Vector3.up), Vector3.one) * patternTransform); } Vector3 tileSize = new Vector3( (6.0f * (swarmerCenterToRightWingtip.x * Mathf.Sin(60.0f * Mathf.Deg2Rad))), 0.0f, (3.0f * swarmerCenterToRightWingtip.x)); Vector3 tilePosition = Vector3.Scale( tileSize, new Vector3( (tileColumnIndex / 2.0f), 0.0f, tileRowIndex + (0.5f * (tileColumnIndex % 2)))); inoutSwarmerState.Position = (tilePosition + patternTransform.MultiplyPoint(Vector3.zero)); inoutSwarmerState.LocalForward = patternTransform.MultiplyVector(Vector3.forward); inoutSwarmerState.LocalUp = patternTransform.MultiplyVector(Vector3.up); }
private void SetSwarmerTransformForHexLaceTiledFloor( int swarmerIndex, ref SwarmShaderSwarmerState inoutSwarmerState) { int swarmersPerTile = 6; // NOTE: The lace-pattern tiles as a hexagon. int tileIndex = (swarmerIndex / swarmersPerTile); int patternIndex = (swarmerIndex % swarmersPerTile); int tilingStride = Mathf.CeilToInt(Mathf.Sqrt(SwarmerCount / (float)swarmersPerTile)); int tileRowIndex = ((tileIndex / tilingStride) - (tilingStride / 2)); int tileColumnIndex = ((tileIndex % tilingStride) - (tilingStride / 2)); Vector3 swarmerCenterToRightWingtip = (SwarmerModelScale * swarmerModel.SwarmerCenterToRightWingtip); Matrix4x4 patternTransform = Matrix4x4.identity; // Place the swarmer along the X+ axis, facing Z+. { patternTransform = ( Matrix4x4.TRS( ( (-1.0f * swarmerCenterToRightWingtip) + ((2 * swarmerCenterToRightWingtip.x) * Vector3.right) ), Quaternion.identity, Vector3.one) * patternTransform); } // Rotate the swarmer into position around the tile's center. { Vector3 originToTileCenter = new Vector3( swarmerCenterToRightWingtip.x, 0.0f, (2 * (swarmerCenterToRightWingtip.x * Mathf.Sin(60.0f * Mathf.Deg2Rad)))); patternTransform = ( Matrix4x4.TRS( (-1.0f * originToTileCenter), Quaternion.identity, Vector3.one) * patternTransform); patternTransform = ( Matrix4x4.TRS( Vector3.zero, Quaternion.AngleAxis((60.0f * patternIndex), Vector3.up), Vector3.one) * patternTransform); patternTransform = ( Matrix4x4.TRS( originToTileCenter, Quaternion.identity, Vector3.one) * patternTransform); } Vector3 tileSize = new Vector3( (6.0f * swarmerCenterToRightWingtip.x), 0.0f, (4.0f * (swarmerCenterToRightWingtip.x * Mathf.Sin(60.0f * Mathf.Deg2Rad)))); Vector3 tilePosition = Vector3.Scale( tileSize, new Vector3( (tileColumnIndex / 2.0f), 0.0f, tileRowIndex + (0.5f * (tileColumnIndex % 2)))); inoutSwarmerState.Position = (tilePosition + patternTransform.MultiplyPoint(Vector3.zero)); inoutSwarmerState.LocalForward = patternTransform.MultiplyVector(Vector3.forward); inoutSwarmerState.LocalUp = patternTransform.MultiplyVector(((patternIndex % 2) == 0) ? Vector3.up : Vector3.down); }