TeleporterSceneNode::TeleporterSceneNode(
	const Demo* const demo,
	const core::aabbox3d<f32>& placeA,
	const core::aabbox3d<f32>& placeB,
	const bool viceversa, const s32 id) :
	ISceneNode(demo->getSceneManager()->getRootSceneNode(), demo->getSceneManager(), id),
	demo(demo),
	nodesToWatch(nodesToWatch),
	placeA(placeA), placeB(placeB), viceversa(viceversa), dontTeleport(false), dontTeleportTimer(0.0f)
{
#ifdef _DEBUG
	setDebugName("TeleporterSceneNode");
#endif

	this->whirl[0] = new WhirlSceneNode(100, demo->getSceneManager()->getRootSceneNode(), demo->getSceneManager(), -1);
	this->whirl[0]->setPosition(placeA.getCenter());
	this->whirl[0]->setScale(irr::core::vector3df(30.0f, 30.0f, 30.0f));
//	this->whirl[0]->setDebugDataVisible(irr::scene::EDS_BBOX);

	this->whirl[1] = new WhirlSceneNode(100, demo->getSceneManager()->getRootSceneNode(), demo->getSceneManager(), -1);
	this->whirl[1]->setPosition(placeB.getCenter());
	this->whirl[1]->setScale(irr::core::vector3df(30.0f, 30.0f, 30.0f));

	this->Material.Lighting = false;


	this->text[0] = demo->getSceneManager()->addBillboardTextSceneNode(
		demo->getFont(), L"Teleporter", this->whirl[0], irr::core::dimension2df(120, 100), irr::core::vector3df(0, 5, 0));


	this->text[1] = demo->getSceneManager()->addBillboardTextSceneNode(
		demo->getFont(), L"Teleporter", this->whirl[1], irr::core::dimension2df(120, 100), irr::core::vector3df(0, 5, 0));

	this->setAutomaticCulling(irr::scene::EAC_OFF);
}
Beispiel #2
0
	CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
		: scene::ISceneNode(parent, mgr, id)
	{
		Material.Wireframe = false;
		Material.Lighting = false;

		Vertices[0] = video::S3DVertex(0,0,10, 1,1,0,
				video::SColor(255,0,255,255), 0, 1);
		Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0,
				video::SColor(255,255,0,255), 1, 1);
		Vertices[2] = video::S3DVertex(0,20,0, 0,1,1,
				video::SColor(255,255,255,0), 1, 0);
		Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1,
				video::SColor(255,0,255,0), 0, 0);

	/*
	The Irrlicht Engine needs to know the bounding box of a scene node.
	It will use it for automatic culling and other things. Hence, we
	need to create a bounding box from the 4 vertices we use.
	If you do not want the engine to use the box for automatic culling,
	and/or don't want to create the box, you could also call
	irr::scene::ISceneNode::setAutomaticCulling() with irr::scene::EAC_OFF.
	*/
		Box.reset(Vertices[0].Pos);
		for (s32 i=1; i<4; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}
