/// <summary> /// Smooth occlusion per face (position in AOArray) /// </summary> byte SmoothOcclusion(SmallCube _cube, int _aox, int _aoy, int _aoz, int _vidx, int _side) { byte oc = 0; int offset; Vector3Int o = new Vector3Int(_aox, _aoy, _aoz); Vector3Int r = CubeHelpers.SolidVertex[_vidx]; int sign = _side & 1; int dim = _side >> 1; if (sign != 0) { o[CubeHelpers.D[dim]] += 1; } else { o[CubeHelpers.D[dim]] -= 1; } //current int x, y, z; int xx, yy, zz; x = o[0]; y = o[1]; z = o[2]; x = x + 1; y = y + 1; z = z + 1; xx = x; yy = y; zz = z; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; //3darray[(x * (sy*sz)) + (z * sy) + y] offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); if (dim == 0)//X { int s1 = 1; int s2 = 1; if (r[1] == 0) { s1 = -s1; //corner } if (r[2] == 0) { s2 = -s2; //corner } //Y-Z yy = y; zz = z + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); yy = y + s1; zz = z; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); yy = y + s1; zz = z + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); } else if (dim == 1)//Y { int s1 = 1; int s2 = 1; if (r[0] == 0) { s1 = -s1; //corner } if (r[2] == 0) { s2 = -s2; //corner } //X-Z xx = x; zz = z + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); xx = x + s1; zz = z; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); xx = x + s1; zz = z + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); } else if (dim == 2) //Z { int s1 = 1; int s2 = 1; if (r[0] == 0) { s1 = -s1; //corner } if (r[1] == 0) { s2 = -s2; //corner } //X-Y xx = x; yy = y + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); xx = x + s1; yy = y; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); xx = x + s1; yy = y + s2; offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; offset = Math.Max(0, offset); offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1); oc += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1); } return(oc); }
public bool RayCast(Vector3 _o, Vector3 _ray, float _dist, ref BoundingBox _obb, ref Vector3Int _oposcubeTrack, out SmallCube _ocube) { float cs = (float)CubeHelpers.CUBE_SIZE; //Step from _o to _ray float d = 0.0f; Vector3 p = _o; _ocube = CubeArray3D.m_emptyCube; //Debug.WriteLine("RayCast start at {0} dir {1}", p, _ray); while (d < _dist) { //Get cube at _o int cx = (int)(p.X / CubeHelpers.CUBE_SIZE); //World To Cube unit int cy = (int)(p.Y / CubeHelpers.CUBE_SIZE); int cz = (int)(p.Z / CubeHelpers.CUBE_SIZE); if (cx >= 0 && cy >= 0 && cz >= 0 && cx < m_array.CUBESIZEX && cy < m_array.CUBESIZEY && cz < m_array.CUBESIZEZ) { SmallCube cube; m_array.GetCube(cx, cy, cz, out cube); if (cube.byMatL0 != 0) { //Debug.WriteLine("Cube Found at {0},{1},{2}", cx, cy, cz); _oposcubeTrack.X = cx; //In cube unit _oposcubeTrack.Y = cy; //In cube unit _oposcubeTrack.Z = cz; //BB _obb.Min.X = (float)(cx * CubeHelpers.CUBE_SIZE); //To world coords _obb.Min.Y = (float)(cy * CubeHelpers.CUBE_SIZE); //To world coords _obb.Min.Z = (float)(cz * CubeHelpers.CUBE_SIZE); //To world coords _obb.Max.X = _obb.Min.X + cs; _obb.Max.Y = _obb.Min.Y + cs; _obb.Max.Z = _obb.Min.Z + cs; _ocube = cube; return(true); } } d += 1.0f; p += _ray; } //Debug.WriteLine("RayCast end at {0}", p); return(false); }