コード例 #1
0
ファイル: scene.cpp プロジェクト: darwin/inferno
int testhit_trianglevoxel(int triid, int vx, int vy, int vz)
{
  float boxcenter[3];
  float boxhalfsize[3];
  float triverts[3][3];
  
  boxcenter[0] = vx + (float)VOXELSIZEX/2;
  boxcenter[1] = vy + (float)VOXELSIZEY/2;
  boxcenter[2] = vz + (float)VOXELSIZEZ/2;

  boxhalfsize[0] = (float)VOXELSIZEX/2;
  boxhalfsize[1] = (float)VOXELSIZEY/2;
  boxhalfsize[2] = (float)VOXELSIZEZ/2;

  triverts[0][0] = scene_triinfos[triid].v0.x;
  triverts[0][1] = scene_triinfos[triid].v0.y;
  triverts[0][2] = scene_triinfos[triid].v0.z;

  triverts[1][0] = scene_triinfos[triid].v1.x;
  triverts[1][1] = scene_triinfos[triid].v1.y;
  triverts[1][2] = scene_triinfos[triid].v1.z;

  triverts[2][0] = scene_triinfos[triid].v2.x;
  triverts[2][1] = scene_triinfos[triid].v2.y;
  triverts[2][2] = scene_triinfos[triid].v2.z;

  return triBoxOverlap(boxcenter, boxhalfsize, triverts);
}
コード例 #2
0
ファイル: CharacterController.cpp プロジェクト: jpmit/mutiny
bool CharacterController::colliding(Vector3 center, Vector3 half, Vector3 a, Vector3 b, Vector3 c)
{
  float tri[3][3];

  tri[0][0] = a.x;
  tri[0][1] = a.y;
  tri[0][2] = a.z;

  tri[1][0] = b.x;
  tri[1][1] = b.y;
  tri[1][2] = b.z;

  tri[2][0] = c.x;
  tri[2][1] = c.y;
  tri[2][2] = c.z;

  float halfsize[3];
  halfsize[0] = half.x;
  halfsize[1] = half.y;
  halfsize[2] = half.z;

  float _center[3];
  _center[0] = center.x;
  _center[1] = center.y;
  _center[2] = center.z;

  if(triBoxOverlap(_center, halfsize, tri) != 0)
  {
    return true;
  }

  return false;
}
コード例 #3
0
bool Triangle::intersectsBox(AABB box) const {
    Vector3d bcenter = (box.minCorner + box.maxCorner) / 2.0;
    float boxcenter[3];
    boxcenter[0] = bcenter[0];
    boxcenter[1] = bcenter[1];
    boxcenter[2] = bcenter[2];
    Vector3d bhalfsize = (box.maxCorner - box.minCorner) / 2.0;
    bhalfsize += Vector3d::Constant(EPSILON * 1000);
    float boxhalfsize[3];
    boxhalfsize[0] = bhalfsize[0];
    boxhalfsize[1] = bhalfsize[1];
    boxhalfsize[2] = bhalfsize[2];
    float triverts[3][3];

    triverts[0][0] = p1[0];
    triverts[0][1] = p1[1];
    triverts[0][2] = p1[2];

    triverts[1][0] = p2[0];
    triverts[1][1] = p2[1];
    triverts[1][2] = p2[2];

    triverts[2][0] = p3[0];
    triverts[2][1] = p3[1];
    triverts[2][2] = p3[2];

    return triBoxOverlap(boxcenter, boxhalfsize, triverts);
}
コード例 #4
0
    bool containsTriangle(const float *p1,const float *p2,const float *p3) const
    {
        float boxCenter[3];
        float boxHalfSize[3];
        float triVerts[3][3];

        boxCenter[0] = (mMin[0]+mMax[0])*0.5f;
        boxCenter[1] = (mMin[1]+mMax[1])*0.5f;
        boxCenter[2] = (mMin[2]+mMax[2])*0.5f;

        boxHalfSize[0] = (mMax[0]-mMin[0])*0.5f;
        boxHalfSize[1] = (mMax[1]-mMin[1])*0.5f;
        boxHalfSize[2] = (mMax[2]-mMin[2])*0.5f;

        triVerts[0][0] = p1[0];
        triVerts[0][1] = p1[1];
        triVerts[0][2] = p1[2];

        triVerts[1][0] = p2[0];
        triVerts[1][1] = p2[1];
        triVerts[1][2] = p2[2];

        triVerts[2][0] = p3[0];
        triVerts[2][1] = p3[1];
        triVerts[2][2] = p3[2];

        int ret = triBoxOverlap(boxCenter,boxHalfSize,triVerts);

        return ret == 1 ? true : false;
    }
コード例 #5
0
ファイル: intr_tribox.cpp プロジェクト: sutuglon/Motor
bool testIntersectionTriBox(const Vec3f *_pts, const Box &_box)
{
	//float pt[3][3];
/*
	pt[0][0] = _pts[0].x;	pt[0][1] = _pts[0].y;	pt[0][2] = _pts[0].z;
	pt[1][0] = _pts[1].x;	pt[1][1] = _pts[1].y;	pt[1][2] = _pts[1].z;
	pt[2][0] = _pts[2].x;	pt[2][1] = _pts[2].y;	pt[2][2] = _pts[2].z;
*/
	int res = triBoxOverlap(&_box.center.x, &_box.extent.x, _pts);
	if (res == 1)
		return true;

	return false;
}
コード例 #6
0
ファイル: AxisAlignedBox3.cpp プロジェクト: houpcz/Octree
bool AxisAlignedBox3::CollisionTriangle(sglTriangle * triangle)
{
	mmVector3 center = Center();
	mmVector3 diagonal = Diagonal();
	
	//const float eps = 1.00f;
	float boxcenter[3] = {center.x, center.y, center.z};
	float boxhalfsize[3] = {diagonal.x / 2.0f, diagonal.y / 2.0f, diagonal.z / 2.0f};
	float triverts[3][3] = { {triangle->point1.x, triangle->point1.y, triangle->point1.z},
						   {triangle->point2.x, triangle->point2.y, triangle->point2.z},
						   {triangle->point3.x, triangle->point3.y, triangle->point3.z}};

	return triBoxOverlap(boxcenter, boxhalfsize, triverts);
}
コード例 #7
0
ファイル: voxel.cpp プロジェクト: desaic/matchtex
bool trigCubeIntersect(int tidx, const Mesh & m ,
                       GridIdx & cube,
                       real_t * mn, real_t side_len)
{
  float boxcenter[3]={mn[0]+(0.5+cube[0])*side_len,
                      mn[1]+(0.5+cube[1])*side_len,
                      mn[2]+(0.5+cube[2])*side_len};
  float boxhalfsize[3]={side_len/2,side_len/2,side_len/2};
  float triverts[3][3];
  for(int ii=0;ii<3;ii++){
    for(int jj=0;jj<3;jj++){
      triverts[ii][jj]=m.v[m.t[tidx][ii]][jj];
    }
  }
  return triBoxOverlap(boxcenter,boxhalfsize, triverts);
}
コード例 #8
0
EXPORT(sqInt) primitiveTriBoxIntersects(void) {
    float* maxCorner;
    float* v0;
    float* v2;
    float* v1;
    float* minCorner;
    sqInt result;

    if (!((interpreterProxy->methodArgumentCount()) == 5)) {
        return interpreterProxy->primitiveFail();
    }
    v2 = stackVector3(0);
    v1 = stackVector3(1);
    v0 = stackVector3(2);
    maxCorner = stackVector3(3);
    minCorner = stackVector3(4);
    result = triBoxOverlap(minCorner, maxCorner, v0, v1, v2);
    if (result < 0) {
        return interpreterProxy->primitiveFail();
    }
    interpreterProxy->pop(6);
    interpreterProxy->pushBool(result);
}
コード例 #9
0
ファイル: bbtree.c プロジェクト: ClavinSBU/gts
/**
 * gts_bbox_overlaps_segment:
 * @bb: a #GtsBBox.
 * @s: a #GtsSegment.
 *
 * This functions uses gts_bbox_overlaps_triangle() with a degenerate
 * triangle.
 *
 * Returns: %TRUE if @bb overlaps with @s, %FALSE otherwise.
 */