Beispiel #3
0
	CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
		: scene::ISceneNode(parent, mgr, id)
	{
		Descriptor = mgr->getVideoDriver()->getVertexDescriptor(0);

		VertexBuffer = new scene::CVertexBuffer<video::S3DVertex>();
		IndexBuffer = new scene::CIndexBuffer(video::EIT_16BIT);
		MeshBuffer = new scene::CMeshBuffer<video::S3DVertex>(Descriptor);

		Material.Wireframe = false;
		Material.Lighting = false;

		video::S3DVertex Vertices[4];

		Vertices[0] = video::S3DVertex(0,0,10, 1,1,0, video::SColor(255,0,255,255), 0, 1);
		Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0, video::SColor(255,255,0,255), 1, 1);
		Vertices[2] = video::S3DVertex(0,20,0, 0,1,1, video::SColor(255,255,255,0), 1, 0);
		Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1, video::SColor(255,0,255,0), 0, 0);

		for (s32 i = 0; i<4; ++i)
			VertexBuffer->addVertex(&Vertices[i]);
			
	/*
	Indices into the 'Vertices' array. A triangle needs 3 vertices 
	so you have to pass the 3 corresponding indices for each triangle to 
	tell which of the vertices should be used for it.
	*/

		IndexBuffer->addIndex(0);
		IndexBuffer->addIndex(2);
		IndexBuffer->addIndex(3);
		IndexBuffer->addIndex(2);
		IndexBuffer->addIndex(1);
		IndexBuffer->addIndex(3);
		IndexBuffer->addIndex(1);
		IndexBuffer->addIndex(0);
		IndexBuffer->addIndex(3);
		IndexBuffer->addIndex(2);
		IndexBuffer->addIndex(0);
		IndexBuffer->addIndex(1);

	/*
	Append Vertex and Index buffers to the Mesh buffer.
	*/

		MeshBuffer->setVertexBuffer(VertexBuffer, 0);
		MeshBuffer->setIndexBuffer(IndexBuffer);

	/*
	The Irrlicht Engine needs to know the bounding box of a scene node.
	It will use it for automatic culling and other things. Hence, we
	need to create a bounding box from the 4 vertices we use.
	If you do not want the engine to use the box for automatic culling,
	and/or don't want to create the box, you could also call
	irr::scene::ISceneNode::setAutomaticCulling() with irr::scene::EAC_OFF.
	*/
		Box.reset(Vertices[0].Pos);
		for (s32 i=1; i<4; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}
void COctreeTriangleSelector::getTrianglesFromOctree(
		SOctreeNode* node, s32& trianglesWritten,
		s32 maximumSize, const core::aabbox3d<f32>& box,
		const core::matrix4* mat, core::triangle3df* triangles) const
{
	if (!box.intersectsWithBox(node->Box))
		return;

	const u32 cnt = node->Triangles.size();

	for (u32 i=0; i<cnt; ++i)
	{
		const core::triangle3df& srcTri = node->Triangles[i];
		// This isn't an accurate test, but it's fast, and the 
		// API contract doesn't guarantee complete accuracy.
		if (srcTri.isTotalOutsideBox(box))
			continue;

		core::triangle3df& dstTri = triangles[trianglesWritten];
		mat->transformVect(dstTri.pointA, srcTri.pointA );
		mat->transformVect(dstTri.pointB, srcTri.pointB );
		mat->transformVect(dstTri.pointC, srcTri.pointC );
		++trianglesWritten;

		// Halt when the out array is full.
		if (trianglesWritten == maximumSize)
			return;
	}

	for (u32 i=0; i<8; ++i)
		if (node->Child[i])
			getTrianglesFromOctree(node->Child[i], trianglesWritten,
			maximumSize, box, mat, triangles);
}
void COctTreeTriangleSelector::getTrianglesFromOctTree(
		SOctTreeNode* node, s32& trianglesWritten,
		s32 maximumSize, const core::aabbox3d<f32>& box,
		const core::matrix4* mat, core::triangle3df* triangles) const
{
	if (!box.intersectsWithBox(node->Box))
		return;

	s32 cnt = node->Triangles.size();
	if (cnt + trianglesWritten > maximumSize)
		cnt -= cnt + trianglesWritten - maximumSize;

	s32 i;
	
	for (i=0; i<cnt; ++i)
	{
		triangles[trianglesWritten] = node->Triangles[i];
		mat->transformVect(triangles[trianglesWritten].pointA);
		mat->transformVect(triangles[trianglesWritten].pointB);
		mat->transformVect(triangles[trianglesWritten].pointC);
		++trianglesWritten;
	}

	for (i=0; i<8; ++i)
		if (node->Child[i])
			getTrianglesFromOctTree(node->Child[i], trianglesWritten,
			maximumSize, box, mat, triangles);
}
Beispiel #6
0
	CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager *mgr, s32 id)
		:scene::ISceneNode(parent, mgr, id)
	{
		Material.Wireframe = false;
		Material.Lighting  = false;

		Vertices[0] = video::S3DVertex(0,0,10, 1,1,0,    video::SColor(255,0,255,255), 0, 1);
		Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0,  video::SColor(255,255,0,255), 1, 1);
		Vertices[2] = video::S3DVertex(0,20,0, 0,1,1,    video::SColor(255,255,255,0), 1, 0);
		Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1, video::SColor(255,0, 255, 0), 0, 0);

		Box.reset(Vertices[0].Pos);

		for (s32 i=1; i<4; ++i) 
		{
			Box.addInternalPoint(Vertices[i].Pos);
		}
	}
