2016-06-04 3 views
0

Away3D 사용 ... 생성 한 큐브 배열이 있습니다. 이 큐브 배열은 50x50x50 큐브가 포함 된 "섹터"에 있습니다. 섹터에 포함 된 유일한 것은 큐브 좌표와 색입니다. 이들은 Cube 클래스 안에 저장됩니다. 난 단지 공기 나는 방법이 ... 흥미로운 숫자를 시도했습니다공기에 닿는 큐브 찾기 [벡터 요소 찾기]

(현재 "공기"를 "컬러"는 0xFFFFFF) ...

내 현재의 방법을 터치 것들 (느린 렌더링 할) 각 객체에 대해 vector3D 점을 만들고 내 "섹터"에있는 모든 큐브의 점을 포함하는 Vector3D 집합에 indexOf를 사용했습니다.

public function renderSector(sector:Sector):void 
    { 
     trace("init sector render.."); 
     allCubes = sector.cubes; 
     //Render only things touching air. 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is not an air block 
      if (cube.color != 0xFFFFFF) 
      { 
       var topEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z); 
       var bottomEstimate:Vector3D = new Vector3D(cube.x, cube.y +1, cube.z); 
       var leftEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z +1); 
       var rightEstimate:Vector3D = new Vector3D(cube.x - 1, cube.y, cube.z); 
       var frontEstimate:Vector3D = new Vector3D(cube.x, cube.y -1, cube.z); 
       var backEstimate:Vector3D = new Vector3D(cube.x, cube.y, cube.z - 1); 

       //If the cube is next to an air block 
       if (checkForAir(topEstimate) || checkForAir(bottomEstimate) || checkForAir(leftEstimate) || checkForAir(rightEstimate) || checkForAir(frontEstimate) || checkForAir(backEstimate)) 
       { 
        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 

      } 

     } 
    } 

    private function checkForAir(point:Vector3D):Boolean 
    { 
     var returnValue:Boolean = new Boolean(false); 
     var index:int = allCubes.indexOf(point); 
     if (index > -1) 
     { 
      if (allCubes[index].color == 0xFFFFFF) 
      { 
       returnValue = true; 
      } 
     } 
     return returnValue; 
    } 

