// ------------------------------------------------------------------------------------------------ // Build a tetrahedron with points.magnitude == 1 unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions) { positions.reserve(positions.size()+9); const float a = 1.41421f/3.f; const float b = 2.4494f/3.f; const aiVector3D v0 = aiVector3D(0.f,0.f,1.f); const aiVector3D v1 = aiVector3D(2*a,0,-1.f/3.f); const aiVector3D v2 = aiVector3D(-a,b,-1.f/3.f); const aiVector3D v3 = aiVector3D(-a,-b,-1.f/3.f); ADD_TRIANGLE(v0,v1,v2); ADD_TRIANGLE(v0,v2,v3); ADD_TRIANGLE(v0,v3,v1); ADD_TRIANGLE(v1,v3,v2); return 3; }
// ------------------------------------------------------------------------------------------------ // Build a tetrahedron with points.magnitude == 1 unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions) { positions.reserve(positions.size()+9); const ai_real a = 1.41421/3.0; const ai_real b = 2.4494/3.0; const aiVector3D v0 = aiVector3D(0.0,0.0,1.0); const aiVector3D v1 = aiVector3D(2*a,0,-1.0/3.0); const aiVector3D v2 = aiVector3D(-a,b,-1.0/3.0); const aiVector3D v3 = aiVector3D(-a,-b,-1.0/3.0); ADD_TRIANGLE(v0,v1,v2); ADD_TRIANGLE(v0,v2,v3); ADD_TRIANGLE(v0,v3,v1); ADD_TRIANGLE(v1,v3,v2); return 3; }
// ------------------------------------------------------------------------------------------------ // Fast subdivision for a mesh whose verts have a magnitude of 1 void Subdivide(std::vector<aiVector3D>& positions) { // assume this to be constant - (fixme: must be 1.0? I think so) const float fl1 = positions[0].Length(); unsigned int origSize = (unsigned int)positions.size(); for (unsigned int i = 0 ; i < origSize ; i+=3) { aiVector3D& tv0 = positions[i]; aiVector3D& tv1 = positions[i+1]; aiVector3D& tv2 = positions[i+2]; aiVector3D a = tv0, b = tv1, c = tv2; aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1; aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1; aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1; tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original ADD_TRIANGLE(v1, v2, a); ADD_TRIANGLE(v2, v3, c); ADD_TRIANGLE(v3, v1, b); } }
void CollisionShapeBox::update_indicator(RID p_indicator) { VisualServer *vs=VisualServer::get_singleton(); vs->poly_clear(p_indicator); Color col(0.4,1.0,1.0,0.5); for (int i=0;i<6;i++) { Vector3 face_points[4]; for (int j=0;j<4;j++) { float v[3]; v[0]=1.0; v[1]=1-2*((j>>1)&1); v[2]=v[1]*(1-2*(j&1)); for (int k=0;k<3;k++) { if (i<3) face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); else face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); } } for(int j=0;j<4;j++) face_points[i]*=half_extents; ADD_TRIANGLE(face_points[0],face_points[1],face_points[2],col); ADD_TRIANGLE(face_points[2],face_points[3],face_points[0],col); } }
void CollisionShapeCapsule::update_indicator(RID p_indicator) { VisualServer *vs=VisualServer::get_singleton(); vs->poly_clear(p_indicator); Color col(0.4,1.0,1.0,0.5); DVector<Plane> planes = Geometry::build_capsule_planes(radius, height, 12, 3, Vector3::AXIS_Z); Geometry::MeshData md = Geometry::build_convex_mesh(planes); for(int i=0;i<md.faces.size();i++) { for(int j=2;j<md.faces[i].indices.size();j++) { ADD_TRIANGLE(md.vertices[md.faces[i].indices[0]],md.vertices[md.faces[i].indices[j-1]],md.vertices[md.faces[i].indices[j]],col); } } }
// ------------------------------------------------------------------------------------------------ // Build an octahedron with points.magnitude == 1 unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions) { positions.reserve(positions.size()+24); const aiVector3D v0 = aiVector3D(1.0f, 0.f, 0.f) ; const aiVector3D v1 = aiVector3D(-1.0f, 0.f, 0.f); const aiVector3D v2 = aiVector3D(0.f, 1.0f, 0.f); const aiVector3D v3 = aiVector3D(0.f, -1.0f, 0.f); const aiVector3D v4 = aiVector3D(0.f, 0.f, 1.0f); const aiVector3D v5 = aiVector3D(0.f, 0.f, -1.0f); ADD_TRIANGLE(v4,v0,v2); ADD_TRIANGLE(v4,v2,v1); ADD_TRIANGLE(v4,v1,v3); ADD_TRIANGLE(v4,v3,v0); ADD_TRIANGLE(v5,v2,v0); ADD_TRIANGLE(v5,v1,v2); ADD_TRIANGLE(v5,v3,v1); ADD_TRIANGLE(v5,v0,v3); return 3; }
RES Camera::_get_gizmo_geometry() const { Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); Ref<FixedMaterial> mat( memnew( FixedMaterial )); mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.5) ); mat->set_line_width(4); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); //mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); switch(mode) { case PROJECTION_PERSPECTIVE: { Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) ); Vector3 nside=side; nside.x=-nside.x; Vector3 up=Vector3(0,side.x,0); #define ADD_TRIANGLE( m_a, m_b, m_c)\ {\ surface_tool->add_vertex(m_a);\ surface_tool->add_vertex(m_b);\ surface_tool->add_vertex(m_b);\ surface_tool->add_vertex(m_c);\ surface_tool->add_vertex(m_c);\ surface_tool->add_vertex(m_a);\ } ADD_TRIANGLE( Vector3(), side+up, side-up ); ADD_TRIANGLE( Vector3(), nside+up, nside-up ); ADD_TRIANGLE( Vector3(), side+up, nside+up ); ADD_TRIANGLE( Vector3(), side-up, nside-up ); side.x*=0.25; nside.x*=0.25; Vector3 tup( 0, up.y*3/2,side.z); ADD_TRIANGLE( tup, side+up, nside+up ); } break; case PROJECTION_ORTHOGONAL: { #define ADD_QUAD( m_a, m_b, m_c, m_d)\ {\ surface_tool->add_vertex(m_a);\ surface_tool->add_vertex(m_b);\ surface_tool->add_vertex(m_b);\ surface_tool->add_vertex(m_c);\ surface_tool->add_vertex(m_c);\ surface_tool->add_vertex(m_d);\ surface_tool->add_vertex(m_d);\ surface_tool->add_vertex(m_a);\ } float hsize=size*0.5; Vector3 right(hsize,0,0); Vector3 up(0,hsize,0); Vector3 back(0,0,-1.0); Vector3 front(0,0,0); ADD_QUAD( -up-right,-up+right,up+right,up-right); ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back); ADD_QUAD( up+right,up+right+back,up-right+back,up-right); ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right); right.x*=0.25; Vector3 tup( 0, up.y*3/2,back.z ); ADD_TRIANGLE( tup, right+up+back, -right+up+back ); } break; } return surface_tool->commit(); }
// ------------------------------------------------------------------------------------------------ // Build an incosahedron with points.magnitude == 1 unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions) { positions.reserve(positions.size()+60); const float t = (1.f + 2.236067977f)/2.f; const float s = math::sqrt(1.f + t*t); const aiVector3D v0 = aiVector3D(t,1.f, 0.f)/s; const aiVector3D v1 = aiVector3D(-t,1.f, 0.f)/s; const aiVector3D v2 = aiVector3D(t,-1.f, 0.f)/s; const aiVector3D v3 = aiVector3D(-t,-1.f, 0.f)/s; const aiVector3D v4 = aiVector3D(1.f, 0.f, t)/s; const aiVector3D v5 = aiVector3D(1.f, 0.f,-t)/s; const aiVector3D v6 = aiVector3D(-1.f, 0.f,t)/s; const aiVector3D v7 = aiVector3D(-1.f, 0.f,-t)/s; const aiVector3D v8 = aiVector3D(0.f, t, 1.f)/s; const aiVector3D v9 = aiVector3D(0.f,-t, 1.f)/s; const aiVector3D v10 = aiVector3D(0.f, t,-1.f)/s; const aiVector3D v11 = aiVector3D(0.f,-t,-1.f)/s; ADD_TRIANGLE(v0,v8,v4); ADD_TRIANGLE(v0,v5,v10); ADD_TRIANGLE(v2,v4,v9); ADD_TRIANGLE(v2,v11,v5); ADD_TRIANGLE(v1,v6,v8); ADD_TRIANGLE(v1,v10,v7); ADD_TRIANGLE(v3,v9,v6); ADD_TRIANGLE(v3,v7,v11); ADD_TRIANGLE(v0,v10,v8); ADD_TRIANGLE(v1,v8,v10); ADD_TRIANGLE(v2,v9,v11); ADD_TRIANGLE(v3,v11,v9); ADD_TRIANGLE(v4,v2,v0); ADD_TRIANGLE(v5,v0,v2); ADD_TRIANGLE(v6,v1,v3); ADD_TRIANGLE(v7,v3,v1); ADD_TRIANGLE(v8,v6,v4); ADD_TRIANGLE(v9,v4,v6); ADD_TRIANGLE(v10,v5,v7); ADD_TRIANGLE(v11,v7,v5); return 3; }
void PaintLayer::drawLines(CCArray *linePoints, ccColor4F color) { unsigned int numberOfVertices = (linePoints->count() - 1) * 18; LineVertex *vertices = (LineVertex *)calloc(sizeof(LineVertex), numberOfVertices); CCPoint prevPoint = ((LinePoint *)linePoints->objectAtIndex(0))->pos; float prevValue = ((LinePoint *)linePoints->objectAtIndex(0))->width; float curValue; int index = 0; for (int i = 1; i < linePoints->count(); ++i) { LinePoint *pointValue = (LinePoint *)linePoints->objectAtIndex(i); CCPoint curPoint = pointValue->pos; curValue = pointValue->width; //! equal points, skip them if (ccpFuzzyEqual(curPoint, prevPoint, 0.0001f)) { continue; } CCPoint dir = ccpSub(curPoint, prevPoint); CCPoint perpendicular = ccpNormalize(ccpPerp(dir)); CCPoint A = ccpAdd(prevPoint, ccpMult(perpendicular, prevValue / 2)); CCPoint B = ccpSub(prevPoint, ccpMult(perpendicular, prevValue / 2)); CCPoint C = ccpAdd(curPoint, ccpMult(perpendicular, curValue / 2)); CCPoint D = ccpSub(curPoint, ccpMult(perpendicular, curValue / 2)); //! continuing line if (connectingLine || index > 0) { A = prevC; B = prevD; } else if (index == 0) { //! circle at start of line, revert direction circlesPoints->addObject(pointValue); circlesPoints->addObject(linePoints->objectAtIndex(i-1)); } ADD_TRIANGLE(A, B, C, 1.0f); ADD_TRIANGLE(B, C, D, 1.0f); prevD = D; prevC = C; if (finishingLine && (i == linePoints->count() - 1)) { circlesPoints->addObject(linePoints->objectAtIndex(i-1)); circlesPoints->addObject(pointValue); finishingLine = false; } prevPoint = curPoint; prevValue = curValue; //! Add overdraw CCPoint F = ccpAdd(A, ccpMult(perpendicular, overdraw)); CCPoint G = ccpAdd(C, ccpMult(perpendicular, overdraw)); CCPoint H = ccpSub(B, ccpMult(perpendicular, overdraw)); CCPoint I = ccpSub(D, ccpMult(perpendicular, overdraw)); //! end vertices of last line are the start of this one, also for the overdraw if (connectingLine || index > 6) { F = prevG; H = prevI; } prevG = G; prevI = I; ADD_TRIANGLE(F, A, G, 2.0f); ADD_TRIANGLE(A, G, C, 2.0f); ADD_TRIANGLE(B, H, D, 2.0f); ADD_TRIANGLE(H, D, I, 2.0f); } this->fillLineTriangles(vertices, index, color); if (index > 0) { connectingLine = true; } free(vertices); }
// ------------------------------------------------------------------------------------------------ // Build an incosahedron with points.magnitude == 1 unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions) { positions.reserve(positions.size()+60); const ai_real t = ( ai_real( 1.0 )+ ai_real( 2.236067977 ) ) / ai_real( 2.0 ); const ai_real s = std::sqrt(ai_real(1.0) + t*t); const aiVector3D v0 = aiVector3D(t,1.0, 0.0)/s; const aiVector3D v1 = aiVector3D(-t,1.0, 0.0)/s; const aiVector3D v2 = aiVector3D(t,-1.0, 0.0)/s; const aiVector3D v3 = aiVector3D(-t,-1.0, 0.0)/s; const aiVector3D v4 = aiVector3D(1.0, 0.0, t)/s; const aiVector3D v5 = aiVector3D(1.0, 0.0,-t)/s; const aiVector3D v6 = aiVector3D(-1.0, 0.0,t)/s; const aiVector3D v7 = aiVector3D(-1.0, 0.0,-t)/s; const aiVector3D v8 = aiVector3D(0.0, t, 1.0)/s; const aiVector3D v9 = aiVector3D(0.0,-t, 1.0)/s; const aiVector3D v10 = aiVector3D(0.0, t,-1.0)/s; const aiVector3D v11 = aiVector3D(0.0,-t,-1.0)/s; ADD_TRIANGLE(v0,v8,v4); ADD_TRIANGLE(v0,v5,v10); ADD_TRIANGLE(v2,v4,v9); ADD_TRIANGLE(v2,v11,v5); ADD_TRIANGLE(v1,v6,v8); ADD_TRIANGLE(v1,v10,v7); ADD_TRIANGLE(v3,v9,v6); ADD_TRIANGLE(v3,v7,v11); ADD_TRIANGLE(v0,v10,v8); ADD_TRIANGLE(v1,v8,v10); ADD_TRIANGLE(v2,v9,v11); ADD_TRIANGLE(v3,v11,v9); ADD_TRIANGLE(v4,v2,v0); ADD_TRIANGLE(v5,v0,v2); ADD_TRIANGLE(v6,v1,v3); ADD_TRIANGLE(v7,v3,v1); ADD_TRIANGLE(v8,v6,v4); ADD_TRIANGLE(v9,v4,v6); ADD_TRIANGLE(v10,v5,v7); ADD_TRIANGLE(v11,v7,v5); return 3; }
void makeCameraFrustum(shapes::Mesh &mesh, double near_, double far_, double fovX, double fovY, bool makeSolid, bool addPrism) { double ax = tan(fovX/2) ; double ay = tan(fovY/2) ; double nx = near_ * ax ; double ny = near_ * ay ; double fx = far_ * ax ; double fy = far_ * ay ; btVector3 p[9] ; p[0] = btVector3(0, 0, 0) ; // origin p[1] = btVector3( -nx, -ny, near_ ); p[2] = btVector3( nx, -ny, near_ ); p[3] = btVector3( nx, ny, near_ ); p[4] = btVector3( -nx, ny, near_ ); p[5] = btVector3( -fx, -fy, far_ ); p[6] = btVector3( fx, -fy, far_ ); p[7] = btVector3( fx, fy, far_ ); p[8] = btVector3( -fx, fy, far_ ); mesh.vertexCount = 9 ; mesh.vertices = new double [3 * mesh.vertexCount] ; mesh.triangleCount = 8 ; if ( makeSolid ) { mesh.triangleCount += 2 ; if ( !addPrism ) mesh.triangleCount += 2 ; } if ( addPrism ) mesh.triangleCount += 4 ; mesh.triangles = new unsigned int [mesh.triangleCount * 3] ; for(int i=0, k=0 ; i<9 ; i++ ) { mesh.vertices[k++] = p[i].x() ; mesh.vertices[k++] = p[i].y() ; mesh.vertices[k++] = p[i].z() ; } #define ADD_TRIANGLE(v1, v2, v3)\ mesh.triangles[k++] = v1 ;\ mesh.triangles[k++] = v2 ;\ mesh.triangles[k++] = v3 ; int k=0 ; ADD_TRIANGLE(1, 5, 4) ; ADD_TRIANGLE(4, 5, 8) ; ADD_TRIANGLE(1, 5, 6) ; ADD_TRIANGLE(1, 6, 2) ; ADD_TRIANGLE(2, 6, 3) ; ADD_TRIANGLE(3, 6, 7) ; ADD_TRIANGLE(4, 8, 7) ; ADD_TRIANGLE(4, 7, 3) ; if ( makeSolid ) { ADD_TRIANGLE(5, 6, 7) ; ADD_TRIANGLE(5, 7, 8) ; if ( !addPrism ) { ADD_TRIANGLE(1, 2, 3) ; ADD_TRIANGLE(1, 3, 4) ; } } if ( addPrism ) { ADD_TRIANGLE(0, 1, 2) ; ADD_TRIANGLE(0, 2, 3) ; ADD_TRIANGLE(0, 3, 4) ; ADD_TRIANGLE(0, 4, 1) ; } mesh.normals = 0 ; }
void rIndexedShadowVolume_c::addDirectionalIndexedVertexList( const rIndexBuffer_c& oIndices, const rVertexBuffer_c& oVerts, const vec3_c& lightDir, const class planeArray_c* extraPlanesArray, float lightInfinity, const class aabb* bounds ) { #if 1 // for a single triangle, in worst case we might need to create: // front cap + end cap + 3 edge quads // 1 + 1 + 3 * 2 = 2 + 6 = 8 triangles indices.ensureAllocated_indices( indices.getNumIndices() + oIndices.getNumTriangles() * 8 * 3 ); points.ensureAllocated( points.size() + oVerts.size() * 2 ); #endif #ifdef OPTIMIZE_SLOW_ADDTRIANGLE if ( indices.getU16Ptr() == 0 ) return; u16* pFirstIndex = ( ( u16* )indices.getU16Ptr() ) + indices.getNumIndices(); u16* pNextIndex = pFirstIndex; #endif vec3_c delta = lightDir * lightInfinity; //if(rf_ssv_algorithm.getInt() == 0) { // for(u32 i = 0; i < oIndices.getNumIndices(); i+=3){ // u32 i0 = oIndices[i+0]; // u32 i1 = oIndices[i+1]; // u32 i2 = oIndices[i+2]; // const vec3_c &v0 = oVerts[i0].xyz; // const vec3_c &v1 = oVerts[i1].xyz; // const vec3_c &v2 = oVerts[i2].xyz; // addTriangle(v0,v1,v2,light); // } //} else { //bool bMeshFullyInsideLight; //if(bounds) { // bMeshFullyInsideLight = IsAABBInsideSphere(*bounds,light,lightRadius); //} else { // bMeshFullyInsideLight = false; //} // do the same thing as above, but a little faster way static arraySTD_c<byte> bPointTransformed; if ( bPointTransformed.size() < oVerts.size() ) { bPointTransformed.resize( oVerts.size() ); } bPointTransformed.nullMemory(); static arraySTD_c<vec3_c> pointsTransformed; if ( pointsTransformed.size() < oVerts.size() ) { pointsTransformed.resize( oVerts.size() ); } u32 tri = 0; for ( u32 i = 0; i < oIndices.getNumIndices(); i += 3, tri++ ) { u32 vi0 = oIndices[i + 0]; u32 vi1 = oIndices[i + 1]; u32 vi2 = oIndices[i + 2]; const vec3_c& p0 = oVerts[vi0].xyz; const vec3_c& p1 = oVerts[vi1].xyz; const vec3_c& p2 = oVerts[vi2].xyz; // cull triangles that are outside light radius // This is a good optimisation for very large models intersecting very small lights //if(rf_ssv_cullTrianglesOutSideLightSpheres.getInt()) { // // we can't cull that way any triangles if mesh bounds are entirely inside light sphere // if(bMeshFullyInsideLight == false) { // if(CU_IntersectSphereTriangle(light,lightRadius,p0,p1,p2) == false) { // continue; // } // } //} float d; if ( extraPlanesArray == 0 ) { plane_c triPlane; triPlane.fromThreePoints( p2, p1, p0 ); d = triPlane.norm.dotProduct( lightDir ); } else { d = extraPlanesArray->getArray()[tri].norm.dotProduct( lightDir ); } if ( d > 0 ) { continue; } vec3_c& p0Projected = pointsTransformed[vi0]; if ( bPointTransformed[vi0] == 0 ) { bPointTransformed[vi0] = 1; p0Projected = p0 - delta; } vec3_c& p1Projected = pointsTransformed[vi1]; if ( bPointTransformed[vi1] == 0 ) { bPointTransformed[vi1] = 1; p1Projected = p1 - delta; } vec3_c& p2Projected = pointsTransformed[vi2]; if ( bPointTransformed[vi2] == 0 ) { bPointTransformed[vi2] = 1; p2Projected = p2 - delta; } u32 i0 = this->registerPoint( p0 ); u32 i1 = this->registerPoint( p1 ); u32 i2 = this->registerPoint( p2 ); u32 pi0 = this->registerPoint( p0Projected ); u32 pi1 = this->registerPoint( p1Projected ); u32 pi2 = this->registerPoint( p2Projected ); #ifdef OPTIMIZE_SLOW_ADDTRIANGLE ADD_TRIANGLE( pNextIndex, i2, i1, i0 ); ADD_TRIANGLE( pNextIndex, pi0, pi1, pi2 ); ADD_QUAD( pNextIndex, i0, i1, pi0, pi1 ); ADD_QUAD( pNextIndex, i1, i2, pi1, pi2 ); ADD_QUAD( pNextIndex, i2, i0, pi2, pi0 ); #else indices.addTriangle( i2, i1, i0 ); indices.addTriangle( pi0, pi1, pi2 ); c_capTriPairsAdded++; indices.addQuad( i0, i1, pi0, pi1 ); c_edgeQuadsAdded++; indices.addQuad( i1, i2, pi1, pi2 ); c_edgeQuadsAdded++; indices.addQuad( i2, i0, pi2, pi0 ); c_edgeQuadsAdded++; #endif } } #ifdef OPTIMIZE_SLOW_ADDTRIANGLE u32 numAddedIndices = pNextIndex - pFirstIndex; indices.forceSetIndexCount( indices.getNumIndices() + numAddedIndices ); #endif }