void BuildCylinder(   
        core::array<video::S3DVertex>& vertexArray,
        core::array<u16>& indexArray,
        core::aabbox3d<f32>& boundingBox,
        
        f32 height,
        f32 startRadius,
        f32 endRadius,
        s32 radialSegments,
        
        const core::matrix4& transform,
        
        f32 startTCoordY = 0.0f,
        f32 endTCoordY = 1.0f,
        video::SColor startColor = video::SColor(255,255,255,255),
        video::SColor endColor = video::SColor(255,255,255,255) )
{
    u16 vertexIndex = vertexArray.size();
    
    s32 radialVertices = radialSegments + 1; // We want one additional vertex to make the texture wraps correctly
    
    // Place bottom cap
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df pos;
        core::vector3df normal = dir;

        pos = dir * startRadius;
        
        // Place bottom vertex
        transform.transformVect( pos );
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = startTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            startColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint( pos );
    }
    
    // Place top cap and indices
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df normal = dir;
        core::vector3df pos = dir * endRadius;
        pos.Y = height;
        
        transform.transformVect( pos ); 
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = endTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            endColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint(pos);
        
        // Add indices
        if ( i != radialVertices-1 )
        {
            s32 i2 = (i+1)%radialVertices;
            // Place the indices
            indexArray.push_back ( vertexIndex + i );
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + i2 );
            
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + radialVertices + i2 );
            indexArray.push_back ( vertexIndex + i2 );
        }
    }
}
Beispiel #8
0
PathCost Pathfinder::calcCost(v3s16 pos, v3s16 dir)
{
    INodeDefManager *ndef = m_env->getGameDef()->ndef();
    PathCost retval;

    retval.updated = true;

    v3s16 pos2 = pos + dir;

    //check limits
    if (!m_limits.isPointInside(pos2)) {
        DEBUG_OUT("Pathfinder: " << PP(pos2) <<
                  " no cost -> out of limits" << std::endl);
        return retval;
    }

    MapNode node_at_pos2 = m_env->getMap().getNodeNoEx(pos2);

    //did we get information about node?
    if (node_at_pos2.param0 == CONTENT_IGNORE ) {
        VERBOSE_TARGET << "Pathfinder: (1) area at pos: "
                       << PP(pos2) << " not loaded";
        return retval;
    }

    if (!ndef->get(node_at_pos2).walkable) {
        MapNode node_below_pos2 =
            m_env->getMap().getNodeNoEx(pos2 + v3s16(0, -1, 0));

        //did we get information about node?
        if (node_below_pos2.param0 == CONTENT_IGNORE ) {
            VERBOSE_TARGET << "Pathfinder: (2) area at pos: "
                           << PP((pos2 + v3s16(0, -1, 0))) << " not loaded";
            return retval;
        }

        if (ndef->get(node_below_pos2).walkable) {
            retval.valid = true;
            retval.value = 1;
            retval.direction = 0;
            DEBUG_OUT("Pathfinder: "<< PP(pos)
                      << " cost same height found" << std::endl);
        }
        else {
            v3s16 testpos = pos2 - v3s16(0, -1, 0);
            MapNode node_at_pos = m_env->getMap().getNodeNoEx(testpos);

            while ((node_at_pos.param0 != CONTENT_IGNORE) &&
                    (!ndef->get(node_at_pos).walkable) &&
                    (testpos.Y > m_limits.MinEdge.Y)) {
                testpos += v3s16(0, -1, 0);
                node_at_pos = m_env->getMap().getNodeNoEx(testpos);
            }

            //did we find surface?
            if ((testpos.Y >= m_limits.MinEdge.Y) &&
                    (node_at_pos.param0 != CONTENT_IGNORE) &&
                    (ndef->get(node_at_pos).walkable)) {
                if ((pos2.Y - testpos.Y - 1) <= m_maxdrop) {
                    retval.valid = true;
                    retval.value = 2;
                    //difference of y-pos +1 (target node is ABOVE solid node)
                    retval.direction = ((testpos.Y - pos2.Y) +1);
                    DEBUG_OUT("Pathfinder cost below height found" << std::endl);
                }
                else {
                    INFO_TARGET << "Pathfinder:"
                                " distance to surface below to big: "
                                << (testpos.Y - pos2.Y) << " max: " << m_maxdrop
                                << std::endl;
                }
            }
            else {
                DEBUG_OUT("Pathfinder: no surface below found" << std::endl);
            }
        }
    }
    else {
        v3s16 testpos = pos2;
        MapNode node_at_pos = m_env->getMap().getNodeNoEx(testpos);

        while ((node_at_pos.param0 != CONTENT_IGNORE) &&
                (ndef->get(node_at_pos).walkable) &&
                (testpos.Y < m_limits.MaxEdge.Y)) {
            testpos += v3s16(0, 1, 0);
            node_at_pos = m_env->getMap().getNodeNoEx(testpos);
        }

        //did we find surface?
        if ((testpos.Y <= m_limits.MaxEdge.Y) &&
                (!ndef->get(node_at_pos).walkable)) {

            if (testpos.Y - pos2.Y <= m_maxjump) {
                retval.valid = true;
                retval.value = 2;
                retval.direction = (testpos.Y - pos2.Y);
                DEBUG_OUT("Pathfinder cost above found" << std::endl);
            }
            else {
                DEBUG_OUT("Pathfinder: distance to surface above to big: "
                          << (testpos.Y - pos2.Y) << " max: " << m_maxjump
                          << std::endl);
            }
        }
        else {
            DEBUG_OUT("Pathfinder: no surface above found" << std::endl);
        }
    }
    return retval;
}
Beispiel #9
0
void CNodeDefManager::clear()
{
	m_content_features.clear();
	m_name_id_mapping.clear();
	m_name_id_mapping_with_aliases.clear();
	m_group_to_items.clear();
	m_next_id = 0;
	m_selection_box_union.reset(0,0,0);
	m_selection_box_int_union.reset(0,0,0);

	resetNodeResolveState();

	u32 initial_length = 0;
	initial_length = MYMAX(initial_length, CONTENT_UNKNOWN + 1);
	initial_length = MYMAX(initial_length, CONTENT_AIR + 1);
	initial_length = MYMAX(initial_length, CONTENT_IGNORE + 1);
	m_content_features.resize(initial_length);

	// Set CONTENT_UNKNOWN
	{
		ContentFeatures f;
		f.name = "unknown";
		// Insert directly into containers
		content_t c = CONTENT_UNKNOWN;
		m_content_features[c] = f;
		addNameIdMapping(c, f.name);
	}

	// Set CONTENT_AIR
	{
		ContentFeatures f;
		f.name                = "air";
		f.drawtype            = NDT_AIRLIKE;
		f.param_type          = CPT_LIGHT;
		f.light_propagates    = true;
		f.sunlight_propagates = true;
		f.walkable            = false;
		f.pointable           = false;
		f.diggable            = false;
		f.buildable_to        = true;
		f.floodable           = true;
		f.is_ground_content   = true;
		// Insert directly into containers
		content_t c = CONTENT_AIR;
		m_content_features[c] = f;
		addNameIdMapping(c, f.name);
	}

	// Set CONTENT_IGNORE
	{
		ContentFeatures f;
		f.name                = "ignore";
		f.drawtype            = NDT_AIRLIKE;
		f.param_type          = CPT_NONE;
		f.light_propagates    = false;
		f.sunlight_propagates = false;
		f.walkable            = false;
		f.pointable           = false;
		f.diggable            = false;
		f.buildable_to        = true; // A way to remove accidental CONTENT_IGNOREs
		f.is_ground_content   = true;
		// Insert directly into containers
		content_t c = CONTENT_IGNORE;
		m_content_features[c] = f;
		addNameIdMapping(c, f.name);
	}
}
Beispiel #10
0
	CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id
							,core::vector3d<float>P[]
							,core::vector3d<float>Ups[]
							,short ncontrolpts)
		: scene::ISceneNode(parent, mgr, id)
	{

		Material.Wireframe = true;
		Material.Lighting = false;

		std::vector<core::vector3d<float> >p;
		core::vector3d<float> basetri[3]
			=	{{-0.5,0,0},{0.5,0,0},{0.25,-0.25,0}};
		core::vector3d<float> rottri[2];

		core::vector3d<float> A,B,C;
		float ABdot,BCdot,ABmag,BCmag;
		float cosABang,cosBCang,ABang,BCang,angtotal;

		//calculate angle of rotation
		{
		A=P[1]-P[0];
		B=P[2]-P[1];
		C=P[3]-P[2];
		ABdot=A.dotProduct(B);
		BCdot=B.dotProduct(C);
		ABmag=A.getLength()*B.getLength();
		BCmag=B.getLength()*C.getLength();
		cosABang=ABdot/ABmag;
		cosBCang=BCdot/BCmag;
		ABang=acos(cosABang);
		BCang=acos(cosBCang);
		angtotal=ABang+BCang;
		}

		//set up the interpolation of the spline
		const float pi=3.1415927;
		float angdegrees=angtotal*180/pi;
		float npoints=angdegrees/12;
		nverts=(s16)(npoints+0.5);
		float tstep=1/std::max((float)nverts,1.0f);
		core::vector3d<float> curpt;
		core::vector3d<float> curup;

		//print some info before setting the interppolation points
		std::cout<<"total curve angle: "<<angtotal<<std::endl;
		std::cout<<"; steps: "<<nverts<<std::endl;

		//interpolate the spline
		p.clear();
		for(float t=0.0;t<1.0+tstep;t+=tstep)
			{
			float scale[4]=
				{
				pow(1.0f-t,3)
				,3*pow(1.0f-t,2)*t
				,3*(1.0f-t)*pow(t,2)
				,pow(t,3)
				};
			curup= 	scale[0]*Ups[0]				//pow(1-t,3)*P[0]
						+	scale[1]*Ups[1]		//3*pow(1-t,2)*t*P[1]
						+	scale[2]*Ups[2]	//3*(1-t)*pow(t,2)*P[2]
						+	scale[3]*Ups[3];					//pow(t,3)*P[3]
			curpt= 	scale[0]*P[0]				//pow(1-t,3)*P[0]
						+	scale[1]*P[1]		//3*pow(1-t,2)*t*P[1]
						+	scale[2]*P[2]	//3*(1-t)*pow(t,2)*P[2]
						+	scale[3]*P[3];					//pow(t,3)*P[3]
			//=(1-$A11)^3*B$4    +      3*(1-$A11)^2*$A11*B$5
			//+     3*(1-$A11)*$A11^2*B$6    +    $A11^3*B$7
			p.push_back(curpt);
			}
		for(int i=0;i<p.size();i++)
			{
			std::cout<<"interpolation - pt "<<i<<" - ";
			std::cout<<"("<<p[i].X<<","<<p[i].Y<<","<<p[i].Z<<")"<<std::endl;

			Vertices[i] =
					video::S3DVertex(p[i].X,p[i].Y,p[i].Z, 1,1,0,
							video::SColor(255,0,0,255), 0, 1);
			}

	/*
	The Irrlicht Engine needs to know the bounding box of a scene node.
	It will use it for automatic culling and other things. Hence, we
	need to create a bounding box from the 4 vertices we use.
	If you do not want the engine to use the box for automatic culling,
	and/or don't want to create the box, you could also call
	irr::scene::ISceneNode::setAutomaticCulling() with irr::scene::EAC_OFF.
	*/
		Box.reset(Vertices[0].Pos);
		for (s32 i=1; i<nverts; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}