gboolean gts_bbox_overlaps_segment (GtsBBox * bb, GtsSegment * s)
{
  double bc[3], bh[3], tv[3][3];
  GtsPoint * p1, * p2, * p3;

  g_return_val_if_fail (bb != NULL, FALSE);
  g_return_val_if_fail (s != NULL, FALSE);

  bc[0] = (bb->x2 + bb->x1)/2.;
  bh[0] = (bb->x2 - bb->x1)/2.;
  bc[1] = (bb->y2 + bb->y1)/2.;
  bh[1] = (bb->y2 - bb->y1)/2.;
  bc[2] = (bb->z2 + bb->z1)/2.;
  bh[2] = (bb->z2 - bb->z1)/2.;
  p1 = GTS_POINT (s->v1);
  p2 = GTS_POINT (s->v2);
  p3 = p1;
  tv[0][0] = p1->x; tv[0][1] = p1->y; tv[0][2] = p1->z;
  tv[1][0] = p2->x; tv[1][1] = p2->y; tv[1][2] = p2->z;
  tv[2][0] = p3->x; tv[2][1] = p3->y; tv[2][2] = p3->z;

  return triBoxOverlap (bc, bh, tv);
}
コード例 #10
0
ファイル: bbtree.c プロジェクト: ClavinSBU/gts
/**
 * gts_bbox_overlaps_triangle:
 * @bb: a #GtsBBox.
 * @t: a #GtsTriangle.
 *
 * This is a wrapper around the fast overlap test of Tomas
 * Akenine-Moller (http://www.cs.lth.se/home/Tomas_Akenine_Moller/).
 *
 * Returns: %TRUE if @bb overlaps with @t, %FALSE otherwise.
 */
