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); }
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); }
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); }
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 ); } } }
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; }
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); } }
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); }