아무런 일도 일어나지 않습니다. 3DVevtor를 사용하여 옆에 에어 블록이있는 큐브가 없습니다 (약 2 분 동안 실행). 따라서, 현재 큐브의 "다음"큐브 목록을 가져 오는 동안 모든 큐브를 다시 반복 해 봅니다. 각 큐브를 서로 비교하고 내 Sector 클래스에 저장된 3DVector를 비교하여이 작업을 수행합니다.

 public function renderSector(sector:Sector):void 
    { 
     //Render only things touching air. 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is next to an air block and is not an air block, render it. 
      if (cube.color != 0xFFFFFF) 
      { 
       var touchesAir:Boolean = new Boolean(false); 

       //Search touching cubes 
       var touchingCubes:Vector.<Cube> = new Vector.<Cube>(); 

       for each (var possibleCube:Cube in sector.cubes) 
       { 
        if ((possibleCube.x == cube.x + 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) || 
         (possibleCube.y == cube.y + 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) || 
         (possibleCube.z == cube.z + 1 && possibleCube.x == cube.x && possibleCube.y == cube.y) || 
         (possibleCube.x == cube.x - 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) || 
         (possibleCube.y == cube.y - 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) || 
         (possibleCube.z == cube.z - 1 && possibleCube.x == cube.x && possibleCube.y == cube.y)) 
        { 
         touchingCubes.push(possibleCube); 
        } 
       } 

       for each (var touchingCube:Cube in touchingCubes) 
       { 
        if (touchingCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 

       if (touchesAir) 
       { 
        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 


      } 
     } 

는 그것이 하나를 찾기위한 .... 섹터의 현재 사양은 50x25x50 잔디 색깔의 블록의 평면 인은 약 15 초 정도 소요 works..but. 그래서 이것은 시간이 좀 걸릴 것입니다 ..

내 첫 번째 방법 (그리고 오 남자는 이것에 대해 브레인 스토밍을 한 뒤 약 1 시간이 걸렸습니다)은 내 메인 옆에있는 각 큐브의 위치를 ​​가져 오는 것입니다 [/ i]. 큐브를 월드 제너레이터 함수의 렌더링 순서에 따라 처리합니다.

public static function generateSector(type:String, position:Vector3D):Sector 
    { 
     var returnSector:Sector; 
     var grassArray:Vector.<uint> = new Vector.<uint>(); 
     grassArray.push(new uint(0x56b000)); 
     grassArray.push(new uint(0x63c900)); 
     grassArray.push(new uint(0x6fe300)); 
     grassArray.push(new uint(0x7cfc00)); 

     //Current types...grass field 
     switch(type) 
     { 
      case "grass": 
       var cubeArray:Vector.<Cube> = new Vector.<Cube>(); 

       for (var x:int = 0; x < 50; x++) //Moving right 
       { 
        for (var z:int = 0; z < 50; z++) //Headed out. 
        { 
         for (var y:int = 0; y < 50; y++) //From bottom up. 
         { 
          if (y < 25) 
          { 
           var color:uint = grassArray[Math.floor(Math.random() * 4)]; 
          } 
          else 
          { 
           var color:uint = 0xFFFFFF; 
          } 

          cubeArray.push(new Cube(x,y,z,color)); 
         } 
        } 
       } 
       returnSector = new Sector(position.x, position.y, position.z, cubeArray); 
       break; 
     } 

     return returnSector; 
    } 

Y 빌딩 제 (아래쪽 상단) 후 X 다음 Z

그래서

간단 권리 [아래와]? 큐브의 순서에 따라 필자는 현재 큐브의 인덱스에 1을 더하여 현재 큐브 맨 위에 큐브를 가져올 수 있어야합니다. 맞습니까?

public function renderSector(sector:Sector):void 
    { 
     //Render only things touching air. 
     var counter:int = 0; 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is next to an air block and is not an air block, render it. 
      if (cube.color != 0xFFFFFF) 
      { 
       var touchesAir:Boolean = new Boolean(false); 

       try 
       { 
        var topCube:Cube = sector.cubes[counter + 1]; 
        if (topCube.color == 0xFFFFFF) 
        { 
         touchesAir == true; 
        } 
       } 
       catch(rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var bottomCube:Cube = sector.cubes[counter - 1]; 
        if (bottomCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var leftCube:Cube = sector.cubes[counter - (50 * 50)]; 
        if (leftCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var rightCube:Cube = sector.cubes[(50 * 50) + counter]; 
        if (rightCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var frontCube:Cube = sector.cubes[counter - 50]; 
        if (frontCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var backCube:Cube = sector.cubes[counter + 50]; 
        if (backCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 

       if (touchesAir) 
       { 

        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 


      } 
     } 
    } 

이 하나가 약 4 초에 렌더링 (다른 큐브를 얻기 각각 내 50x50x50 그리드 이외의 것 모든 큐브에 대한 그들의 과정의 순서와 잡기 오류 기준)! 하지만 실제로 화면에 큐브가 나타나지 않으며 ... 추적 문이 실행되지 않습니다. 나는 이유를 알아낼 행운이 없었다.

TL; DR 큐브 격자가 있다고 가정 해 보겠습니다. 당신은 어떻게 열려있는 것들만 렌더링합니까?

또는 (좋은 대안) "볼 수있는"메쉬 만 렌더링하십시오. (나는 그 (것)들을 제거하거나 그 (것)들의 ontop의 옆에 또는 때 ontop를 클릭 할 때 그 (것)들을 제거하기 위하여 청취자가 있기 때문에 합병하지 않는 메시를 필요로한다)

답변

0

당신은 자고 잊지 그 때 잊지 그 순간을 알고있다 내부의 카운터를 참조하기 때문에 각 루프에 대해 카운터할까요? 카운터가 (내가 indexItem의 이름을 변경해야하는) 큐브는 "공기"인지 여부를 확인 내 조건 내부를 통해 실행중인 현재 큐브의 인덱스를 일치하는 것을

counter = sector.cubes.indexOf(cube); 

필요가 있는지 확인합니다.

물론 리소스 제한 오류가 발생하지만 섹터 크기를 줄이고 몇 개의 메시를 결합하면 해결할 수 있습니다.

[Fault] exception, information=Error: Error #3691: Resource limit for this resource type exceeded.