Example #1
0
void CCullingSystem::initializeOccluders()
{
	static core::array<SOccluderEntry> occluders_tmp;
	occluders_tmp.set_used(0);

	m_Occluders.sort();

	for (u32 i=0; i<m_Occluders.size(); i++)
	{
		bool occluded = false;

		for (u32 j=i+1; j<m_Occluders.size(); j++)
		{
			if (m_Occluders[j].isOccludeByPlanes(m_Occluders[i].tbbox))
			{
				occluded = true;
				break;
			}
		}

		if (!occluded)
		{
			occluders_tmp.push_back(m_Occluders[i]);	
		}
	}

	m_Occluders.set_used(0);
	m_Occluders = occluders_tmp;
}
Example #2
0
void CCal3DSceneNode::render()
{
    //----------------------------------------------------------//
    if ( calModel == 0 )
        return;                              // Make sure there is a model to render
        
    //----------------------------------------------------------//
    video::IVideoDriver* driver = SceneManager->getVideoDriver(); // Get the video driver
    CalRenderer* renderer = calModel->getRenderer();            // Get the CalRenderer

    
    
    //----------------------------------------------------------//
    // All we're doing here is form a bridge between the CalRenderer and the IVideoDriver
    // The CalRenderer gives us data (doesn't draw anything) and IVideoDriver needs that data
    // Only problem is that we need to convert it to Irrlicht Compatible data
    // To explain what's going on, this simple diagram should help:
    //  CalRenderer >--GET--> Data >--CONVERT--> Irrlicht Format >--SEND--> IVideoDriver >--DRAW--> ..
    
    //----------------------------------------------------------//
    calModel->getSkeleton()->calculateBoundingBoxes();        // Calculate the bounding box of the skeleton
    
    //----------------------------------------------------------//
    if ( renderer == 0  )
        return;                               // Bail out if no renderer was received
    if ( !renderer->beginRendering() )
        return;                  // Bail out if renderer encountered an error
        
    //----------------------------------------------------------// Move to our position (and rotate/scale)
    driver->setTransform( video::ETS_WORLD, AbsoluteTransformation );
    
    
    //----------------------------------------------------------//
    s32 numMeshes = renderer->getMeshCount();                   // Get the number of meshes we need to draw
    for ( s32 meshId = 0; meshId < numMeshes; meshId++ )        // Loop for every mesh
    {
        //--------------------------------------------------------//
        s32 numSubMeshes = renderer->getSubmeshCount(meshId);     // Get the number of submeshes
        for ( s32 subId = 0; subId < numSubMeshes; subId++ )      // Loop for every submesh
        {
            if ( !renderer->selectMeshSubmesh(meshId, subId) )      // Select the current mesh and submesh
            {
                continue;                                             // Skip this submesh if it failed
            }
            
            //------------------------------------------------------//
            if ( !OverrideMaterial )                              // Should we use Cal3D's material?
            {
                u8 meshColor [4];                                     // Color stored in RGBA format
                // Irrlicht wants it in ARGB format
                renderer->getAmbientColor( meshColor );               // Get the ambient color
                Material.AmbientColor.setRed( meshColor[0] );       // Set the red component
                Material.AmbientColor.setGreen( meshColor[1] );     // Set the green component
                Material.AmbientColor.setBlue( meshColor[2] );      // Set the blue component
                Material.AmbientColor.setAlpha( meshColor[3] );     // Set the alpha component
                
                renderer->getDiffuseColor( meshColor );               // Get the diffuse color
                Material.DiffuseColor.setRed( meshColor[0] );       // Set the red component
                Material.DiffuseColor.setGreen( meshColor[1] );     // Set the green component
                Material.DiffuseColor.setBlue( meshColor[2] );      // Set the blue component
                Material.DiffuseColor.setAlpha( meshColor[3] );     // Set the alpha component
                
                renderer->getSpecularColor( meshColor );              // Get the specular color
                Material.SpecularColor.setRed( meshColor[0] );      // Set the red component
                Material.SpecularColor.setGreen( meshColor[1] );    // Set the green component
                Material.SpecularColor.setBlue( meshColor[2] );     // Set the blue component
                Material.SpecularColor.setAlpha( meshColor[3] );    // Set the alpha component
                
                Material.Shininess = renderer->getShininess();      // Set the shininess factor
                
                if ( renderer->getMapCount() >= 1 )
                {                                                     // Get the irrlicht texture from user data
                    Material.setTexture(0, (video::ITexture*)renderer->getMapUserData(0));
                }
            }
            
            //------------------------------------------------------//
            s32 vertexCount = renderer->getVertexCount();           // Get the number of vertices
            if (vertexCount == 0)
                continue;                         // Skip if the mesh is empty
                
            static core::array<core::vector3df> vertexBuffer;    // Use a core::array to support msvc
            vertexBuffer.set_used( vertexCount );          // Make room for the vertex coordinates
            renderer->getVertices( &vertexBuffer[0].X );              // Copy the vertices into the buffer
            
            //------------------------------------------------------//
            static core::array<core::vector3df> normalBuffer;
            normalBuffer.set_used( vertexCount );       // Buffer for the vertex normals
            renderer->getNormals( &normalBuffer[0].X );               // Copy the normals to the buffer
            
            //------------------------------------------------------//
            static core::array<core::vector2df> texCoordBuffer;
            texCoordBuffer.set_used( vertexCount );                 // Buffer for the vertex texture coordinates
            renderer->getTextureCoordinates( 0, &texCoordBuffer[0].X );// Copy the texture coordinates to the buffer
            
            //------------------------------------------------------//
            s32 faceCount = renderer->getFaceCount();               // Get the number of faces
            static CalIndex cal_indices[30000000];
            renderer->getFaces(  cal_indices );                   // Copy the face indices to the buffer
            static core::array<u16> faceBuffer;
            faceBuffer.set_used( faceCount * 3 );                   // Buffer for the face v1,v2,v3 indices
            for(int i = 0; i < faceCount * 3; ++i)
            {
              faceBuffer[i] = cal_indices[i];
            }
            
            //------------------------------------------------------//
            static core::array<video::S3DVertex> irrVertexBuffer;
            irrVertexBuffer.set_used( vertexCount );                // Buffer for the irrlicht vertices
            for (s32 vert=0; vert<vertexCount; vert++)              // Convert all vertices to irrlicht format
            { // Irrlicht and Cal3D uses different coordinates. Irrlicht's Y points up, where Cal3D's Z points up
                irrVertexBuffer[vert].Pos.X = vertexBuffer[vert].X;  // Set the X coordinate
                irrVertexBuffer[vert].Pos.Y = vertexBuffer[vert].Y;  // Set the Y coordinate (Cal3D's Z coord)
                irrVertexBuffer[vert].Pos.Z = vertexBuffer[vert].Z;  // Set the Z coordinate (Cal3D's Y coord)
                
                irrVertexBuffer[vert].Color.set(255,128,128,128);     // Vertex colors aren't supported by Cal3D
                
                irrVertexBuffer[vert].Normal.X = normalBuffer[vert].X;// Set the X coordinate
                irrVertexBuffer[vert].Normal.Y = normalBuffer[vert].Y;// Set the Y coordinate (Cal3D's Z coord)
                irrVertexBuffer[vert].Normal.Z = normalBuffer[vert].Z;// Set the Z coordinate (Cal3D's Y coord)
                
                irrVertexBuffer[vert].TCoords.X = texCoordBuffer[vert].X;// Set the X texture coordinate (U)
                irrVertexBuffer[vert].TCoords.Y = texCoordBuffer[vert].Y;// Set the Y texture coordinate (V)
            }
            
            //------------------------------------------------------// Invert triangle direction
            for (s32 face=0; face<faceCount; face++)                // Irrlicht wants indices in the opposite order
            {
                u16 faceA = faceBuffer[face*3];                      // Swap first and last vertex index
                faceBuffer[face*3]   = faceBuffer[face*3+2];         // Set the first to the last
                faceBuffer[face*3+2] = faceA;                        // And the last to the first
            }
            
            //------------------------------------------------------// Finally! Time to draw everthing

           Material.BackfaceCulling = false;

           float k;

           if(draw_mode != DM_DEFAULT)
           {
               video::SMaterial debug_material;
               debug_material.Wireframe = true;
               debug_material.BackfaceCulling = false;
               debug_material.Lighting = false;
               driver->setMaterial(debug_material);
              
               /* so that debug looks good for all sizes of models*/
               k = EXTENT_K * BoundingBox.getExtent().getLength();
           }
           else
           {
               driver->setMaterial( Material );
           }

           if(draw_mode == DM_DEFAULT)
           {
               driver->drawIndexedTriangleList(irrVertexBuffer.const_pointer(),
                                               vertexCount,
                                               faceBuffer.const_pointer(),
                                               faceCount);
           }
           else if(draw_mode == DM_WIREFRAME || 
                   draw_mode == DM_WIREFRAME_AND_SKELETON)
           {
               /* draw faces */
               for (s32 face=0; face<faceCount; ++face)
               {
                 u16 i1, i2, i3;
                 i1 = faceBuffer[face*3+0];
                 i2 = faceBuffer[face*3+1];
                 i3 = faceBuffer[face*3+2];

                 driver->draw3DLine(core::vector3df(vertexBuffer[i1].X,
                                                    vertexBuffer[i1].Y,
                                                    vertexBuffer[i1].Z),
                                    core::vector3df(vertexBuffer[i2].X,
                                                    vertexBuffer[i2].Y,
                                                    vertexBuffer[i2].Z),
                                    video::SColor(255,0,0,255));
                 driver->draw3DLine(core::vector3df(vertexBuffer[i2].X,
                                                    vertexBuffer[i2].Y,
                                                    vertexBuffer[i2].Z),
                                    core::vector3df(vertexBuffer[i3].X,
                                                    vertexBuffer[i3].Y,
                                                    vertexBuffer[i3].Z),
                                    video::SColor(255,0,0,255));
                 driver->draw3DLine(core::vector3df(vertexBuffer[i3].X,
                                                    vertexBuffer[i3].Y,
                                                    vertexBuffer[i3].Z),
                                    core::vector3df(vertexBuffer[i1].X,
                                                    vertexBuffer[i1].Y,
                                                    vertexBuffer[i1].Z),
                                    video::SColor(255,0,0,255));
               }

           }

           if(draw_mode == DM_SKELETON || 
              draw_mode == DM_WIREFRAME_AND_SKELETON)
           {
              float lines[1024][2][3];
              int num_lines;
              num_lines =  calModel->getSkeleton()->getBoneLines(&lines[0][0][0]);
              video::S3DVertex vertex;

              for(int line = 0; line < num_lines; ++line)
              {
                  driver->draw3DLine(core::vector3df(lines[line][0][0], 
                                                     lines[line][0][1],
                                                     lines[line][0][2]),
                                     core::vector3df(lines[line][1][0], 
                                                     lines[line][1][1],
                                                     lines[line][1][2]),
                                     video::SColor(255,255,0,0));
                 
                  core::aabbox3df box1(lines[line][0][0]-SKELETON_K*k,
                                       lines[line][0][1]-SKELETON_K*k, 
                                       lines[line][0][2]-SKELETON_K*k,

                                       lines[line][0][0]+SKELETON_K*k, 
                                       lines[line][0][1]+SKELETON_K*k, 
                                       lines[line][0][2]+SKELETON_K*k);

                  core::aabbox3df box2(lines[line][1][0]-SKELETON_K*k,
                                       lines[line][1][1]-SKELETON_K*k, 
                                       lines[line][1][2]-SKELETON_K*k,

                                       lines[line][1][0]+SKELETON_K*k, 
                                       lines[line][1][1]+SKELETON_K*k, 
                                       lines[line][1][2]+SKELETON_K*k);
                 
                  driver->draw3DBox(box1, video::SColor(255,0,255,0));
                  driver->draw3DBox(box2, video::SColor(255,0,255,0));
              }
           }

           if(draw_bbox)
           {
             video::SMaterial debug_material;
             debug_material.Wireframe = true;
             debug_material.BackfaceCulling = false;
             debug_material.Lighting = false;
             driver->setMaterial(debug_material);

             driver->draw3DBox(BoundingBox, video::SColor(255,255,0,255));
           }

           if(draw_normals)
           {
             k = EXTENT_K * BoundingBox.getExtent().getLength();

             video::SMaterial debug_material;
             debug_material.Wireframe = true;
             debug_material.BackfaceCulling = false;
             debug_material.Lighting = false;
             driver->setMaterial(debug_material);

             /* draw normals */
             for (s32 vert=0; vert<vertexCount; ++vert)
             {
                 driver->draw3DLine(core::vector3df(vertexBuffer[vert].X, 
                                                    vertexBuffer[vert].Y,
                                                    vertexBuffer[vert].Z),
                                    core::vector3df(vertexBuffer[vert].X + NORMAL_K*k*normalBuffer[vert].X,
                                                    vertexBuffer[vert].Y + NORMAL_K*k*normalBuffer[vert].Y,
                                                    vertexBuffer[vert].Z + NORMAL_K*k*normalBuffer[vert].Z),
                                    video::SColor(255,0,255,0));
             }
           }
        } // for subId
        
    } // for meshId
    
    //----------------------------------------------------------//
    renderer->endRendering();                                   // Tell the renderer we are finished now
}
Example #3
0
	HeightMap(u16 _w, u16 _h) : Width(_w), Height(_h), s(0.f), data(0)
	{
		s = sqrtf((f32)(Width * Width + Height * Height));
		data.set_used(Width * Height);
	}