gboolean gts_bbox_overlaps_triangle (GtsBBox * bb, GtsTriangle * t)
{
  double bc[3], bh[3], tv[3][3];
  GtsPoint * p1, * p2, * p3;

  g_return_val_if_fail (bb != NULL, FALSE);
  g_return_val_if_fail (t != NULL, FALSE);

  bc[0] = (bb->x2 + bb->x1)/2.;
  bh[0] = (bb->x2 - bb->x1)/2.;
  bc[1] = (bb->y2 + bb->y1)/2.;
  bh[1] = (bb->y2 - bb->y1)/2.;
  bc[2] = (bb->z2 + bb->z1)/2.;
  bh[2] = (bb->z2 - bb->z1)/2.;
  p1 = GTS_POINT (GTS_SEGMENT (t->e1)->v1);
  p2 = GTS_POINT (GTS_SEGMENT (t->e1)->v2);
  p3 = GTS_POINT (gts_triangle_vertex (t));
  tv[0][0] = p1->x; tv[0][1] = p1->y; tv[0][2] = p1->z;
  tv[1][0] = p2->x; tv[1][1] = p2->y; tv[1][2] = p2->z;
  tv[2][0] = p3->x; tv[2][1] = p3->y; tv[2][2] = p3->z;

  return triBoxOverlap (bc, bh, tv);
}
コード例 #11
0
ファイル: atlasOldMesher.cpp プロジェクト: gitrider/wxsj2
void AtlasOldMesher::writeCollision(Stream *s)
{
   // First, do the binning. This is a bit gross but, hey, what can you do...
   const U32 gridSize = BIT(gAtlasColTreeDepth-1);
   const U32 gridCount = gridSize * gridSize;

   Vector<U16> bins[gridCount];

   // Track the min/max for the bins.
   S16 binsMax[gridCount];
   S16 binsMin[gridCount];

   // Clear bins.
   for(S32 i=0; i<gridCount; i++)
   {
      binsMax[i] = S16_MIN;
      binsMin[i] = S16_MAX;
   }

   // Get the size of bins (we step in x/y, not in Z).
   Point3F binSize( mBounds.len_x() / F32(gridSize), mBounds.len_y() / F32(gridSize), mBounds.len_z());

   for(S32 i=0; i<gridSize; i++)
   {
      for(S32 j=0; j<gridSize; j++)
      {
         // Figure the bounds for this bin...
         Box3F binBox;

         binBox.minExtents.x = binSize.x * i;
         binBox.minExtents.y = binSize.y * j;
         binBox.minExtents.z = mBounds.minExtents.z - 1.f;

         binBox.maxExtents.x = binSize.x * (i+1);
         binBox.maxExtents.y = binSize.y * (j+1);
         binBox.maxExtents.z = mBounds.maxExtents.z + 1.f;

         Vector<U16> &binList = bins[i * gridSize + j];

         S16 &binMin = binsMin[i * gridSize + j];
         S16 &binMax = binsMax[i * gridSize + j];

         // Now, consider all the triangles in the mesh. Note: we assume a trilist.
         for(S32 v=0; v<mIndices.size(); v+=3)
         {
            // Get the verts.
            const Vert &a = mVerts[mIndices[v+0]];
            const Vert &b = mVerts[mIndices[v+1]];
            const Vert &c = mVerts[mIndices[v+2]];

            // If it's a special, skip it, we don't want to collide with skirts.
            if(a.special ||
               b.special ||
               c.special)
               continue; // I can't stand skirts!

            // Reject anything degenerate...
            if(mIndices[v+0] == mIndices[v+1])
               continue;
            if(mIndices[v+1] == mIndices[v+2])
               continue;
            if(mIndices[v+2] == mIndices[v+0])
               continue;

            // Otherwise, we're good, so consider it for the current bin.
            const Point3F aPos = getVertPos(a);
            const Point3F bPos = getVertPos(b);
            const Point3F cPos = getVertPos(c);

            if(triBoxOverlap(binBox, aPos, bPos, cPos))
            {
               // Got a hit, add it to the list!
               binList.push_back(v);

               // Update the min/max info. This will be TOO BIG if we have a
               // very large triangle! An optimal implementation will do a clip,
               // then update the bin. This is probably ok for the moment.
               S16 hA = mHeight->sample(a.pos);
               S16 hB = mHeight->sample(b.pos);
               S16 hC = mHeight->sample(c.pos);

               if(hA > binMax) binMax = hA;
               if(hB > binMax) binMax = hB;
               if(hC > binMax) binMax = hC;

               if(hA < binMin) binMin = hA;
               if(hB < binMin) binMin = hB;
               if(hC < binMin) binMin = hC;
            }
         }

		 // Limit the triangle count to 16bits.  While primary meshes support more
		 // than that, collision meshes don't.  If we don't catch that here, we'll
		 // see raycasting issues later in Atlas.
		 AssertISV( binList.size() <= 65536,
			 "AtlasOldMesher::writeCollision - too many triangles! (>65536)  Try again with a deeper tree" );

         // Ok, we're all set for this bin...
         AssertFatal(binMin <= binMax,
            "AtlasOldMesher::writeCollision - empty bin, crap!");
      }
   }

   // Next, generate the quadtree.
   FrameAllocatorMarker qtPool;
   const U32 nodeCount = QuadTreeTracer::getNodeCount(gAtlasColTreeDepth);
   S16 *qtMin = (S16*)qtPool.alloc(sizeof(S16) * nodeCount);
   S16 *qtMax = (S16*)qtPool.alloc(sizeof(S16) * nodeCount);

   // We have to recursively generate this from the bins on up. First we copy
   // the bins from earlier, then we do our recursomatic thingummy. (It's
   // actually not recursive.)
   for(S32 i=0; i<gridSize; i++)
   {
      for(S32 j=0; j<gridSize; j++)
      {
         const U32 qtIdx = QuadTreeTracer::getNodeIndex(gAtlasColTreeDepth-1, Point2I(i,j));

         qtMin[qtIdx] = binsMin[i * gridSize + j];
         qtMax[qtIdx] = binsMax[i * gridSize + j];

         AssertFatal(qtMin[qtIdx] <= qtMax[qtIdx],
            "AtlasOldMesher::writeCollision - bad child quadtree node min/max! (negative a)");

      }
   }

   // Alright, now we go up the bins, generating from the four children of each,
   // till we hit the root.

   // For each empty level from bottom to top...
   for(S32 depth = gAtlasColTreeDepth - 2; depth >= 0; depth--)
   {
      // For each square...
      for(S32 i=0; i<BIT(depth); i++)
      for(S32 j=0; j<BIT(depth); j++)
      {
         const U32 curIdx = QuadTreeTracer::getNodeIndex(depth, Point2I(i,j));

         // For each of this square's 4 children...
         for(S32 subI=0; subI<2; subI++)
         for(S32 subJ=0; subJ<2; subJ++)
         {
            const U32 subIdx =
               QuadTreeTracer::getNodeIndex(depth+1, Point2I(i*2+subI,j*2+subJ));

            // As is the child.
            AssertFatal(qtMin[subIdx] <= qtMax[subIdx],
               "AtlasOldMesher::writeCollision - bad child quadtree node min/max! (a)");

            // Update the min and max of the parent.
            if(qtMin[subIdx] < qtMin[curIdx]) qtMin[curIdx] = qtMin[subIdx];
            if(qtMax[subIdx] > qtMax[curIdx]) qtMax[curIdx] = qtMax[subIdx];

            // Make sure we actually contain the child.
            AssertFatal(qtMin[subIdx] >= qtMin[curIdx],
               "AtlasOldMesher::writeCollision - bad quadtree child min during coltree generation!");
            AssertFatal(qtMax[subIdx] <= qtMax[curIdx],
               "AtlasOldMesher::writeCollision - bad quadtree child max during coltree generation!");

            // And that the parent is still valid.
            AssertFatal(qtMin[curIdx] <= qtMax[curIdx],
               "AtlasOldMesher::writeCollision - bad parent quadtree node min/max!");

            // As is the child.
            AssertFatal(qtMin[subIdx] <= qtMax[subIdx],
               "AtlasOldMesher::writeCollision - bad child quadtree node min/max! (b)");

         }
      }
   }

   // Wasn't that fun? Now we have a ready-to-go quadtree.

   // Now write the quadtree, in proper order
   for(S32 i=0; i<nodeCount; i++)
   {
      AssertFatal(qtMin[i] <= qtMax[i], "AtlasOldMesher::writeCollision - invalid quadtree min/max.");
      s->write(qtMin[i]);
      s->write(qtMax[i]);
   }

   s->write(U32(0xb33fd34d));

   // We have to generate...
   // ... the list of triangle offsets for each bin. (Done above!)
   // ... the triangle buffer which stores the offsets for each bin.
   ChunkTriangleBufferGenerator ctbg(gridSize);

   for(S32 i=0; i<gridSize; i++)
      for(S32 j=0; j<gridSize; j++)
         ctbg.insertBinList(Point2I(i,j), bins[i * gridSize + j]);

   // Finally, write the data out.
   ctbg.write(s);
}
コード例 #12
0
void UniformGrid::calculateGrid(unsigned int p_numTriangles, std::vector<RTMesh>* p_mesh, std::vector<RTMaterial>* p_material, std::vector<RTLight>* p_light, Vector3 p_numVoxels)
{
	std::vector<RTTriangle*>* aux_grid = new std::vector<RTTriangle*>[(int)(p_numVoxels.x * p_numVoxels.y * p_numVoxels.z)];
  
	unsigned int size = 0;
	for(unsigned int i=0; i<p_mesh->size(); i++){
		std::vector<RTTriangle>* trianglesArray = p_mesh->at(i).getTriangles();
		for(unsigned int j=0; j<trianglesArray->size(); j++){
			RTTriangle* currentTriangle = &(trianglesArray->at(j));

			Vector3 voxelIndex_vertex1 = getVertexGridIndex(currentTriangle->v1);
			Vector3 voxelIndex_vertex2 = getVertexGridIndex(currentTriangle->v2);
			Vector3 voxelIndex_vertex3 = getVertexGridIndex(currentTriangle->v3);

			aux_grid[getVoxelAt(voxelIndex_vertex1)].push_back(currentTriangle);
			size++;
			if((voxelIndex_vertex2 == voxelIndex_vertex1) == false){
				aux_grid[getVoxelAt(voxelIndex_vertex2)].push_back(currentTriangle);
				size++;
			}
			if((voxelIndex_vertex3 == voxelIndex_vertex2) == false && (voxelIndex_vertex3 == voxelIndex_vertex1) == false){
				aux_grid[getVoxelAt(voxelIndex_vertex3)].push_back(currentTriangle);
				size++;
			}

			
			//Test triangle / box intersections
			for(float x=0; x<m_numVoxels.x; x++){
				for(float y=0; y<m_numVoxels.y; y++){
					for(float z=0; z<m_numVoxels.z; z++){
						Vector3 bbMin = m_min + Vector3(x * m_voxelSize.x, y * m_voxelSize.y, z * m_voxelSize.z);
						Vector3 bbMax = bbMin + m_voxelSize;
						

						float bbCenter [] = {bbMin.x + ((bbMax.x - bbMin.x) / 2.0f),
											(bbMin.y + (bbMax.y - bbMin.y) / 2.0f),
											(bbMin.z + (bbMax.z - bbMin.z) / 2.0f)};

						float bbHalfSize [] = {((m_voxelSize).x / 2.0f),
												((m_voxelSize).y / 2.0f),
												((m_voxelSize).z / 2.0f)};

						float triangle [][3] = {{currentTriangle->v1.x, currentTriangle->v1.y, currentTriangle->v1.z},
												 {currentTriangle->v2.x, currentTriangle->v2.y, currentTriangle->v2.z},
												 {currentTriangle->v3.x, currentTriangle->v3.y, currentTriangle->v3.z}};

						bool hit = triBoxOverlap(bbCenter, bbHalfSize, triangle);
						//std::cout << triBoxOverlap(bbCenter, bbHalfSize, triangle) << "\n";

						Vector3 voxel = Vector3(x,y,z);
						if(hit == true && (voxel == voxelIndex_vertex1) == false
							&& (voxel == voxelIndex_vertex2) == false && (voxel == voxelIndex_vertex3) == false){
							aux_grid[getVoxelAt(voxel)].push_back(currentTriangle);
							size++;
						}
					}
				}
			}
		}
	}
 // 
  GLint max_tex_size = 0;
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
  int texture2DnumLines;

  
	m_gridArraySize = (int)(p_numVoxels.x * p_numVoxels.y * p_numVoxels.z) * 4;
  texture2DnumLines = (int)((m_gridArraySize/4)/max_tex_size) + (int)(m_gridArraySize%max_tex_size != 0);
	m_gridArray = new GLfloat[texture2DnumLines*max_tex_size*4];
	for(int i = 0; i < texture2DnumLines*max_tex_size*4; ++i) m_gridArray[i] = -1.0f;
	//memset(m_gridArray, -1.0f, sizeof(GLfloat) * m_gridArraySize);//Do not work for floats different then 0 

	size += p_numVoxels.x * p_numVoxels.y * p_numVoxels.z;
	m_triangleListArraySize = size;
  texture2DnumLines = (int)((m_triangleListArraySize)/max_tex_size) + (int)(m_triangleListArraySize%max_tex_size != 0);
	m_triangleListArray = new GLfloat[texture2DnumLines*max_tex_size];
	for(int i = 0; i < texture2DnumLines*max_tex_size; ++i) m_triangleListArray[i] = -1.0f;

	m_triangleVertexArraySize = p_numTriangles * 3 * 3;
  texture2DnumLines = (int)((m_triangleVertexArraySize/3)/max_tex_size) + (int)(m_triangleVertexArraySize%max_tex_size != 0);
 	m_triangleVertexArray = new GLfloat[texture2DnumLines*max_tex_size*3];
	for(int i = 0; i < texture2DnumLines*max_tex_size*3; ++i) m_triangleVertexArray[i] = 1.0f;
  
	m_triangleNormalsArraySize = p_numTriangles * 3 * 3;
  texture2DnumLines = (int)((m_triangleNormalsArraySize/3)/max_tex_size) + (int)(m_triangleNormalsArraySize%max_tex_size != 0);
	m_triangleNormalsArray = new GLfloat[texture2DnumLines*max_tex_size*3];
	memset(m_triangleNormalsArray, 0, sizeof(GLfloat) * texture2DnumLines*max_tex_size*3);

	m_triangleMaterialArraySize = p_numTriangles * 3 * 4;
  texture2DnumLines = (int)((m_triangleMaterialArraySize/4)/max_tex_size) + (int)(m_triangleMaterialArraySize%max_tex_size != 0);
	m_triangleMaterialArray = new GLfloat[texture2DnumLines*max_tex_size*4];
	memset(m_triangleMaterialArray, 0, sizeof(GLfloat) * texture2DnumLines*max_tex_size*4);

  m_lightsArraySize = p_light->size()*sizeof(struct lightStruct)/(sizeof(GLfloat));
  m_lightsArray = new GLfloat[m_lightsArraySize];
  for( unsigned int i = 0; i < p_light->size(); ++i)
    memcpy(&m_lightsArray[i*sizeof(struct lightStruct)/sizeof(GLfloat)], p_light->at(i).getLightStruct(), sizeof(struct lightStruct));

 
	unsigned int gridCount = 0;
	unsigned int gridCountPlusOne = 0;
	int cont = 0;
	int gridIndexCont = 0;
	for(int x=0; x<p_numVoxels.x; x++){
		for(int y=0; y<p_numVoxels.y; y++){
			for(int z=0; z<p_numVoxels.z; z++){
				unsigned int prevGridCountPlusOne = gridCountPlusOne;
				for(int j=0; j<aux_grid[cont].size(); j++){
					unsigned int triangleIndex = aux_grid[cont].at(j)->getGlobalIndex();

					m_triangleListArray[gridCountPlusOne+j] = triangleIndex;


					m_triangleVertexArray[triangleIndex*3*3] = aux_grid[cont].at(j)->v1.x;
					m_triangleVertexArray[triangleIndex*3*3+1] = aux_grid[cont].at(j)->v1.y;
					m_triangleVertexArray[triangleIndex*3*3+2] = aux_grid[cont].at(j)->v1.z;

					m_triangleVertexArray[triangleIndex*3*3+3] = aux_grid[cont].at(j)->v2.x;
					m_triangleVertexArray[triangleIndex*3*3+3+1] = aux_grid[cont].at(j)->v2.y;
					m_triangleVertexArray[triangleIndex*3*3+3+2] = aux_grid[cont].at(j)->v2.z;

					m_triangleVertexArray[triangleIndex*3*3+3+3] = aux_grid[cont].at(j)->v3.x;
					m_triangleVertexArray[triangleIndex*3*3+3+3+1] = aux_grid[cont].at(j)->v3.y;
					m_triangleVertexArray[triangleIndex*3*3+3+3+2] = aux_grid[cont].at(j)->v3.z;



					m_triangleNormalsArray[triangleIndex*3*3] = aux_grid[cont].at(j)->n1.x;
					m_triangleNormalsArray[triangleIndex*3*3+1] = aux_grid[cont].at(j)->n1.y;
					m_triangleNormalsArray[triangleIndex*3*3+2] = aux_grid[cont].at(j)->n1.z;

          m_triangleNormalsArray[triangleIndex*3*3+3] = aux_grid[cont].at(j)->n2.x;
          m_triangleNormalsArray[triangleIndex*3*3+3+1] = aux_grid[cont].at(j)->n2.y;
          m_triangleNormalsArray[triangleIndex*3*3+3+2] = aux_grid[cont].at(j)->n2.z;

          m_triangleNormalsArray[triangleIndex*3*3+3+3] = aux_grid[cont].at(j)->n3.x;
          m_triangleNormalsArray[triangleIndex*3*3+3+3+1] = aux_grid[cont].at(j)->n3.y;
          m_triangleNormalsArray[triangleIndex*3*3+3+3+2] = aux_grid[cont].at(j)->n3.z;



          m_triangleMaterialArray[triangleIndex*3*4] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).opacity;
          m_triangleMaterialArray[triangleIndex*3*4+1] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).reflective;
          m_triangleMaterialArray[triangleIndex*3*4+2] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).refractive;
          m_triangleMaterialArray[triangleIndex*3*4+3] = 1.0;

          m_triangleMaterialArray[triangleIndex*3*4+4] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).diffuse.r;
					m_triangleMaterialArray[triangleIndex*3*4+4+1] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).diffuse.g;
					m_triangleMaterialArray[triangleIndex*3*4+4+2] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).diffuse.b;
          m_triangleMaterialArray[triangleIndex*3*4+4+3] = 1.0;

          m_triangleMaterialArray[triangleIndex*3*4+4+4] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).specular.r;
          m_triangleMaterialArray[triangleIndex*3*4+4+4+1] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).specular.g;
          m_triangleMaterialArray[triangleIndex*3*4+4+4+2] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).specular.b;
          m_triangleMaterialArray[triangleIndex*3*4+4+4+3] = p_material->at(aux_grid[cont].at(j)->getMaterialIndex()).specularExp;
				}
				m_gridArray[gridIndexCont++] = x;
				m_gridArray[gridIndexCont++] = y;
				m_gridArray[gridIndexCont++] = z;
				m_gridArray[gridIndexCont++] = aux_grid[cont].size() != 0 ? (float)prevGridCountPlusOne : -1.0;
				
				gridCountPlusOne += aux_grid[cont].size()+1;
				gridCount += aux_grid[cont].size();

				cont++;
			}
		}
	}
	delete [] aux_grid;
}
コード例 #13
0
ファイル: Resizer.cpp プロジェクト: zephyrer/mesh-editor
void Resizer::computeFacePassthroughingCell(int _faceIndex,float _tempVertex[3][3],int _indexMin[3],int _indexMax[3],float _cellHalfLength[3])
{
	int num = 0;                        //记录该face穿过的cell的个数
	float cellCenter[3];                //记录当前cell的中心点
	//仔细考虑八种情况
	if(_indexMax[0] == _indexMin[0])         
	{
		if(_indexMax[1] == _indexMin[1])    
		{
			if(_indexMax[2] == _indexMin[2])    //如果X,Y,Z方向都相同(肯定是相交的)
			{
				facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],_indexMin[1],_indexMin[2]);
			//	printf("X,Y,Z方向都相同:%d--%d\n",num,computeCellIndex(_indexMin[0],_indexMin[1],_indexMin[2]));
				num++; 
				facePassthroughCellNum[_faceIndex] = num; 
			//	Sleep(500);
			}
			else             //如果X,Y方向相同,Z方向不同(需要判断是否相交)      
			{
				cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0];
				cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1];
				for(int j=_indexMin[2];j<=_indexMax[2];j++)    //Z轴
				{
					cellCenter[2] = minBoundingBox[2]+j*edgeLength[2]+_cellHalfLength[2];
					if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
					{
						facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],_indexMin[1],j);
					//	printf("X,Y方向相同,Z方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],_indexMin[1],j));
						num++;
					//	Sleep(500);
					}
					/*else
					{
						printf("X,Y方向相同,Z方向不同:face和cell不相交.\n");
						Sleep(500);
					}*/
				}
				facePassthroughCellNum[_faceIndex] = num;
			}
		}
		else                 //Y方向不相同
		{
			if(_indexMin[2] == _indexMax[2])    //X,Z方向相同,Y方向不同
			{
				cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0];
				cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2];
				for(int j=_indexMin[1];j<=_indexMax[1];j++)    //Y轴
				{
					cellCenter[1] = minBoundingBox[1]+j*edgeLength[1]+_cellHalfLength[1];
					if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
					{
						facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],j,_indexMin[2]);
					//	printf("X,Z方向相同,Y方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],j,_indexMin[2]));
						num++;
					//	Sleep(500);
					}
					/*else
					{
						printf("X,Z方向相同,Y方向不同:face和cell不相交.\n");
						Sleep(500);
					}*/
					facePassthroughCellNum[_faceIndex] = num;
				}
			}
			else           //X方向相同,Y,Z方向不同
			{
				cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0];
				for(int j=_indexMin[1];j<=_indexMax[1];j++)           //Y方向
				{
					for(int k=_indexMin[2];k<=_indexMax[2];k++)       //Z方向
					{
						cellCenter[1] = minBoundingBox[1]+j*edgeLength[1]+_cellHalfLength[1];
						cellCenter[2] = minBoundingBox[2]+k*edgeLength[2]+_cellHalfLength[2];
						if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
						{
							facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],j,k);
						//	printf("X方向相同,Y,Z方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],j,k));
							num++;
						//	Sleep(500);
						}
						/*else
						{
							printf("X方向相同,Y,Z方向不同:face和cell不相交.\n");
							Sleep(500);
						}*/
						facePassthroughCellNum[_faceIndex] = num;
					}
				}
			}
		}
	}
	else           //X方向不同
	{
		if(_indexMin[1] == _indexMax[1])     //Y方向相同
		{
			if(_indexMin[2] == _indexMax[2])    //Y,Z方向相同,X方向不同
			{
				cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1];
				cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2];
				for(int j=_indexMin[0];j<=_indexMax[0];j++)    //X方向
				{
					cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0];
					if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
					{
						facePassthroughCell[_faceIndex][num] = computeCellIndex(j,_indexMin[1],_indexMin[2]);
					//	printf("Y,Z方向相同,X方向不同:%d--%d\n",num,computeCellIndex(j,_indexMin[1],_indexMin[2]));
						num++;
					//	Sleep(500);
					}
					/*else
					{
						printf("Y,Z方向相同,X方向不同:face和cell不相交.\n");
						Sleep(500);
					}*/
				}
				facePassthroughCellNum[_faceIndex] = num;
			}
			else     //Y方向相同,X,Z方向不同
			{
				cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1];
				for(int j=_indexMin[0];j<=_indexMax[0];j++)           //X方向
				{
					for(int k=_indexMin[2];k<=_indexMax[2];k++)       //Z方向
					{
						cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0];
						cellCenter[2] = minBoundingBox[2]+k*edgeLength[2]+_cellHalfLength[2];
						if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
						{
							facePassthroughCell[_faceIndex][num] = computeCellIndex(j,_indexMin[1],k);
						//	printf("Y方向相同,X,Z方向不同:%d--%d\n",num,computeCellIndex(j,_indexMin[1],k));
							num++;
						//	Sleep(500);
						}
						/*else
						{
							printf("Y方向相同,X,Z方向不同:face和cell不相交.\n");
							Sleep(500);
						}*/
						facePassthroughCellNum[_faceIndex] = num;
					}
				}
			}
		}
		else      //Y方向不同
		{
			if(_indexMin[2] == _indexMax[2])        //Z方向相同,X,Y方向不同
			{
				cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2];
				for(int j=_indexMin[0];j<=_indexMax[0];j++)           //X方向
				{
					for(int k=_indexMin[1];k<=_indexMax[1];k++)       //Y方向
					{
						cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0];
						cellCenter[1] = minBoundingBox[1]+k*edgeLength[1]+_cellHalfLength[1];
						if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
						{
							facePassthroughCell[_faceIndex][num] = computeCellIndex(j,k,_indexMin[2]);
						//	printf("Z方向相同,X,Y方向不同:%d--%d\n",num,computeCellIndex(j,k,_indexMin[2]));
							num++;
						//	Sleep(500);
						}
						/*else
						{
							printf("Z方向相同,X,Y方向不同:face和cell不相交.\n");
							Sleep(500);
						}*/
						facePassthroughCellNum[_faceIndex] = num;
					}
				}
			} 
			else        //X,Y,Z方向都不同
			{
				for(int j=_indexMin[0];j<=_indexMax[0];j++)   //X轴
				{
					for(int k=_indexMin[1];k<=_indexMax[1];k++)   //Y轴
					{
						for(int p=_indexMin[2];p<=_indexMax[2];p++)   //Z轴
						{
							cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0];
							cellCenter[1] = minBoundingBox[1]+k*edgeLength[1]+_cellHalfLength[1];
							cellCenter[2] = minBoundingBox[2]+p*edgeLength[2]+_cellHalfLength[2];
							if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1)      //如果face和cell相交
							{
								facePassthroughCell[_faceIndex][num] = computeCellIndex(j,k,p);
							/*	printf("X,Y,Z方向不同:%d--%d\n",num,computeCellIndex(j,k,p));
								printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",_tempVertex[0][0],_tempVertex[0][1],_tempVertex[0][2],
																			_tempVertex[1][0],_tempVertex[1][1],_tempVertex[1][2],
																			_tempVertex[2][0],_tempVertex[2][1],_tempVertex[2][2]);*/
								num++;
							//	Sleep(1500);
							}
							/*else
							{
								printf("X,Y,Z方向不同:face和cell不相交.\n");
								printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",_tempVertex[0][0],_tempVertex[0][1],_tempVertex[0][2],
								                                            _tempVertex[1][0],_tempVertex[1][1],_tempVertex[1][2],
																			_tempVertex[2][0],_tempVertex[2][1],_tempVertex[2][2]);
								Sleep(1500);
							}*/
							facePassthroughCellNum[_faceIndex] = num;
						}
					}
				}
			}
		}
	}
}
コード例 #14
0
/*! Builds the uniform grid for ray tracing acceleration
*/
void SLUniformGrid::build(SLVec3f minV, SLVec3f maxV)
{  
    _minV = minV;
    _maxV = maxV;
   
    deleteAll();
   
    // Calculate uniform grid 
    // Calc. voxel resolution, extent and allocate voxel array
    SLVec3f size = _maxV - _minV;
   
    // Woo's method
    SLfloat voxDensity = 20.0f;
    SLuint  numT = _m->numI / 3; // NO. of triangles
    SLfloat nr = (SLfloat)pow(voxDensity*numT,1.0f/3.0f);
    SLfloat maxS = SL_max(size.x, size.y, size.z);
    _voxResX = max(1, (SLint)(nr*size.x/maxS));
    _voxResY = max(1, (SLint)(nr*size.y/maxS));
    _voxResZ = max(1, (SLint)(nr*size.z/maxS));
   
    _voxResXY= _voxResX * _voxResY;
    _voxCnt  = _voxResZ * _voxResXY;
    _voxExtX = size.x / _voxResX;
    _voxExtY = size.y / _voxResY;
    _voxExtZ = size.z / _voxResZ;
   
    // Allocate array of pointer to SLV32ushort
    _vox = new SLV32ushort*[_voxCnt];
    for (SLuint i=0; i<_voxCnt; ++i) _vox[i] = 0;

    SLint    x, y, z;
    SLuint   i, curVoxel = 0;
    SLfloat  boxHalfExt[3] = {_voxExtX*0.5f, _voxExtY*0.5f, _voxExtZ*0.5f};
    SLfloat  curVoxelCenter[3];
    SLfloat  vert[3][3];
    SLuint   voxCntNotEmpty = 0;
    
    // Loop through all triangles and assign them to the voxels
    for(SLuint t = 0; t < numT; ++t)
    {  
        // Copy triangle vertices into SLfloat array[3][3]
        SLuint i = t * 3;
        if (_m->I16)
        {   vert[0][0] = _m->finalP()[_m->I16[i  ]].x;
            vert[0][1] = _m->finalP()[_m->I16[i  ]].y;
            vert[0][2] = _m->finalP()[_m->I16[i  ]].z;
            vert[1][0] = _m->finalP()[_m->I16[i+1]].x;
            vert[1][1] = _m->finalP()[_m->I16[i+1]].y;
            vert[1][2] = _m->finalP()[_m->I16[i+1]].z;
            vert[2][0] = _m->finalP()[_m->I16[i+2]].x;
            vert[2][1] = _m->finalP()[_m->I16[i+2]].y;
            vert[2][2] = _m->finalP()[_m->I16[i+2]].z;
        } else
        {   vert[0][0] = _m->finalP()[_m->I32[i  ]].x;
            vert[0][1] = _m->finalP()[_m->I32[i  ]].y;
            vert[0][2] = _m->finalP()[_m->I32[i  ]].z;
            vert[1][0] = _m->finalP()[_m->I32[i+1]].x;
            vert[1][1] = _m->finalP()[_m->I32[i+1]].y;
            vert[1][2] = _m->finalP()[_m->I32[i+1]].z;
            vert[2][0] = _m->finalP()[_m->I32[i+2]].x;
            vert[2][1] = _m->finalP()[_m->I32[i+2]].y;
            vert[2][2] = _m->finalP()[_m->I32[i+2]].z;
        }
        // Min. and max. point of triangle
        SLVec3f minT = SLVec3f(SL_min(vert[0][0], vert[1][0], vert[2][0]),
                               SL_min(vert[0][1], vert[1][1], vert[2][1]),
                               SL_min(vert[0][2], vert[1][2], vert[2][2]));
        SLVec3f maxT = SLVec3f(SL_max(vert[0][0], vert[1][0], vert[2][0]),
                               SL_max(vert[0][1], vert[1][1], vert[2][1]),
                               SL_max(vert[0][2], vert[1][2], vert[2][2]));
      
        // min voxel index of triangle
        SLint minx = (SLint)((minT.x-_minV.x) / _voxExtX);
        SLint miny = (SLint)((minT.y-_minV.y) / _voxExtY);
        SLint minz = (SLint)((minT.z-_minV.z) / _voxExtZ);
        // max voxel index of triangle
        SLint maxx = (SLint)((maxT.x-_minV.x) / _voxExtX);
        SLint maxy = (SLint)((maxT.y-_minV.y) / _voxExtY);
        SLint maxz = (SLint)((maxT.z-_minV.z) / _voxExtZ);
        if (maxx >= _voxResX) maxx=_voxResX-1;
        if (maxy >= _voxResY) maxy=_voxResY-1;
        if (maxz >= _voxResZ) maxz=_voxResZ-1;
                                                   
        // Loop through voxels
        curVoxelCenter[2]  = _minV.z + minz*_voxExtZ + boxHalfExt[2];
        for (z=minz; z<=maxz; ++z, curVoxelCenter[2] += _voxExtZ) 
        {  
            curVoxelCenter[1]  = _minV.y + miny*_voxExtY + boxHalfExt[1];
            for (y=miny; y<=maxy; ++y, curVoxelCenter[1] += _voxExtY) 
            {  
                curVoxelCenter[0]  = _minV.x + minx*_voxExtX + boxHalfExt[0];
                for (x=minx; x<=maxx; ++x, curVoxelCenter[0] += _voxExtX) 
                {  
                    curVoxel = x + y*_voxResX + z*_voxResXY;
               
                    //triangle-AABB overlap test by Thomas Möller
                    if (triBoxOverlap(curVoxelCenter, boxHalfExt, vert))
                    //trianlgesAABB-AABB overlap test is faster but not as precise
                    //if (triBoxBoxOverlap(curVoxelCenter, boxHalfExt, vert)) 
                    {  
                        {  if (_vox[curVoxel] == 0) 
                            {   voxCntNotEmpty++;
                                _vox[curVoxel] = new SLV32ushort;
                            }
                            _vox[curVoxel]->push_back(t);

                            if (_vox[curVoxel]->size() > _voxMaxTria)
                                _voxMaxTria = _vox[curVoxel]->size();
                        }
                    }
                }
            }
        }
    }
   
    _voxCntEmpty = _voxCnt - voxCntNotEmpty;
   
    // Reduce dynamic arrays to real size
    for (i=0; i<_voxCnt; ++i) 
    {   if (_vox[i])
            _vox[i]->reserve(_vox[i]->size());
    }

    /*
    // dump for debugging
    SL_LOG("\nMesh name: %s\n", _m->name().c_str());
    SL_LOG("Number of voxels: %d\n", _voxCnt);
    SL_LOG("Empty voxels: %4.0f%%\n", 
            (SLfloat)(_voxCnt-voxCntNotEmpty)/(SLfloat)_voxCnt * 100.0f);
    SL_LOG("Avg. tria. per voxel: %4.1f\n", (SLfloat)_m->numF/(SLfloat)voxCntNotEmpty);
             
    // dump voxels
    curVoxel = 0;
    curVoxelCenter[2]  = _minV.z + boxHalfExt[2];
    for (z=0; z<_voxResZ; ++z, curVoxelCenter[2] += _voxExtZ) 
    {  
        curVoxelCenter[1]  = _minV.y + boxHalfExt[1];
        for (y=0; y<_voxResY; ++y, curVoxelCenter[1] += _voxExtY) 
        {  
            curVoxelCenter[0]  = _minV.x + boxHalfExt[0];
            for (x=0; x<_voxResX; ++x, curVoxelCenter[0] += _voxExtX) 
            {              
            SL_LOG("\t%0d(%3.1f,%3.1f,%3.1f):%0d " ,curVoxel, 
                    curVoxelCenter[0], curVoxelCenter[1], curVoxelCenter[2],
                    _vox[curVoxel].size());
            curVoxel++;
            }
            SL_LOG("\n");
        }
        SL_LOG("\n");
    }
    */
}
コード例 #15
0
ファイル: Octree.cpp プロジェクト: zaeraal/SDF_Library
	void Octree::Build(Face** tria, unsigned int length)
	{
		if(length == 0)
			return;

		// Front half			Back half (viewed from front)
		// -----------------	-----------------
		// |       |       |	|       |       |
		// |   2   |   6   |	|   3   |   7   |
		// |       |       |	|       |       |
		// -----------------	-----------------
		// |       |       |	|       |       |
		// |   0   |   4   |	|   1   |   5   |
		// |       |       |	|       |       |
		// -----------------	-----------------
		// x smeruje doprava, y smeruje hore, z ODOMNA!! - bacha opengl ma Z inak
		// tabulka offsetov
		float Table[8][3] =
        {
            {-1.0, -1.0, -1.0},
            {-1.0, -1.0, +1.0},
            {-1.0, +1.0, -1.0},
            {-1.0, +1.0, +1.0},
            {+1.0, -1.0, -1.0},
            {+1.0, -1.0, +1.0},
            {+1.0, +1.0, -1.0},
            {+1.0, +1.0, +1.0}
        };
		if((depth >= max_depth) || (length <= min_count))
		{
			count = length;
			triangles = tria;
			isLeaf = true;
		}
		else
		{
			isLeaf = false;
			count = 0;
			int new_depth = depth + 1;
			float new_size = size / 2.0f;

			LinkedList<Face>** son_tria = new LinkedList<Face>* [8];
			for(unsigned int i = 0; i < 8; i++)
				son_tria[i] = NULL; // preistotu

			// zisti kam patria trojuholniky
			for(unsigned int i = 0; i < length; i++)
			{
				byte code1 = GetCode(tria[i]->v[0]->P);
				byte code2 = GetCode(tria[i]->v[1]->P);
				byte code3 = GetCode(tria[i]->v[2]->P);
				byte code = FLAG8;

				if((code1 == code2) && (code1 == code3))
				{
					code = code1;
					if(son_tria[code] == NULL)
						son_tria[code] = new LinkedList<Face>(tria[i]);
					else
						son_tria[code]->InsertToEnd(tria[i]);
				}
				else
				{
					// moc neurychli
					/*bool crosses [8] = {0,0,0,0,0,0,0,0};
					bool crosses1 [8] = {0,0,0,0,0,0,0,0};
					bool crosses2 [8] = {0,0,0,0,0,0,0,0};
					bool crosses3 [8] = {0,0,0,0,0,0,0,0};

					if(!(code1 & FLAG1) || !(code2 & FLAG1) || !(code3 & FLAG1))
						{ crosses1[0] = true; crosses1[2] = true; crosses1[4] = true; crosses1[6] = true; }
					if((code1 & FLAG1) || (code2 & FLAG1) || (code3 & FLAG1))
						{ crosses1[1] = true; crosses1[3] = true; crosses1[5] = true; crosses1[7] = true; }
					if(!(code1 & FLAG2) || !(code2 & FLAG2) || !(code3 & FLAG2))
						{ crosses2[0] = true; crosses2[4] = true; crosses2[1] = true; crosses2[5] = true; }
					if((code1 & FLAG2) || (code2 & FLAG2) || (code3 & FLAG2))
						{ crosses2[2] = true; crosses2[6] = true; crosses2[3] = true; crosses2[7] = true; }
					if(!(code1 & FLAG4) || !(code2 & FLAG4) || !(code3 & FLAG4))
						{ crosses3[0] = true; crosses3[1] = true; crosses3[2] = true; crosses3[3] = true; }
					if((code1 & FLAG4) || (code2 & FLAG4) || (code3 & FLAG4))
						{ crosses3[4] = true; crosses3[5] = true; crosses3[6] = true; crosses3[7] = true; }
					for(byte j = 0; j < 8; j++)
					{
						if((crosses1[j] == true) && (crosses2[j] == true) && (crosses3[j] == true) )
							crosses[j] = true;
					}*/
					for(byte j = 0; j < 8; j++)
					{
						/*if(crosses[j] == false)
							continue;*/
						Vector4 tmpv = Vector4(origin.X + new_size*Table[j][0],
											   origin.Y + new_size*Table[j][1],
											   origin.Z + new_size*Table[j][2]);
						if(triBoxOverlap(tmpv, new_size, tria[i]->v[0]->P, tria[i]->v[1]->P, tria[i]->v[2]->P))
						{
							code = j;
							if(son_tria[code] == NULL)
								son_tria[code] = new LinkedList<Face>(tria[i]);
							else
								son_tria[code]->InsertToEnd(tria[i]);
						}
					}
				}
			}
			/*
			// old tabulka offsetov
			float Table[8][3] =
            {
                {-1.0, -1.0, -1.0},
                {+1.0, -1.0, -1.0},
                {-1.0, +1.0, -1.0},
                {+1.0, +1.0, -1.0},
                {-1.0, -1.0, +1.0},
                {+1.0, -1.0, +1.0},
                {-1.0, +1.0, +1.0},
                {+1.0, +1.0, +1.0}
            };*/

			// vytvor octree a uloz ich tam
			for(int i = 0; i < 8; i++)
			{
				Vector4 tmpv = Vector4(origin.X + new_size*Table[i][0],
									   origin.Y + new_size*Table[i][1],
									   origin.Z + new_size*Table[i][2]);
				son[i] = new Octree(new_depth, new_size, tmpv, this);

				unsigned int velkost = (son_tria[i] == NULL ? 0 : son_tria[i]->GetSize());
				Face** tmp_zoznam = NULL;
				if(velkost > 0)
				{
					tmp_zoznam = new Face* [velkost];

					LinkedList<Face>::Cell<Face>* tmp = son_tria[i]->start;
					for(unsigned int j = 0; j < velkost; j++)
					{
						tmp_zoznam[j] = tmp->data;
						tmp = tmp->next;
					}
				}
				son[i]->Build(tmp_zoznam, velkost);
			}

			// zmazanie pola, kedze vytvaram vlastne
			delete [] tria;

			// zmazanie pomocnych poli kedze som urobil vlastne
			for(unsigned int i = 0; i < 8; i++)
			{
				delete son_tria[i];
				son_tria[i] = NULL;		// preistotu
			}
			delete [] son_tria;
		}
	}
