Beispiel #1
0
            [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
                };
            }
Beispiel #2
0
            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
            }
Beispiel #3
0
        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;
                    }
                }
            }
        }
Beispiel #4
0
    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
                });
            }
        }
Beispiel #6
0
            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);
    }