private JobHandle JobChain(JobHandle inputDeps) { var size = data.Length * data.checks[0].values.Length * 2; // Build the RaycastCommands var commands = new NativeArray <RaycastCommand>(size, Allocator.TempJob); // Output var results = new NativeArray <RaycastHit>(size, Allocator.TempJob); var raycastJob = new RaycastSetUp { checkpoints = data.checks, commands = commands }; var deps = raycastJob.Schedule(inputDeps); deps.Complete(); // Do the raycast job deps = RaycastCommand.ScheduleBatch(commands, results, 32, inputDeps); deps.Complete(); UpdatePlayerLap(results); // Dispose the raycast commands as the results are needed. commands.Dispose(); // Dispose the results, we've finished processing them. results.Dispose(); return(deps); }
void Update() { handle.Complete(); // Raycastの開始点と位置を設定 for (int i = 0; i < transformArray.length; i++) { var targetPosition = transformArray[i].position; var direction = Vector3.down; var command = new RaycastCommand(targetPosition, direction); commands[i] = command; } // 移動のコマンドを設定 UpdatePosition updatePositionJob = new UpdatePosition() { raycastResults = results, velocitys = velocity }; ApplyPosition applyPosition = new ApplyPosition() { velocitys = velocity }; // 並列処理を実行(即完了待ち) // 終わったらコマンドに使ったバッファは不要なので破棄 var raycastJobHandle = RaycastCommand.ScheduleBatch(commands, results, 20); var updatePositionHandle = updatePositionJob.Schedule(transformArray.length, 20, raycastJobHandle); handle = applyPosition.Schedule(transformArray, updatePositionHandle); JobHandle.ScheduleBatchedJobs(); }
private void CastRaysJob() { NativeArray <RaycastHit> results = new NativeArray <RaycastHit>(rayAmount, Allocator.TempJob); NativeArray <RaycastCommand> commands = new NativeArray <RaycastCommand>(rayAmount, Allocator.TempJob); for (int i = 0; i < rayAmount; i++) { Ray r = cam.ViewportPointToRay(new Vector3(rPoints[i].x, rPoints[i].y, 0f)); commands[i] = new RaycastCommand(r.origin, r.direction, rayDistance); } var handle = RaycastCommand.ScheduleBatch(commands, results, 1); handle.Complete(); for (int i = 0; i < results.Length; i++) { RaycastHit batchedHit = results[i]; if (batchedHit.collider == null) { continue; } batchedHit.transform.GetComponent <OcclusionObject>()?.HitOcclude(stayTime); } commands.Dispose(); results.Dispose(); }
// Update is called once per frame void Update() { var commands = new NativeArray <RaycastCommand>(targets.Length, Allocator.TempJob); var results = new NativeArray <RaycastHit>(targets.Length, Allocator.Temp); for (int i = 0; i < targets.Length; i++) { var targetPosition = targets[i].position; var direction = Vector3.down; var command = new RaycastCommand(targetPosition, direction); commands[i] = command; } RaycastCommand.ScheduleBatch(commands, results, 20).Complete(); commands.Dispose(); for (int i = 0; i < targets.Length; i++) { Debug.Log(velocity.Length); if (velocity[i] < 0 && results[i].distance < 0.5f) { velocity[i] = 1; } velocity[i] -= 0.098f; } results.Dispose(); for (int i = 0; i < targets.Length; i++) { targets[i].localPosition += Vector3.up * velocity[i]; } }
void DoReadyShots(int count, ref List <RaycastHit> hits, ref JobHandle handle) { try { // Create arrays for shot rays and results with variable size shotRays = new NativeArray <RaycastCommand>(count, Allocator.TempJob); shotResults = new NativeArray <RaycastHit>(count, Allocator.TempJob); // Get all ready shot rays for (int i = 0; i < count; i++) { shotRays[i] = allShots[readyShotsIndex[i]].ray; } // Schedule raycast job handle = RaycastCommand.ScheduleBatch(shotRays, shotResults, count, default(JobHandle)); // Confirm completion of job handle.Complete(); // Immediately send results to a proper list hits = shotResults.ToList(); // Dispose of temporary arrays shotRays.Dispose(); shotResults.Dispose(); } catch (InvalidOperationException e) { Debug.LogWarning("[CaughtError] Error in DoReadyShots: " + e.ToString()); } }
/// <summary> /// 该接口要达到一定量级性能才会更优 /// </summary> /// <param name="bounds"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static RaycastHit[] RaycastGrid(Vector3 center, int width, int height, int layerMask = -1, int maxHists = 1, int maxHeight = 1000) { var results = new NativeArray <RaycastHit>(width * height * maxHists, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(width * height, Allocator.TempJob); var halfWidth = (width - 1) * 0.5f; var halfHeight = (height - 1) * 0.5f; var offsetHeight = Vector3.up * maxHeight; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { var rayCenter = center - new Vector3(halfWidth, center.y, halfHeight) + new Vector3(i, 0, j); commands[i + j * width] = new RaycastCommand(rayCenter + offsetHeight, Vector3.down, layerMask: layerMask); } } if (maxHists == 1) { var handle = RaycastCommand.ScheduleBatch(commands, results, 1); handle.Complete(); } else { var handle = new RaycastAllCommand(commands, results, maxHists); handle.Schedule(default).Complete();
// Update is called once per frame void Update() { handle.Complete(); for (int i = 0; i < targets.Length; i++) { var targetPosition = targets[i].position; var direction = Vector3.down; var command = new RaycastCommand(targetPosition, direction); commands[i] = command; } // 移動的command 設定 UpdatePosition updatePositionJob = new UpdatePosition() { raycastResults = results, objVelocitys = velocities }; ApplyPosition applyPosition = new ApplyPosition() { objVelocitys = velocities }; var raycastJobHandle = RaycastCommand.ScheduleBatch(commands, results, 20); var updatePositionHandle = updatePositionJob.Schedule(transformArray.length, 20, raycastJobHandle); handle = applyPosition.Schedule(transformArray, updatePositionHandle); }
private void RaycasExample() { // Perform a single raycast using RaycastCommand and wait for it to complete // Setup the command and result buffers var results = new NativeArray <RaycastHit>(1, Allocator.Temp); var commands = new NativeArray <RaycastCommand>(1, Allocator.Temp); // Set the data of the first command Vector3 origin = Vector3.forward * -10; Vector3 direction = Vector3.forward; commands[0] = new RaycastCommand(origin, direction); // Schedule the batch of raycasts JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle)); // Wait for the batch processing job to complete handle.Complete(); // Copy the result. If batchedHit.collider is null there was no hit RaycastHit batchedHit = results[0]; // Dispose the buffers results.Dispose(); commands.Dispose(); }
// root = the bottom left most sector. public void SetAdjacentNodes(int2 root) { s_SetAdjacentNodes.Begin(); float3 centerOffset = new float3(root.x * m_GridSpacing, root.y * m_GridSpacing, 0.0f) - new float3(m_GridDimensions * m_GridSpacing, m_GridDimensions * m_GridSpacing, 0.0f); for (int y = 0, index = 0; y < m_RootNodeDimension; y++) { for (int x = 0; x < m_RootNodeDimension; x++, index++) { m_RaycastCommands[index] = new RaycastCommand(centerOffset + new float3(x * m_SectorSpacing, y * m_SectorSpacing, -1.0f), Vector3.forward, 1.5f, m_ParentLayer, 1); } } RaycastCommand.ScheduleBatch(m_RaycastCommands, m_RootNodeHits, 8).Complete(); for (int y = 0, index = 0; y < m_RootNodeDimension; y++) { for (int x = 0; x < m_RootNodeDimension; x++, index++) { colliderArray[index] = (m_RootNodeHits[index].collider != null) ? m_RootNodeHits[index].collider.GetComponent <GravNodeCollider>() : null; parentGridPoses[index] = (colliderArray[index] != null) ? colliderArray[index].GetNodeTransform() : centerOffset + new float3(x * m_SectorSpacing, y * m_SectorSpacing, 0.0f); } } s_SetAdjacentNodes.End(); }
public static void BakeObject(GameObject obj, float rayLength, bool stochastic = false, int sampleCount = 8) { float startTime = Time.realtimeSinceStartup; Mesh mesh = obj.GetComponent <MeshFilter>().sharedMesh; List <Vector3> vert = new List <Vector3>(); mesh.GetVertices(vert); List <Vector3> norm = new List <Vector3>(); mesh.GetNormals(norm); Color[] colors = new Color[vert.Count]; for (int r = 0; r < sampleCount; r++) { var results = new NativeArray <RaycastHit>(mesh.vertexCount, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(mesh.vertexCount, Allocator.TempJob); for (int i = 0; i < mesh.vertexCount; i++) { Vector3 randomVectors = new Vector3(Random.Range(-1, 1), Random.Range(-1, 1), Random.Range(-1, 1)) * 0.3f; if (!stochastic) { randomVectors = Vector3.zero; } commands[i] = new RaycastCommand(obj.transform.localToWorldMatrix.MultiplyPoint(vert[i]) + obj.transform.localToWorldMatrix.MultiplyVector(norm[i]) * 0.002f, obj.transform.localToWorldMatrix.MultiplyVector(norm[i]) + randomVectors, rayLength); } JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle)); handle.Complete(); for (int i = 0; i < results.Length; i++) { if (results[i].collider != null) { RaycastHit hit = results[i]; if (!isPointLit(hit.point + hit.normal * 0.01f)) { colors[i] += fromValue(Mathf.Clamp01(hit.distance / rayLength)) / sampleCount; } else { colors[i] += Color.white / sampleCount; } } else { colors[i] += Color.white / sampleCount; } } commands.Dispose(); results.Dispose(); } if (useDebug) { Debug.Log("Baked object " + obj.name + " in " + (Time.realtimeSinceStartup - startTime) + "ms"); } mesh.SetColors(colors); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (minionSystem == null) { return(inputDeps); } if (arrows.Length == 0) { return(inputDeps); } if (minions.Length == 0) { return(inputDeps); } // Update seems to be called after Play mode has been exited // ============ REALLOC =============== // todo fix nativearray NativeArrayExtensions.ResizeNativeArray(ref raycastHits, math.max(raycastHits.Length, arrows.Length)); NativeArrayExtensions.ResizeNativeArray(ref raycastCommands, math.max(raycastCommands.Length, arrows.Length)); // ============ JOB CREATION =============== var arrowJob = new ProgressArrowJob { raycastCommands = raycastCommands, arrows = arrows.data, arrowEntities = arrows.entities, dt = Time.deltaTime, allMinionTransforms = minions.transforms, buckets = minionSystem.CollisionBuckets, minionConstData = minions.constData, AttackCommands = CommandSystem.AttackCommandsConcurrent, minionEntities = minions.entities, queueForKillingEntities = lifecycleManager.queueForKillingEntities }; var stopArrowJob = new StopArrowsJob { raycastHits = raycastHits, arrows = arrows.data, arrowEntities = arrows.entities, stoppedArrowsQueue = lifecycleManager.deathQueue }; var arrowJobFence = arrowJob.Schedule(arrows.Length, SimulationState.SmallBatchSize, JobHandle.CombineDependencies(inputDeps, CommandSystem.AttackCommandsFence)); arrowJobFence.Complete(); var raycastJobFence = RaycastCommand.ScheduleBatch(raycastCommands, raycastHits, SimulationState.SmallBatchSize, arrowJobFence); var stopArrowJobFence = stopArrowJob.Schedule(arrows.Length, SimulationState.SmallBatchSize, raycastJobFence); CommandSystem.AttackCommandsConcurrentFence = JobHandle.CombineDependencies(stopArrowJobFence, CommandSystem.AttackCommandsConcurrentFence); // Complete arrow movement return(stopArrowJobFence); }
/* * Might cause memory leaks if interrupted before NativeArrays are disposed */ private static void ParallelIncrementalRaycast( List <ParallelIncrementalRaycastData> paths ) { List <ParallelIncrementalRaycastData> remainingPaths = new List <ParallelIncrementalRaycastData>(paths); NativeArray <RaycastHit> results = default(NativeArray <RaycastHit>); NativeArray <RaycastCommand> commands = default(NativeArray <RaycastCommand>); do { results = new NativeArray <RaycastHit>(remainingPaths.Count, Allocator.TempJob); commands = new NativeArray <RaycastCommand>(remainingPaths.Count, Allocator.TempJob); for (int i = 0; i < remainingPaths.Count; i++) { commands[i] = new RaycastCommand( remainingPaths[i].start, remainingPaths[i].dx, remainingPaths[i].remaining.magnitude, instance.collisionMask ); } JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle)); handle.Complete(); for (int i = 0; i < remainingPaths.Count; i++) { ParallelIncrementalRaycastData data = remainingPaths[i]; RaycastHit batchedHit = results[i]; data.hit = batchedHit; if (batchedHit.collider == null) { continue; } data.remaining -= (batchedHit.point - data.start); data.start = (batchedHit.point + data.dx); if (batchedHit.collider.transform.GetComponent <Obstacle>() != null) { IntersectionResult result = new IntersectionResult(batchedHit); data.onIntersect(result); } } remainingPaths.RemoveAll( path => !path.continueCondition(path.result) || path.hit.collider == null ); results.Dispose(); commands.Dispose(); } while (remainingPaths.Count > 0); }
// Build a job chain with a given scanner. JobHandle BuildJobChain(float3 origin, Scanner scanner, JobHandle deps) { // Transform output destination var transforms = _voxelGroup.GetComponentDataArray <LocalToWorld>(); if (transforms.Length == 0) { return(deps); } if (_pTransformCount == null) { // Initialize the transform counter. _pTransformCount = (int *)UnsafeUtility.Malloc( sizeof(int), sizeof(int), Allocator.Persistent); *_pTransformCount = 0; } else { // Wrap around the transform counter to avoid overlfow. *_pTransformCount %= transforms.Length; } // Total count of rays var total = scanner.Resolution.x * scanner.Resolution.y; // Ray cast command/result array var commands = new NativeArray <RaycastCommand>(total, Allocator.TempJob); var hits = new NativeArray <RaycastHit>(total, Allocator.TempJob); // 1: Set-up jobs var setupJob = new SetupJob { Commands = commands, Origin = origin, Extent = scanner.Extent, Resolution = scanner.Resolution }; deps = setupJob.Schedule(total, 64, deps); // 2: Raycast jobs deps = RaycastCommand.ScheduleBatch(commands, hits, 16, deps); // 3: Transfer jobs var transferJob = new TransferJob { RaycastCommands = commands, RaycastHits = hits, Scale = scanner.Extent.x * 2 / scanner.Resolution.x, Transforms = transforms, pCounter = _pTransformCount }; deps = transferJob.Schedule(total, 64, deps); return(deps); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { RocketRotateJob rocketRotateJob = new RocketRotateJob { vec3CometPosition = GameManager.instance.Comet.position, }; JobHandle rotateHandle = rocketRotateJob.Schedule(this, inputDeps); if (m_raycastJH.IsCompleted) { World.Active.GetOrCreateManager <SpaceShipMoveSystem>().m_spaceShipOffsetMoveJH.Complete(); for (int i = 0; i < m_rocketProximityGroup.Length; ++i) { float DistBetweenCenters = Vector3.Distance(GameManager.instance.Comet.position, m_rocketProximityGroup.Positions[i].Value); if (DistBetweenCenters < GameManager.instance.CometColliderRadius * 2 + m_rocketProximityGroup.Collisions[i].Height) { m_entityManager.SetComponentData(m_rocketProximityGroup.Entities[i], new RocketProximityState { Value = 2 }); } else if (i < m_raycastHits.Length - 1 && m_raycastHits[i].collider != null) { m_entityManager.SetComponentData(m_rocketProximityGroup.Entities[i], new RocketProximityState { Value = 1 }); } else { m_entityManager.SetComponentData(m_rocketProximityGroup.Entities[i], new RocketProximityState { Value = 0 }); } } m_raycastHits.Dispose(); m_raycastCommands.Dispose(); int opSize = m_rocketProximityGroup.Length; m_raycastCommands = new NativeArray <RaycastCommand>(opSize, Allocator.Persistent); m_raycastHits = new NativeArray <RaycastHit>(opSize, Allocator.Persistent); for (int i = 0; i < opSize; ++i) { Vector3 pos = m_rocketProximityGroup.Positions[i].Value; Vector3 dir = GameManager.instance.Comet.position - pos; m_raycastCommands[i] = new RaycastCommand(pos, dir.normalized, raycastLength, cometRaycastMask); } m_raycastJH = RaycastCommand.ScheduleBatch(m_raycastCommands, m_raycastHits, GameManager.SubJobsSplit, rotateHandle); } return(JobHandle.CombineDependencies(rotateHandle, m_raycastJH)); }
public void Schedule(int minCommandsPerJob = 32, JobHandle dependsOn = default(JobHandle)) { #if DEBUG if (_raycastBatchJobHandle.IsCompleted == false) { Debug.LogWarning("WARNING: Scheduling when job is not complete"); } #endif _raycastBatchJobHandle = RaycastCommand.ScheduleBatch(_raycastCommands, _raycastHitresults, minCommandsPerJob, dependsOn); }
public void Schedule(int minCommandsPerJob = 32, JobHandle dependsOn = default(JobHandle)) { #if DEBUG if (_handle.IsCompleted == false) { Debug.LogWarning("Scheduling when job is not complete"); } #endif this._handle = RaycastCommand.ScheduleBatch(this.commands, this.results, minCommandsPerJob, dependsOn); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { int curEntityCnt = m_mobQuery.CalculateEntityCount(); if (na_rayCommands.Length != curEntityCnt) { mobMovementJH.Complete(); na_rayCommands.Dispose(); na_rayCommands = new NativeArray <RaycastCommand>(curEntityCnt, Allocator.Persistent); na_rayHits.Dispose(); na_rayHits = new NativeArray <RaycastHit>(curEntityCnt, Allocator.Persistent); } var setupRaycastJob = new SetupRaycastJob { layerMask = 1 << LayerMask.NameToLayer("Wall"), rayCommands = na_rayCommands, wallPos = GameManager.instance.Target.transform.position }; var setupJH = setupRaycastJob.Schedule(this, inputDeps); var raycastJH = RaycastCommand.ScheduleBatch(na_rayCommands, na_rayHits, 100, setupJH); var mobMovementJob = new MobMovementJob { deltaTime = Time.deltaTime, hits = na_rayHits }; mobMovementJH = mobMovementJob.Schedule(this, raycastJH); mobMovementJH.Complete(); var entities = m_mobQuery.ToEntityArray(Allocator.TempJob); for (int i = 0; i < entities.Length; ++i) { if (EntityManager.GetComponentData <MobStateData>(entities[i]).Value == MobState.Throw) { Vector3 curPos = EntityManager.GetComponentData <Translation>(entities[i]).Value; SpearBehavior spear = PoolManager.instance.SpearPool.SpawnObject(curPos + SettingsManager.ThrowingPoint, Quaternion.Euler(SettingsManager.ThrowingRotation)) as SpearBehavior; spear.Throw(); EntityManager.SetComponentData(entities[i], new MobStateData { Value = MobState.FromTarget }); } } entities.Dispose(); return(mobMovementJH); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { int count = DetectHitQuery.CalculateEntityCount(); if (count == 0) { return(inputDeps); } var resultsArray = new NativeArray <RaycastHit>(count, Allocator.TempJob); NativeArray <RaycastCommand> commands = new NativeArray <RaycastCommand>(count, Allocator.TempJob); var setupCommandsJob = new SetupCommandsJob { prevPositions = DetectHitQuery.ToComponentDataArray <PreviousTranslation>(Allocator.TempJob), curPositions = DetectHitQuery.ToComponentDataArray <Translation>(Allocator.TempJob), rotations = DetectHitQuery.ToComponentDataArray <Rotation>(Allocator.TempJob), cmds = commands, hitMask = Parameters.GetProjectileHitLayer() }.Schedule(count, 1, inputDeps); RaycastCommand.ScheduleBatch(commands, resultsArray, 32, setupCommandsJob).Complete(); var entities = DetectHitQuery.ToEntityArray(Allocator.TempJob); var ownerIDs = DetectHitQuery.ToComponentDataArray <OwnerID>(Allocator.TempJob); var projectiles = DetectHitQuery.ToComponentDataArray <Projectile>(Allocator.TempJob); HitHandlerData handlerData; for (int i = 0; i < resultsArray.Length; i++) { if (resultsArray[i].collider != null) { handlerData = new HitHandlerData { Entity = entities[i], ProjectileID = projectiles[i].ID, OwnerID = ownerIDs[i].Value }; onHitSystemFinish?.Invoke(handlerData, resultsArray[i]); } } entities.Dispose(); ownerIDs.Dispose(); projectiles.Dispose(); commands.Dispose(); resultsArray.Dispose(); return(inputDeps); }
protected override JobHandle OnUpdate(JobHandle deps) { _position = _vehicleGroup.GetComponentDataArray <Position>(); _rotation = _vehicleGroup.GetComponentDataArray <Rotation>(); _vehicleData = _vehicleGroup.GetComponentDataArray <VehicleData>(); _hitResult = _vehicleGroup.GetComponentDataArray <HitResult>(); //RoadGraph.Instance.VehicleData = _vehicleData; var commands = new NativeArray <RaycastCommand>(Capacity, Allocator.TempJob); var hits = new NativeArray <RaycastHit>(Capacity, Allocator.TempJob); // 1: Setup Raycast for environment sensing var setupRaycastJob = new SetupRaycastJob { Commands = commands, VehicleData = _vehicleData, }; deps = setupRaycastJob.Schedule(Capacity, 64, deps); // 2: Raycast jobs deps = RaycastCommand.ScheduleBatch(commands, hits, 64, deps); // 3: Transfer raycast result to vehicledata var transferJob = new TransferRaycastResultJob { Commands = commands, RaycastHits = hits, HitResult = _hitResult }; deps = transferJob.Schedule(Capacity, 64, deps); // 4: move vehicle var vehicleMoveJob = new VehicleMoveJob() { Positions = _position, Rotations = _rotation, VehicleData = _vehicleData, RoadNodes = _roadNodes, RoadSegments = _roadSegments, RandSeed = _randSeed, HitResult = _hitResult }; vehicleMoveJob.FrameSeed = (uint)Time.frameCount; vehicleMoveJob.DeltaTime = Time.deltaTime; deps = vehicleMoveJob.Schedule(Capacity, 64, deps); return(deps); }
private void Update() { // SETUP: Allow for 1 result (the closest) per job var results = new NativeArray <RaycastHit>(1, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(1, Allocator.TempJob); // Here we create one command. Simple demo. // NOTE: This system is optimized to can handle MANY commands. commands[0] = new RaycastCommand(transform.position, Vector3.down, _rayDistance); if (_isDebug == true) { foreach (RaycastCommand raycastCommand in commands) { Debug.DrawRay(raycastCommand.from, raycastCommand.direction * raycastCommand.distance, Color.red, _rayDuration); } } // ************************ // PHYSICS - Here is the RaycastCommand functionality // ************************ var handle = RaycastCommand.ScheduleBatch(commands, results, 1); // Wait for the batch processing job to complete handle.Complete(); // Iterate through all results (Max 1 in this situation) foreach (RaycastHit raycastHit in results) { if (raycastHit.collider != null) { //Debug.Log("Colliding with: " + raycastHit.collider.gameObject.name); if (raycastHit.collider.gameObject.layer == LayerMask.NameToLayer(ProjectConstants.FloorLayer)) { Debug.Log("The floor is close below."); } if (raycastHit.collider.gameObject.layer == LayerMask.NameToLayer(ProjectConstants.RampLayer)) { Debug.Log("The ramp is close below."); } } } // Dispose the buffers results.Dispose(); commands.Dispose(); }
void RaycastParallel(float ts) { // 1. 병렬처리 구조체 인스턴스화 및 데이터 채우기 m_SaveRayDirection = new SaveRayDirection() { _ChannelNum = m_RayChannelNum, _HoriStartDeg = m_HorzStartAngle, _VertStartDeg = m_VertStartAngle, _HoriInterval = m_HorzInterval, _VertInterval = m_VertInterval, _BodyOrientation = transform.rotation, _Origin = transform.position, _MaxDistance = m_MaxDistance, _RayRotation = m_RayRotation, _VertOffset = m_VertOffset, _RaycastCommand = m_RaycastCommand, _RayAngles = m_RayAngles, }; m_SaveDetectionData = new SaveDetectionData() { _RaycastHit = m_Result, _RaycastCommand = m_RaycastCommand, _RayAngles = m_RayAngles, _isSaveIntensity = m_isSaveIntensity, _LidarFrame = m_LidarDetectionData, _WorldFrame = m_WorldDetectionData, _time = ts, _frame = frame, }; // 2. 방향각(Direction) 계산을 위한 병렬처리 스케쥴 등록 // mDIrP 내부 변수 __RayCast에 RaycastCommand의 원점, 방향 등 저장 m_RayDirectionHandle = m_SaveRayDirection.Schedule(m_PointCount, 256); // 3. RaycastCommand 병렬처리 스케쥴 등록 // 발사할 방향이 정의된 m_Command(Native array of RaycastCommands)는 m_DirHandle에 의존함 m_RayCastHandle = RaycastCommand.ScheduleBatch(m_RaycastCommand, m_Result, 256, m_RayDirectionHandle); // 4. Point 저장 스케쥴 등록 // m_SaveRayPoint에서 저장에 사용할 입력값 _Input, _Input2는 m_RayCastHandle에 의존함 // 즉, Execute 될 때 m_RayCastHandle에 저장된 m_Result, m_Command가 _Input으로 입력됨 // 최종적으로 m_PointData에 결과 저장 m_SaveRayHandle = m_SaveDetectionData.Schedule(m_PointCount, 256, m_RayCastHandle); // 모든 병렬처리 완료 설정 // 완료 설정부분이 너무 빠르면 모든 정보가 전부 처리되지 않는다. // LateUpdate혹은 다음 프레임에 처리하는 방법을 염두에 두어야 한다. m_SaveRayHandle.Complete(); }
private void FixedUpdate() { // Avoid updating every physics frame timeAccum += Time.fixedDeltaTime; if (timeAccum >= updateInterval) { timeAccum -= updateInterval; // Fill raycast command buffer for (int i = 0; i < numSensors; ++i) { float angle = (fovStart + deltaAngle * i) * Mathf.Deg2Rad; Vector3 direction = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)); direction = transform.TransformDirection(direction); raycastCommands[i] = new RaycastCommand(transform.position, direction, range, blocksLineOfSight); } // Perform raycasts JobHandle handle = RaycastCommand.ScheduleBatch(raycastCommands, raycastResults, 1, default(JobHandle)); handle.Complete(); // Read results into senses for (int i = 0; i < numSensors; ++i) { RaycastHit hit = raycastResults[i]; if (hit.collider != null) { senses[i] = 1 - hit.distance / range; if (displayDebug) { Debug.DrawLine(transform.position, hit.point, Color.Lerp(Color.white, Color.red, senses[i]), updateInterval - timeAccum); } } else { senses[i] = 0; if (displayDebug) { float angle = (fovStart + deltaAngle * i) * Mathf.Deg2Rad; Vector3 direction = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)); direction = transform.TransformDirection(direction); Debug.DrawRay(transform.position, direction * range, Color.white, updateInterval - timeAccum); } } } } }
private void ViewCastBatch(float[] angles, ViewCastInfo[] resultArray) { if (resultArray.Length < angles.Length) { throw new ArgumentException("Results can't be smaller than angles", nameof(resultArray)); } // Allocate arrays for raycast data var hits = new NativeArray <RaycastHit>(angles.Length, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(angles.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); Vector3 origin = target.transform.position; // Create raycast commands for (var i = 0; i < angles.Length; i++) { commands[i] = new RaycastCommand(origin, DirectionFromAngle(angles[i], true), viewRange, obstacleMask); } // Schedule raycasts JobHandle handle = RaycastCommand.ScheduleBatch(commands, hits, 1); // Wait for the raycasting to complete handle.Complete(); // Fill results array for (var i = 0; i < hits.Length; i++) { RaycastHit hit = hits[i]; // Collider is only valid if hit (yes, this is in the docs) if (hit.collider) { resultArray[i] = new ViewCastInfo(true, hit.point, hit.distance, angles[i], hit.normal); } else { resultArray[i] = new ViewCastInfo(false, origin + DirectionFromAngle(angles[i], true) * viewRange, viewRange, angles[i], hit.normal); } } // Dispose raycast data hits.Dispose(); commands.Dispose(); }
public void ScheduleCommand() { Results = new NativeArray <RaycastHit>(HIT_BUFFER, Allocator.Persistent); Commands = new NativeArray <RaycastCommand>(1, Allocator.Persistent); RaycastCommand command = new RaycastCommand(); command.from = Start; command.direction = (End - Start).normalized; command.layerMask = LayerMask; command.maxHits = HIT_BUFFER; Commands[0] = command; Handle = RaycastCommand.ScheduleBatch(Commands, Results, 1); }
private void Update() { var jobMove = new BulletMove { BulletData = _bulletDataArray.AsDeferredJobArray(), RaycastCommands = _raycastCommandArray.AsDeferredJobArray(), LayerMask = bulletCollisionLayer, DeltaTime = Time.deltaTime, Time = Time.time }; var handlerMove = jobMove.Schedule(_transformAccessArray); handlerMove.Complete(); var handlerRaycast = RaycastCommand.ScheduleBatch(_raycastCommandArray, _raycastHitArray, 16); handlerRaycast.Complete(); MainThreadProcess(); }
static bool MainRaycastScreenToWorld(this Camera camera, Vector3 vPosition , ref NativeArray <RaycastHit> narHit , int nLayerMask = -5, int nMaxHit = -1, float fDistance = (float)(3.40282347E+38)) { var hRay = camera.ScreenPointToRay(vPosition); var narCommand = new NativeArray <RaycastCommand>(1, Allocator.TempJob); narCommand[0] = new RaycastCommand(hRay.origin, hRay.direction, fDistance, nLayerMask, nMaxHit); RaycastCommand.ScheduleBatch(narCommand, narHit, 1).Complete(); narCommand.Dispose(); return(narHit[0].collider != null); }
public static void BakeObjectAlt(GameObject obj) { Vector3 sunDir = new Vector3(); foreach (Light light in FindObjectsOfType <Light>()) { if (light.type == LightType.Directional) { sunDir = light.transform.forward; } } Mesh mesh = obj.GetComponent <MeshFilter>().mesh; List <Vector3> vert = new List <Vector3>(); mesh.GetVertices(vert); List <Vector3> norm = new List <Vector3>(); mesh.GetNormals(norm); Color[] colors = new Color[vert.Count]; var results = new NativeArray <RaycastHit>(mesh.vertexCount, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(mesh.vertexCount, Allocator.TempJob); for (int i = 0; i < mesh.vertexCount; i++) { commands[i] = new RaycastCommand(obj.transform.localToWorldMatrix.MultiplyPoint(vert[i]) + obj.transform.localToWorldMatrix.MultiplyVector(norm[i]) * 0.001f, -sunDir, 512f); } JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle)); handle.Complete(); for (int i = 0; i < results.Length; i++) { if (results[i].collider != null) { colors[i] = fromValue(0.33f); } else { colors[i] = Color.white; } } commands.Dispose(); results.Dispose(); mesh.SetColors(colors); }
/// <summary> /// Does several raycasts using the RaycasCommand job. /// </summary> public void DoRayCastCommands() { //Initialize array to store the results of all the raycastcommands. //Number equals the number of casts times max hits. commandHits = new NativeArray <RaycastHit>(castDirections.Count * maxHits, Allocator.Temp); //Create the raycastcommands. raycastCommands = new NativeArray <RaycastCommand>(castDirections.Count, Allocator.Temp); for (int i = 0; i < castDirections.Count; i++) { if (castDistances.Count <= i) { raycastCommands [i] = new RaycastCommand(transform.position, castDirections [i], castDistances [castDistances.Count - 1], hitLayers, maxHits); } else { raycastCommands [i] = new RaycastCommand(transform.position, castDirections [i], castDistances [i], hitLayers, maxHits); } } //Schedule the job jobHandle = RaycastCommand.ScheduleBatch(raycastCommands, commandHits, minCommandsPerJob); jobHandle.Complete(); GameObject temp; for (int i = 0; i < commandHits.Length; i++) { //A result hit something if the collider is not null. if (commandHits [i].collider != null) { if (!useDebugLine) { temp = Instantiate(linePrefab); temp.transform.position = transform.position; HitLineRenderer hlr = temp.GetComponent <HitLineRenderer>(); hlr.Activate(lineDuration, transform.position, commandHits [i].point, hitLineColor); } else { Debug.DrawLine(transform.position, commandHits [i].point, hitLineColor, lineDuration); } } } //Dipose of results to prevent memory leak. commandHits.Dispose(); raycastCommands.Dispose(); }
private List <Vector3> GetPlacementPositions(LayerMask terrainLayerMask, NativeArray <Quad> placementAreasNativeArray, float minimumDistanceBetweenPositions) { Profiler.BeginSample("Vegetator Raycasts"); var positions = new NativeList <float3>(Allocator.TempJob); GetRaycastPoints(placementAreasNativeArray, minimumDistanceBetweenPositions, positions); var commands = new NativeArray <RaycastCommand>(positions.Length, Allocator.TempJob); var createRaycastsJob = new CreateVegetatorRaycastsJob { LayerMask = terrainLayerMask, Positions = positions, Output = commands }; createRaycastsJob.Schedule(positions.Length, 128).Complete(); var raycastResults = new NativeArray <RaycastHit>(positions.Length, Allocator.TempJob); RaycastCommand.ScheduleBatch(commands, raycastResults, 128).Complete(); commands.Dispose(); positions.Dispose(); if (raycastResults.Length == 0) { Debug.LogWarning($"[VegetationPlacement] Couldn't place trees"); raycastResults.Dispose(); return(new List <Vector3>()); } var placementPositions = new List <Vector3>(); Profiler.BeginSample("Copying Raycast results"); for (var i = 0; i < raycastResults.Length; i++) { placementPositions.Add(raycastResults[i].point); } Profiler.EndSample(); raycastResults.Dispose(); Profiler.EndSample(); return(placementPositions); }
/// <summary> /// 更新処理 /// </summary> void Update() { Vector3 cameraPosition = Camera.main.transform.position; cameraPosition.y = 0.0f; nextFrameSyncHandle.Complete(); // RayCastHitの作成 float rayLength = Time.deltaTime * 3.0f; var createRaycastCommandJob = new CreateRaycastJob() { rayLength = rayLength, rayCastCommands = this.rayCastCommmands, velocities = this.velocities }; // キャラクターの移動Job var characterJob = new CharacterMoveJob() { velocities = this.velocities, drawParameter = this.drawParameter, rayCastResults = rayCastResults, cameraPosition = cameraPosition, deltaTime = Time.deltaTime, realtimeSinceStartup = Time.realtimeSinceStartup, animationLength = animationInfo.animationLength, animationRectInfo = this.animationRectInfo }; // raycast のJob化 JobHandle rayCastJobHandle = RaycastCommand.ScheduleBatch(rayCastCommmands, rayCastResults, 1); JobHandle.ScheduleBatchedJobs(); // Rectの指定 for (int i = 0; i < characterNum; ++i) { boardRenderers[i].SetRect(drawParameter[i]); } var moveJobHandl = characterJob.Schedule(transformAccessArray, rayCastJobHandle); nextFrameSyncHandle = createRaycastCommandJob.Schedule(this.transformAccessArray, moveJobHandl); JobHandle.ScheduleBatchedJobs(); }