コード例 #16
0
ファイル: octree.c プロジェクト: mrDIMAS/OldTech
void Octree_BuildRecursiveInternal( TOctreeNode * node, TTriangle * triangles, int triangleCount, int * indices, int indexCount, int maxTrianglesPerNode ) {
    if( indexCount < maxTrianglesPerNode ) {
        int sizeBytes = sizeof( int ) * indexCount;
        node->indexCount = indexCount;
        node->indices = Memory_AllocateClean( sizeBytes );
        memcpy( node->indices, indices, sizeBytes );
        return;
    }

    Octree_SplitNode( node );

    for( int childNum = 0; childNum < 8; childNum++ ) {
        TOctreeNode * child = node->childs[childNum];

        TVec3 middle = Vec3_Middle( child->min, child->max );
        TVec3 halfSize = Vec3_Scale( Vec3_Sub( child->max, child->min ), 0.5f );

        float center[3] = {middle.x, middle.y, middle.z};
        float half[3] = {halfSize.x, halfSize.y, halfSize.z};

        // count triangles in each leaf 
        int leafTriangleCount = 0;

        for( int i = 0; i < triangleCount; i++ ) {
            TTriangle * triangle = triangles + i;
            float triverts[3][3] = { 	{triangle->a.x,triangle->a.y, triangle->a.z},
                {triangle->b.x,triangle->b.y, triangle->b.z},
                {triangle->c.x,triangle->c.y, triangle->c.z}
            };
            if( triBoxOverlap( center, half, triverts ) ||
                    Octree_IsPointInsideNode( child, &triangle->a ) ||
                    Octree_IsPointInsideNode( child, &triangle->b ) ||
                    Octree_IsPointInsideNode( child, &triangle->c ) ) {
                leafTriangleCount++;
            }
        }

        // allocate memory for temporary leaf and fill it with data 
        int * leafIndices = Memory_NewCount( leafTriangleCount, int );
        int triangleNum = 0;
        for( int i = 0; i < triangleCount; i++ ) {
            TTriangle * triangle = triangles + i;

            float triverts[3][3] = { 	{triangle->a.x,triangle->a.y, triangle->a.z},
                {triangle->b.x,triangle->b.y, triangle->b.z},
                {triangle->c.x,triangle->c.y, triangle->c.z}
            };
            if( triBoxOverlap( center, half, triverts )||
                    Octree_IsPointInsideNode( child, &triangle->a ) ||
                    Octree_IsPointInsideNode( child, &triangle->b ) ||
                    Octree_IsPointInsideNode( child, &triangle->c ) ) {
                *(leafIndices + triangleNum) = i;
                triangleNum++;
            }
        }

        // recursively process childs of this node 
        Octree_BuildRecursiveInternal( child, triangles, triangleCount, leafIndices, triangleNum, maxTrianglesPerNode );

        // leafFaces data already copied to another node, so we can free temporary array 
        Memory_Free( leafIndices );
    }
}