[WriteOnly] public NativeArray <RenderResult> RenderResult; // Would be nice if we could write these and read on main thread public void Execute() { var rng = new Unity.Mathematics.Random(14387 + ((uint)PixelIndex * 7)); var screenPos = Math.ToXYFloat(PixelIndex, Resolution); float3 pixel = new float3(0f); ushort rayCount = 0; for (int r = 0; r < RaysPerPixel; r++) { float2 jitter = new float2(rng.NextFloat(), rng.NextFloat()); float2 p = (screenPos + jitter) / (float2)Resolution; var ray = Camera.GetRay(p, ref rng); pixel += Trace.TraceRecursive(ray, Scene, ref rng, Fibs, 0, MaxDepth, ref rayCount); // float3 col = new float3(1f); // ushort t = 0; // for (; t < Quality.MaxDepth; t++) { // if (!Trace.TraceStep(ref ray, Scene, ref rng, Fibs, ref col)) { // break; // } // } // pixel += col; // rayCount += t; } pixel = math.sqrt(pixel / (float)RaysPerPixel); RenderResult[0] = new RenderResult { Color = pixel, RayCount = rayCount }; }
public void Execute(int i) { var rng = new Unity.Mathematics.Random(14387 + ((uint)i * 7)); var screenPos = Math.ToXYFloat(i, Quality.Resolution); float3 pixel = new float3(0f); ushort traceCount = 0; ushort usefulRays = 0; for (int r = 0; r < Quality.RaysPerPixel; r++) { float2 jitter = new float2(rng.NextFloat(), rng.NextFloat()); float2 p = (screenPos + jitter) / (float2)Quality.Resolution; var ray = Camera.GetRay(p, ref rng); float3 col = TraceRecursive(ray, Scene, ref rng, Fibs, 0, Quality.MaxDepth, ref traceCount); if (math.lengthsq(col) > 0.00001f) { pixel += col; usefulRays++; } } Screen[i] = math.sqrt(pixel / (float)usefulRays); RayCounter[0] += traceCount; // Todo: atomics, or rather, fix the amount of rays per job run }
private void OnDrawGizmos() { if (!Application.isPlaying || !_drawDebugRays) { return; } var rng = new Unity.Mathematics.Random(14387); var screenPos = new float2(0); float3 pixel = new float3(0f); Gizmos.color = new Color(1f, 1f, 1f, 0.5f); for (int s = 0; s < _scene.Spheres.Length; s++) { Gizmos.DrawSphere(_scene.Spheres[s].Center, _scene.Spheres[s].Radius); } for (int r = 0; r < 16; r++) { Gizmos.color = Color.HSVToRGB(r / 8f, 0.7f, 0.5f); float2 jitter = new float2(rng.NextFloat(), rng.NextFloat() / 16f); float2 p = (screenPos + jitter); var ray = _camera.GetRay(p, ref rng); for (int t = 0; t < 8; t++) { const float tMin = 0f; const float tMax = 1000f; Gizmos.DrawSphere(ray.origin, 0.01f); HitRecord hit; bool hitSomething = Intersect.Scene(_scene, ray, tMin, tMax, out hit); if (hitSomething) { Gizmos.DrawLine(ray.origin, hit.point); Ray3f subRay; if (!Trace.Scatter(ray, hit, ref rng, _fibs, out subRay)) { break; } ray = subRay; } else { Gizmos.DrawRay(ray.origin, math.normalize(ray.direction)); break; } } } }
public static void RandomPointsOnCircle(float3 center, float3 range, ref NativeArray <float3> positions, ref NativeArray <quaternion> rotations) { var count = positions.Length; // initialize the seed of the random number generator Unity.Mathematics.Random random = new Unity.Mathematics.Random(); random.InitState(10); for (int i = 0; i < count; i++) { positions[i] = center + random.NextFloat3(-range, range); rotations[i] = random.NextQuaternionRotation(); } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { var random = new Unity.Mathematics.Random(); random.InitState((uint)(Seed + chunkIndex * 10000)); var movements = chunk.GetNativeArray(MovementType); var distances = chunk.GetNativeArray(DistanceType); var prefabs = chunk.GetNativeArray(ArrowPrefabType); var players = chunk.GetNativeArray(PlayerType); for (int i = 0; i < chunk.Count; ++i) { var distance = distances[i]; if (distance.Value < 1.0f) { continue; } distance.Value = 0.0f; distances[i] = distance; var movement = movements[i]; var newPosition = new float3(random.NextInt(0, BoardSize.x), 1.0f, random.NextInt(0, BoardSize.y)); movement.From = movement.To; movement.To = newPosition; movements[i] = movement; var entity = CommandBuffer.CreateEntity(chunkIndex); CommandBuffer.AddComponent(chunkIndex, entity, new LbArrowSpawner() { Prefab = prefabs[i].Value, PlayerId = players[i].Value, Direction = (byte)random.NextInt(0, 4), Location = movement.From }); } }
public unsafe void Execute(int i) { float3 currentPos = Positions[i].Value; float3 currentDir = VehicleData[i].Forward; #region SpeedVariation float prevDistanceAhead = VehicleData[i].HitDistAhead; float newDistanceAhead = HitResult[i].FrontHitDistance; float distAheadDiff = prevDistanceAhead - newDistanceAhead; int hitResult = HitResult[i].HitResultPacked; float maxSpeed = RoadSegments[VehicleData[i].SegId].MaxSpeed; float newSpeed = VehicleData[i].Speed; if (hitResult == 0 && newSpeed < maxSpeed) { newSpeed += 0.5f; } else if ((hitResult & 0x1) == 1 && (distAheadDiff > 0)) { newSpeed -= (distAheadDiff / 2.0f); } newSpeed = newSpeed > maxSpeed ? maxSpeed : newSpeed; newSpeed = newSpeed < 0 ? 0 : newSpeed; #endregion float stepLength = newSpeed * DeltaTime; float segLength = RoadSegments[VehicleData[i].SegId].Length; float stepPerc = stepLength / segLength; float nextPosPerc = VehicleData[i].CurrentSegPos + stepPerc * VehicleData[i].Direction; Unity.Mathematics.Random rdGen = new Unity.Mathematics.Random(); rdGen.InitState(FrameSeed + RandSeed[i]); #region switchLane int laneCount = RoadSegments[VehicleData[i].SegId].LaneNumber; int currentLane = VehicleData[i].Lane; int laneSwitch = rdGen.NextInt(-10, 10); laneSwitch = laneSwitch / 10; if (currentLane == 0 && laneSwitch == -1) { laneSwitch = 0; } if (currentLane == (laneCount - 1) && laneSwitch == 1) { laneSwitch = 0; } int nextLane = VehicleData[i].Lane + laneSwitch; #endregion //great, still in this seg if (nextPosPerc < 1.0f && nextPosPerc > 0.0f) { //step forward float3 nextPos = currentPos + currentDir * stepLength; //offset lane nextPos += laneSwitch * VehicleData[i].Direction * RoadSegments[VehicleData[i].SegId].LaneWidth * RoadSegments[VehicleData[i].SegId].RightDirection; VehicleData[i] = new VehicleData( VehicleData[i].Id, VehicleData[i].SegId, newSpeed, VehicleData[i].Forward, nextPosPerc, VehicleData[i].Direction, nextPos, nextLane, newDistanceAhead ); Positions[i] = new Position() { Value = nextPos }; } //reach end node, find next seg else { int currentSeg = VehicleData[i].SegId; int reachedNode = VehicleData[i].Direction > 0.0f ? RoadSegments[currentSeg].EndNodeId : RoadSegments[currentSeg].StartNodeId; //find next available segment int *_availableSeg = (int *)UnsafeUtility.Malloc( 5 * sizeof(int), sizeof(int), Allocator.Temp); int availableSegCount = 0; for (int k = 0; k < 3; k++) { int seg1 = RoadNodes[reachedNode].ConnectionSegIds[k].x; int seg2 = RoadNodes[reachedNode].ConnectionSegIds[k].y; if (seg1 != -1 && seg1 != currentSeg && //not current seg, and next seg not one-way !(RoadSegments[seg1].EndNodeId == reachedNode && RoadSegments[seg1].IsOneWay == 1)) { _availableSeg[availableSegCount++] = seg1; } if (seg2 != -1 && seg2 != currentSeg && //not current seg, and next seg not one-way !(RoadSegments[seg2].EndNodeId == reachedNode && RoadSegments[seg2].IsOneWay == 1)) { _availableSeg[availableSegCount++] = seg2; } } int nextSeg = currentSeg; float dir = 1.0f; if (availableSegCount > 0)//luckily we can proceed { int selectSegId = rdGen.NextInt(0, availableSegCount); nextSeg = _availableSeg[selectSegId]; dir = RoadSegments[nextSeg].StartNodeId == reachedNode ? 1.0f : -1.0f; } else//to the end, spawn a new pos { nextSeg = rdGen.NextInt(0, RoadSegments.Length); } float3 nextForward = RoadSegments[nextSeg].Direction * dir; quaternion newRot = quaternion.LookRotation(nextForward, new float3() { x = 0, y = 1, z = 0 }); laneCount = RoadSegments[nextSeg].LaneNumber; nextLane = nextLane < laneCount ? nextLane : laneCount - 1; float laneOffset = (nextLane + 0.5f) * RoadSegments[nextSeg].LaneWidth; if (RoadSegments[nextSeg].IsOneWay == 1) { laneOffset -= (laneCount / 2.0f) * RoadSegments[nextSeg].LaneWidth; } float nextPerct = dir > 0.0f ? (nextPosPerc > 0.0f ? nextPosPerc - 1.0f : -nextPosPerc) : (nextPosPerc > 0.0f ? 2.0f - nextPosPerc : nextPosPerc + 1.0f); float3 nextPos = (1.0f - nextPerct) * RoadNodes[RoadSegments[nextSeg].StartNodeId].Position + (nextPerct) * RoadNodes[RoadSegments[nextSeg].EndNodeId].Position; nextPos += laneOffset * dir * RoadSegments[nextSeg].RightDirection; VehicleData[i] = new VehicleData( VehicleData[i].Id, nextSeg, newSpeed, nextForward, nextPerct, dir, nextPos, nextLane, newDistanceAhead ); Positions[i] = new Position() { Value = nextPos }; Rotations[i] = new Rotation() { Value = newRot }; UnsafeUtility.Free(_availableSeg, Allocator.Temp); _availableSeg = null; } }
protected override JobHandle OnUpdate(JobHandle handle) { // filter by SharedComponentData // We can also filter using a componentData for each team var redRenderMesh = EntityManager.GetSharedComponentData <RenderMesh>(GetSingleton <BattleConfigData>().prefabRed); var blueRenderMesh = EntityManager.GetSharedComponentData <RenderMesh>(GetSingleton <BattleConfigData>().prefabBlue); // get red soldiers m_AllSoldiers.SetFilter(redRenderMesh); NativeArray <Entity> redSoldierEntities = m_AllSoldiers.ToEntityArray(Allocator.TempJob); // get blue soldiers m_AllSoldiers.SetFilter(blueRenderMesh); NativeArray <Entity> blueSoldierEntities = m_AllSoldiers.ToEntityArray(Allocator.TempJob); //CONFIGURE RED SOLDIERS // Schedule Job only on the Group of m_SoldiersWithoutTarget // Red soldiers without target var random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); // using the simple random for this example //https://forum.unity.com/threads/mathematics-random-with-in-ijobprocesscomponentdata.598192/ if (blueSoldierEntities.Length > 0) { m_SoldiersWithoutTarget.SetFilter(redRenderMesh); // red soldiers without target handle = new AssignTargetJob { // when to use ToConcurrent ? commandBuffer = endSimCommandBuffer.CreateCommandBuffer().ToConcurrent(), potentialTargets = blueSoldierEntities, random = random //}.ScheduleGroup(m_SoldiersWithoutTarget, handle); }.Schedule(m_SoldiersWithoutTarget, handle); endSimCommandBuffer.AddJobHandleForProducer(handle); } else { blueSoldierEntities.Dispose(); } //CONFIGURE BLUE SOLDIERS if (redSoldierEntities.Length > 0) { m_SoldiersWithoutTarget.SetFilter(blueRenderMesh); // blue soldiers without target handle = new AssignTargetJob { commandBuffer = endSimCommandBuffer.CreateCommandBuffer().ToConcurrent(), potentialTargets = redSoldierEntities, random = random //}.ScheduleGroup(m_SoldiersWithoutTarget, handle); }.Schedule(m_SoldiersWithoutTarget, handle); endSimCommandBuffer.AddJobHandleForProducer(handle); } else { redSoldierEntities.Dispose(); } // dispose return(handle); }