科技公司网站首页做电子简历的网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:33
当前位置: 首页 > news >正文
科技公司网站首页,做电子简历的网站,美食网站开发与设计报告,相应式网站效果 基于体素的射线检测 一个漏检的射线检测 从起点一直递增指定步长即可得到一个稀疏的检测 bool Raycast(Vector3 from, Vector3 forword, float maxDistance){int loop 6666;Vector3 pos from;Debug.DrawLine(from, from forword * maxDistance, Color.red);while (loo…效果 基于体素的射线检测 一个漏检的射线检测 从起点一直递增指定步长即可得到一个稀疏的检测 bool Raycast(Vector3 from, Vector3 forword, float maxDistance){int loop 6666;Vector3 pos from;Debug.DrawLine(from, from forword * maxDistance, Color.red);while (loop– 0){pos forword;if((pos - from).magnitude maxDistance){break;}Vector3Int blockPosition Vector3Int.RoundToInt(pos);if (world.HasBlockCollider(blockPosition)){return true;}if(world.HasVoxelCollider(blockPosition)){return true;}Gizmos.DrawWireCube(blockPosition,Vector3.one);}return false;}可以看到上图有很多地方因为迭代的步长过大导致漏检 为了补充这些空洞可以使用Bresenham重新修改算法 填补空缺 修改步长会导致迭代次数暴增并且想要不漏检需要很小的步长。下面使用了检测相交点是否连续检测是否空缺 首先射线经过的点必然连续那么可以我们就可以直接对比上一次离开方块时的点和当前进入方块的点 leavePoint GetIntersectPoint(aabb, leaveRay, leavePoint);static Vector3 GetIntersectPoint(Bounds aabb, Ray ray, Vector3 point){if (aabb.IntersectRay(ray, out var distance)){point ray.GetPoint(distance);}else // 由于射线平行于方块的面或边导致没有相交稍微放大方块强行相交{aabb.size * 1.01f;if (aabb.IntersectRay(ray, out distance)){point ray.GetPoint(distance);}}return point;} 如果2个坐标是相等的。可以认为射线并没有漏检 oldPoint posInt; aabb.center posInt; aabb.size Vector3.one; if (aabb.IntersectRay(enterRay, out distance)) {enterPoint enterRay.GetPoint(distance);if (leavePoint ! enterPoint){//存在漏检} }否则就需要补充漏检的方块有可能射线一次漏了2个方块没有检测 先检测最靠近离开位置的坐标是否有方块 distance (enterPoint - leavePoint).magnitude * 0.01f; fillPoint Vector3Int.RoundToInt(leavePoint forward * distance); if (checkCollider(fillPoint, ref hitInfo))return true;再检测靠近进入位置的坐标是否有方块 fillPoint2 Vector3Int.RoundToInt(enterPoint - forward * distance); if (fillPoint2 ! fillPoint) {if (checkCollider(fillPoint2, ref hitInfo))return true; }手动覆盖漏检的方块青色为补充的检测 多个轴向观察射线是否在绘制的方块内 细分方块 把一个方块切成 444 共计64个方块 世界坐标转为体素内部坐标 public Vector3 PositionToVoxelPosition(Vector3 position){var pos Vector3Int.RoundToInt(position);position - voxelOffset;position - pos;position * voxelScale;position Vector3Int.one;return Vector3Int.RoundToInt(position);}切分时使用ulong存储体素信息。如果某一位是1即当前位置拥有体素 方块内部坐标转索引。使用索引检测当前位是否有体素 public int VoxelPositionToIndex(Vector3 position){return (int)Mathf.Abs(position.x * BlockWorld.planeCount position.y * BlockWorld.voxelScale position.z);}体素检测先检测当前位置是否是体素块如果是检测方块体内该位置是否有体素 public bool HasVoxelCollider(Vector3 position, out Vector3 result){if (voxelDict.TryGetValue(Vector3Int.RoundToInt(position), out ulong value)){result PositionToVoxelPosition(position);int index VoxelPositionToIndex(result);if ((value index 1) 1){result VoxelPositionToWorldPosition(position, result);return true;}result Vector3.zero;return false;}result position;return false;} 完整代码 using System; using System.Collections.Generic; using UnityEngine;public class BlockWorld:IDisposable {public const int voxelScale 4;public const int planeCount voxelScale * voxelScale;public static Vector3 voxelSize Vector3.one / voxelScale;public static Vector3 voxelStartOffset voxelSize * 0.5f;public static Vector3 voxelAABBSize Vector3.one BlockWorld.voxelSize * 2;public static Vector3 voxelOffset Vector3.one * 0.5f voxelStartOffset;private readonly DictionaryVector3Int, bool blocks new DictionaryVector3Int, bool();private readonly DictionaryVector3Int, ulong voxelDict new DictionaryVector3Int, ulong();public void AddBlock(Vector3Int position){blocks[position] true;}public void AddVoxel(Vector3Int blockPosition, ulong value){voxelDict[blockPosition] value;}public void AddVoxel( Vector3 voxelPosition){var blockPosition Vector3Int.RoundToInt(voxelPosition);voxelDict.TryGetValue(blockPosition, out ulong value);voxelPosition PositionToVoxelPosition(voxelPosition);int index VoxelPositionToIndex(voxelPosition);value | (ulong)1 index;voxelDict[blockPosition] value;}public Vector3 PositionToVoxelPosition(Vector3 position){var pos Vector3Int.RoundToInt(position);position - voxelOffset;position - pos;position * voxelScale;position Vector3Int.one;return Vector3Int.RoundToInt(position);}public Vector3 VoxelPositionToWorldPosition(Vector3 position, Vector3 voxelPosition){return voxelPosition / BlockWorld.voxelScale BlockWorld.voxelSize BlockWorld.voxelStartOffset Vector3Int.RoundToInt(position);}public int VoxelPositionToIndex(Vector3 position){return (int)Mathf.Abs(position.x * BlockWorld.planeCount position.y * BlockWorld.voxelScale position.z);}public void Clear(){blocks.Clear();voxelDict.Clear();}public bool HasBlockCollider(Vector3Int position){return blocks.ContainsKey(position);}public bool HasVoxelCollider(Vector3Int position){return voxelDict.ContainsKey(position);}public bool HasVoxelCollider(Vector3 position, out Vector3 result){if (voxelDict.TryGetValue(Vector3Int.RoundToInt(position), out ulong value)){result PositionToVoxelPosition(position);int index VoxelPositionToIndex(result);if( (value index 1) 1){result VoxelPositionToWorldPosition(position, result);return true;}result Vector3.zero;return false;}result position;return false;}public ulong GetVoxelValue(Vector3Int position){voxelDict.TryGetValue(position, out var value);return value;}void IDisposable.Dispose(){Clear();} } using UnityEngine;public static class BlockPhysics {private const int MAX_LOOP_COUNT 6666;public static bool Raycast(BlockWorld world, Vector3 from, Vector3 forward, float maxDistance, out RaycastHit hitInfo, bool isDraw false){ #if !UNITY_EDITORisDraw false; #endiffloat distance;int loop MAX_LOOP_COUNT;Vector3 to from forward * maxDistance;Vector3 pos from;Vector3 tForward forward * 0.9f;Vector3Int posInt Vector3Int.RoundToInt(pos);Vector3Int oldPoint posInt;Vector3Int fillPoint;Vector3Int fillPoint2;Vector3 leavePoint from;Vector3 enterPoint default;Bounds aabb default;Ray enterRay default;Ray leaveRay default;enterRay.origin from;enterRay.direction forward;leaveRay.origin to forward * 2;leaveRay.direction -forward;hitInfo default;aabb.center posInt;aabb.size Vector3.one;if (aabb.IntersectRay(leaveRay, out distance)){leavePoint leaveRay.GetPoint(distance);}if (maxDistance - (int)maxDistance 0){maxDistance forward.magnitude * 0.9f;}#if UNITY_EDITORint index 0;if (isDraw){Debug.DrawLine(from, to, Color.red);} #endifwhile (loop– 0){pos tForward;if ((pos - from).magnitude maxDistance){break;}posInt Vector3Int.RoundToInt(pos);if (posInt oldPoint)continue;oldPoint posInt;aabb.center posInt;aabb.size Vector3.one;if (aabb.IntersectRay(enterRay, out distance)){enterPoint enterRay.GetPoint(distance);if (leavePoint ! enterPoint){distance (enterPoint - leavePoint).magnitude * 0.01f;fillPoint Vector3Int.RoundToInt(leavePoint forward * distance);if (checkCollider(fillPoint, ref hitInfo))return true;fillPoint2 Vector3Int.RoundToInt(enterPoint - forward * distance);if (fillPoint2 ! fillPoint){if (checkCollider(fillPoint2, ref hitInfo))return true;}}}if (checkCollider(posInt, ref hitInfo))return true;leavePoint GetIntersectPoint(aabb, leaveRay, leavePoint);}return false;bool checkCollider(Vector3Int origin, ref RaycastHit hitInfo){ #if UNITY_EDITORif (isDraw){Gizmos.color Color.grey;Gizmos.DrawWireCube(origin, Vector3.one);UnityEditor.Handles.Label(origin, \([{index}]);} #endifif (world.HasBlockCollider(origin)){aabb.center origin;aabb.size Vector3.one;hitInfo.point origin;if (aabb.IntersectRay(enterRay, out distance)){hitInfo.point enterRay.GetPoint(distance); #if UNITY_EDITORif (isDraw){Gizmos.color Color.red;Gizmos.DrawWireCube(origin, Vector3.one);UnityEditor.Handles.Label(hitInfo.point, \)【{hitInfo.point.x}, {hitInfo.point.y}, {hitInfo.point.z}】);} #endif}return true;}if (world.HasVoxelCollider(origin)){if (RaycastVoxel(world, from, forward, origin, maxDistance, out hitInfo, isDraw)){return true;}}return false;}}static bool RaycastVoxel(BlockWorld world, Vector3 from, Vector3 forward, Vector3 blockPosition, float maxDistance, out RaycastHit hitInfo, bool isDraw false){hitInfo default;float distance 0f;int loop MAX_LOOP_COUNT;Vector3 pos from;Vector3 tForward forward * 0.24f;Vector3 voxelPosition;Vector3 leavePoint from;Vector3 result default;Vector3 fillPoint default;Vector3 fillPoint2 default;Vector3 enterPoint default;Bounds aabb default;Ray enterRay default;enterRay.origin from;enterRay.direction forward;Ray leaveRay default;leaveRay.origin (from forward * maxDistance) forward * 2;leaveRay.direction -forward;aabb.center blockPosition;aabb.size Vector3.one;if (aabb.IntersectRay(enterRay, out distance)){enterPoint enterRay.GetPoint(distance);pos enterPoint;leavePoint enterPoint;}#if UNITY_EDITORif (isDraw){Gizmos.DrawWireSphere(enterPoint, 0.05f);}int index 0; #endifwhile (loop– 0){pos tForward;if ((pos - from).magnitude maxDistance){break;}aabb.center blockPosition;aabb.size BlockWorld.voxelAABBSize;if (!aabb.Contains(pos))break;voxelPosition world.PositionToVoxelPosition(pos);voxelPosition world.VoxelPositionToWorldPosition(pos, voxelPosition);aabb.center voxelPosition;aabb.size BlockWorld.voxelSize;if (aabb.IntersectRay(enterRay, out distance)){enterPoint enterRay.GetPoint(distance);if (leavePoint ! enterPoint){distance (enterPoint - leavePoint).magnitude * 0.01f;fillPoint leavePoint forward * distance;if (checkCollider(fillPoint, ref hitInfo)){return true;}fillPoint2 enterPoint - forward * distance;if (world.PositionToVoxelPosition(fillPoint) ! world.PositionToVoxelPosition(fillPoint2)){if (checkCollider(fillPoint2, ref hitInfo))return true;}}}if (checkCollider(pos, ref hitInfo)){return true;}leavePoint GetIntersectPoint(aabb, leaveRay, leavePoint);}return false;bool checkCollider(Vector3 origin, ref RaycastHit hitInfo){ #if UNITY_EDITORif (isDraw){Gizmos.color Color.gray;var voxelPoint world.PositionToVoxelPosition(origin);voxelPoint world.VoxelPositionToWorldPosition(origin, voxelPoint);Gizmos.DrawWireCube(voxelPoint, BlockWorld.voxelSize);UnityEditor.Handles.Label(voxelPoint, \([{index}]);} #endifif (world.HasVoxelCollider(origin, out result)){aabb.center result;aabb.size BlockWorld.voxelSize;hitInfo.point result;if (aabb.IntersectRay(enterRay, out distance)){hitInfo.point enterRay.GetPoint(distance); #if UNITY_EDITORif (isDraw){Gizmos.color Color.red;var voxelPoint world.PositionToVoxelPosition(origin);voxelPoint world.VoxelPositionToWorldPosition(origin, voxelPoint);Gizmos.DrawWireCube(voxelPoint, BlockWorld.voxelSize);UnityEditor.Handles.Label(hitInfo.point, \)【{hitInfo.point.x}, {hitInfo.point.y}, {hitInfo.point.z}】);} #endif}return true;}return false;}}static Vector3 GetIntersectPoint(Bounds aabb, Ray ray, Vector3 point){if (aabb.IntersectRay(ray, out var distance)){point ray.GetPoint(distance);}else{aabb.size * 1.01f;if (aabb.IntersectRay(ray, out distance)){point ray.GetPoint(distance);}}return point;} }
- 上一篇: 科技公司建设网站公司公司页面设计
- 下一篇: 科技公司网站推荐qq可以做公司免费网站
相关文章
-
科技公司建设网站公司公司页面设计
科技公司建设网站公司公司页面设计
- 技术栈
- 2026年03月21日
-
科技公司php网站模版wordpress阿里秀模板
科技公司php网站模版wordpress阿里秀模板
- 技术栈
- 2026年03月21日
-
科技粉末wordpress seo插件哪个好
科技粉末wordpress seo插件哪个好
- 技术栈
- 2026年03月21日
-
科技公司网站推荐qq可以做公司免费网站
科技公司网站推荐qq可以做公司免费网站
- 技术栈
- 2026年03月21日
-
科技公司主要经营什么深圳网站seo哪家快
科技公司主要经营什么深圳网站seo哪家快
- 技术栈
- 2026年03月21日
-
科技馆网站建设背景简历模板网站免费
科技馆网站建设背景简历模板网站免费
- 技术栈
- 2026年03月21日