core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData, core::vector3df pos, core::vector3df vel)
{
	f32 veryCloseDistance = colData.slidingSpeed;
	
	if (recursionDepth > 5)
		return pos;

	colData.velocity = vel;
	colData.normalizedVelocity = vel;
	colData.normalizedVelocity.normalize();
	colData.basePoint = pos;
	colData.foundCollision = false;
	colData.nearestDistance = FLT_MAX;

	double uhel_cos = 90 - acos(colData.normalizedVelocity.dotProduct(vector3df(0, -1, 0).normalize())) * 180.0 / PI;

	if (recursionDepth > 0 && vel.getLength() > 0 && vel.Y < 0)
	{
		if (abs(uhel_cos) < 50)
			return pos;
	}


	//------------------ collide with world

	// get all triangles with which we might collide
	core::aabbox3d<f32> box(colData.R3Position);
	box.addInternalPoint(colData.R3Position + colData.R3Velocity);
	box.MinEdge -= colData.eRadius;
	box.MaxEdge += colData.eRadius;

	s32 totalTriangleCnt = colData.selector->getTriangleCount();
	Triangles.set_used(totalTriangleCnt);

	core::matrix4 scaleMatrix;
	scaleMatrix.setScale(
			core::vector3df(1.0f / colData.eRadius.X,
					1.0f / colData.eRadius.Y,
					1.0f / colData.eRadius.Z));

	s32 triangleCnt = 0;


	colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix);


	for (s32 i=0; i<triangleCnt; ++i)
		if(testTriangleIntersection(&colData, Triangles[i]))
			colData.triangleIndex = i;


	//---------------- end collide with world

	if (!colData.foundCollision)
		return pos + vel;

	// original destination point
	const core::vector3df destinationPoint = pos + vel;
	core::vector3df newBasePoint = pos;

	if (colData.nearestDistance >= veryCloseDistance)
	{
		core::vector3df v = vel;
		v.setLength( colData.nearestDistance - veryCloseDistance );
		newBasePoint = colData.basePoint + v;

		v.normalize();
		colData.intersectionPoint -= (v * veryCloseDistance);
	}

	// calculate sliding plane

	const core::vector3df slidePlaneOrigin = colData.intersectionPoint;
	const core::vector3df slidePlaneNormal = (newBasePoint - colData.intersectionPoint).normalize();
	core::plane3d<f32> slidingPlane(slidePlaneOrigin, slidePlaneNormal);

	core::vector3df newDestinationPoint =
		destinationPoint -
		(slidePlaneNormal * slidingPlane.getDistanceTo(destinationPoint));

	// generate slide vector

	const core::vector3df newVelocityVector = newDestinationPoint -
		colData.intersectionPoint;

	if (newVelocityVector.getLength() < veryCloseDistance)
		return newBasePoint;

	//printf("Puvodni delka: %f | nova delka: %f\n", colData.velocity.getLength(), newVelocityVector.getLength());

	return collideWithWorld(recursionDepth+1, colData,
		newBasePoint, newVelocityVector);
}