MassSpringArbitrary<Real,TVector>::~MassSpringArbitrary ()
{
    delete1(mSprings);
    delete1(mAdjacent);
}
Exemplo n.º 2
0
 GridGraph2<Real>::~GridGraph2 ()
 {
     delete1( mVertices );
     delete1( mPath );
     delete1( mPending );
 }
Exemplo n.º 3
0
//----------------------------------------------------------------------------
void SceneBuilder::PackVertices (UniMaterialMesh* uniMesh, Mesh* maxMesh,
									std::vector<int>& faceIndexParts,
									PX2::Float3 *normalsAll)
{
	// 对Max的网格进行分割,(根据三角形顶点面的索引),将顶点数据打包进uniMesh。
	// 
	// uniMesh
	//		到打包到的UniMaterialMesh
	// maxMesh
	//		顶点数据来源
	// faceIndexParts
	//		从此获得面,再根据面获得顶点索引
	// normalsAll
	//		法线数据来源

	// 通过Set获取max中的顶点索引
	// Stl的set按照递增顺序插入元素
	std::set<int> vertexIndexs; // Set
	int i, j;
	for (i=0; i<(int)faceIndexParts.size(); i++)
	{
		Face &face = maxMesh->faces[faceIndexParts[i]];
		for (j = 0; j < 3; j++)
		{
			vertexIndexs.insert(face.v[j]);
		}
	}

	if (vertexIndexs.size() == 0)
		return;

	// vMap要足够大,去容纳可能的j,这依赖于Stl::set递增插入元素
	// vMap[k] == -1 表示max中的k顶点不在这个Phoenix网格中
	int indexMax = *vertexIndexs.rbegin();
	int *vMap = new1<int>(indexMax+1);// max vertex index -> Phoenix vertex index
	memset(vMap, 0xFF, (indexMax+1)*sizeof(int));

	uniMesh->VQuantity() = (int)vertexIndexs.size();
	uniMesh->VertexMap() = new1<PX2::Float3>(uniMesh->VQuantity());
	uniMesh->NormalMap() = new1<PX2::Float3>(uniMesh->VQuantity());

	std::set<int>::iterator iter = vertexIndexs.begin();
	for (i=0; i<(int)vertexIndexs.size(); i++, iter++)
	{
		j = *iter; // max vertex index
		vMap[j] = i; // max vertex index -> Phoenix vertex index

		(uniMesh->VertexMap()[i])[0] = maxMesh->verts[j].x;
		(uniMesh->VertexMap()[i])[1] = maxMesh->verts[j].y;
		(uniMesh->VertexMap()[i])[2] = maxMesh->verts[j].z;

		if (normalsAll)
			uniMesh->NormalMap()[i] = normalsAll[j];
	}

	// 建立Phoenix2网格,面的顶点索引
	uniMesh->FQuantity() = (int)faceIndexParts.size();
	uniMesh->Face() = new1<int>(3*uniMesh->FQuantity());
	for (i = 0; i < (int)faceIndexParts.size(); i++)
	{
		Face &face = maxMesh->faces[faceIndexParts[i]];
		for (j = 0; j < 3; j++)
		{
			uniMesh->Face()[3*i+j] = vMap[face.v[j]];
		}
	}
	delete1(vMap);
}
Exemplo n.º 4
0
//----------------------------------------------------------------------------
PX2::Movable *SceneBuilder::BuildMesh(INode *maxNode,
									 PX2::Node *relatParentOrEqualNode)
{
	// 将Max的三角形网格数据转换到一个或者更多的等价的Phoenix2三角形网格。
	//
	// maxNode:
	//		Max场景图中的Mesh节点。
	// relatParentOrEqualNode:
	//		在Phoenix2场景图系统中最新创建的父亲节点。
	// 返回在Phoenix2场景中指向新的孩子节点的指针,这个指针直接指向TriMesh物体;
	// 或者是一个“link”节点,“link”的多个孩子TriMesh代表Max中的多个孩子mesh。

	bool needDel = false;
	TriObject *triObject = GetTriObject(maxNode, &needDel);
	if (!triObject)
	{
		return 0;
	}

	Mesh *maxMesh = &triObject->GetMesh();

	Mtl *mtl = maxNode->GetMtl();
	int mtlIndex = mMtls.GetIndex(mtl);

	// 判断这个Max的几何图形节点是否有“子几何图形节点”,如果有子几何图形节点
	// isEqualNode为真,反之为假。
	// 如果名称相等,就不是relatParentOrEqualNode了,而是equalNode
	PX2::Movable *link = 0;
	bool isEqualNode = (relatParentOrEqualNode->GetName().length()>0 &&
		strcmp(maxNode->GetName(), 
		relatParentOrEqualNode->GetName().c_str()) == 0);

	// maxName
	char *maxName = maxNode->GetName();

	// 如果只需要一个Phoenix的Mesh表示Max的Mesh,直接将Phoenix的Mesh链接到
	// Phoenix的场景图中;否则,创建一个"link"节点,将按照材质分割的子Mesh
	// 放在"link"下。
	int i;
	std::vector<UniMaterialMesh*> uMeshs;
	SplitGeometry(maxMesh, mtlIndex, uMeshs);
	if ((int)uMeshs.size() > 1)
	{
		if (!isEqualNode)
		{
			link = BuildNode(maxNode, relatParentOrEqualNode);
		}
		else
		{
			link = relatParentOrEqualNode;
		}

		assertion(link->IsDerived(PX2::Node::TYPE), "link must be a Node.");

		for (i=0; i<(int)uMeshs.size(); i++)
		{
			PX2::TriMesh *triMesh = uMeshs[i]->ToTriMesh();

			if (triMesh)
			{
				char meshNumber[6];
				sprintf_s(meshNumber, 6, "_%d", i+1);
				size_t size = strlen(maxName) + strlen(meshNumber) + 1;
				char *tdName = new1<char>((int)size);
				strcpy_s(tdName, size, maxName);
				strcat_s(tdName, size, meshNumber);
				triMesh->SetName(tdName);
				delete1(tdName);
				((PX2::Node*)link)->AttachChild(triMesh);
			}
		}
	}
	else if ((int)uMeshs.size() == 1)
	{
		PX2::TriMesh *triMesh = uMeshs[0]->ToTriMesh();
		if (triMesh)
		{
			if (!isEqualNode)
			{
				triMesh->SetName(maxName);
				triMesh->LocalTransform = GetLocalTransform(maxNode, mTimeStart);
			}
			else
			{
				size_t size = strlen(maxName) + 3;
				char *tdName = new1<char>((int)size);
				strcpy_s(tdName, size, maxName);
				strcat_s(tdName, size, "_1");
				triMesh->SetName(tdName);
				delete1(tdName);
			}

			assertion(relatParentOrEqualNode->IsDerived(PX2::Node::TYPE), 
				"relatParentOrEqualNode must be a Node.");

			relatParentOrEqualNode->AttachChild(triMesh);
			link = triMesh;
		}
	}

	for (i=0; i<(int)uMeshs.size(); i++)
	{
		delete0(uMeshs[i]);
	}

	if (needDel)
	{
		delete0(triObject);
	}

	return link;
}
Exemplo n.º 5
0
//----------------------------------------------------------------------------
void WaterDropFormation::Configuration1 ()
{
    delete1(mTargets);
    mTargets = 0;

    const int numCtrlPoints = 14;
    const int degree = 2;
    delete1(mCtrlPoints);
    mCtrlPoints = new1<Vector2f>(numCtrlPoints);
    float* weights = new1<float>(numCtrlPoints);

    // spline
    mCtrlPoints[0] = mSpline->GetControlPoint(0);
    mCtrlPoints[1] = mSpline->GetControlPoint(1);
    mCtrlPoints[2] = 0.5f*(mSpline->GetControlPoint(1) +
        mSpline->GetControlPoint(2));
    mCtrlPoints[3] = mSpline->GetControlPoint(11);
    mCtrlPoints[4] = mSpline->GetControlPoint(12);

    // circle
    int i, j;
    for (i = 2, j = 5; i <= 10; ++i, ++j)
    {
        mCtrlPoints[j] = mSpline->GetControlPoint(i);
    }
    mCtrlPoints[5] = 0.5f*(mCtrlPoints[2] + mCtrlPoints[5]);
    mCtrlPoints[13] = mCtrlPoints[5];

    for (i = 0; i < numCtrlPoints; ++i)
    {
        weights[i] = 1.0f;
    }

    weights[ 6] = mSpline->GetControlWeight(3);
    weights[ 8] = mSpline->GetControlWeight(5);
    weights[10] = mSpline->GetControlWeight(7);
    weights[12] = mSpline->GetControlWeight(9);

    delete0(mSpline);
    mSpline = new0 NURBSCurve2f(5, mCtrlPoints, weights ,degree, false,
        true);

    // Restrict evaluation to a subinterval of the domain.
    mSpline->SetTimeInterval(0.5f, 1.0f);

    mWaterSurface->SetCurve(mSpline);

    mCircle = new0 NURBSCurve2f(9, &mCtrlPoints[5], &weights[5], degree,
        true, false);

    delete1(weights);

    // Restrict evaluation to a subinterval of the domain.  Why 0.375?  The
    // circle NURBS is a loop and not open.  The curve is constructed with
    // iDegree (2) replicated control points.  Although the curve is
    // geometrically symmetric about the vertical axis, it is not symmetric
    // in t about the half way point (0.5) of the domain [0,1].
    mCircle->SetTimeInterval(0.375f, 1.0f);

    // Create water drop.  The outside view value is set to 'false' because
    // the curve (x(t),z(t)) has the property dz/dt < 0.  If the curve
    // instead had the property dz/dt > 0, then 'true' is the correct value
    // for the outside view.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    mWaterDrop = new0 RevolutionSurface(mCircle, mCtrlPoints[9].X(),
        RevolutionSurface::REV_SPHERE_TOPOLOGY, 32, 16, false, false,
        vformat);
    mWaterDrop->SetEffectInstance(
        mWaterEffect->CreateInstance(mWaterTexture));

    mWaterRoot->AttachChild(mWaterDrop);
}
Exemplo n.º 6
0
//----------------------------------------------------------------------------
void SceneBuilder::SplitGeometry(Mesh *maxMesh, int mtlIndex, 
								 std::vector<UniMaterialMesh*> &uMeshes)
{
	// 如果这个Mesh有多个material并且使用两个或者多个material。这个网格需要
	// 被拆分,因为Phoenix2是一个物体只对应一个material。
	//
	// maxMesh:
	//		要分割的Max网格。
	// mtlIndex:
	//		材质ID
	// uMeshes:
	//		UniMaterialMesh集合,Max的mesh被拆分后放里面。

	int i, j;
	PX2::Float3 *normalsAll = 0;
	if (mSettings->IncludeNormals)
	{
		maxMesh->buildNormals();
		normalsAll = new1<PX2::Float3>(maxMesh->numVerts);
		for (i=0; i<maxMesh->numFaces; i++)
		{
			Face &face = maxMesh->faces[i];
			for (j=0; j<3; j++)
			{
				int vertexIndex = face.getVert(j);
				normalsAll[vertexIndex] = GetVertexNormal(maxMesh, i, vertexIndex);
			}
		}
	}

	// 没有材质
	if (mtlIndex < 0)
	{
		UniMaterialMesh *triMesh = new0 UniMaterialMesh;
		triMesh->SetMaterialInstance(PX2::VertexColor4Material::CreateUniqueInstance());

		std::vector<int> faceIndexs;
		int faceIndex = -1;
		for (faceIndex=0; faceIndex<maxMesh->numFaces; faceIndex++)
		{
			faceIndexs.push_back(faceIndex);
		}

		PackVertices(triMesh, maxMesh, faceIndexs, normalsAll);

		if (mSettings->IncludeVertexColors && maxMesh->numCVerts>0)
		{
			PackColors(triMesh, maxMesh, faceIndexs);
		}

		if (mSettings->IncludeTargentBiNormal && maxMesh->numTVerts>0)
		{
			triMesh->SetExportTargentBinormal(true);
		}
		else
		{
			triMesh->SetExportTargentBinormal(false);
		}

		if (mSettings->IncludeTexCoords && maxMesh->numTVerts>0)
		{
			triMesh->SetNumTexcoordToExport(mSettings->NumTexCoords);
			PackTextureCoords(triMesh, maxMesh, faceIndexs);
		}

		uMeshes.push_back(triMesh);

		triMesh->DuplicateGeometry();
	}
	else
	{
		// 获得Mtl的子材质数量
		MtlTree &tree = mMtlTreeList[mtlIndex];
		int subQuantity = 0; // 子材质数量
		if (mtlIndex >= 0)
		{
			subQuantity = tree.GetMChildQuantity();
		}

		// 计算几何图形所使用的最大附加材质索引
		int faceIndex, subID, maxSubID = -1;
		for (faceIndex=0; faceIndex<maxMesh->numFaces; faceIndex++)
		{
			subID = maxMesh->faces[faceIndex].getMatID();
			if (subID >= subQuantity)
			{
				if (subQuantity > 0)
				{
					subID = subID % subQuantity;
				}
				else
				{
					subID = 0;
				}
			}

			if (subID > maxSubID)
			{
				maxSubID = subID;
			}
		}

		// 根据material ID,将每个三角形面分类
		std::vector<int> *faceIndexPartByMtl = new1<std::vector<int> >(maxSubID+1);
		for (faceIndex=0; faceIndex<maxMesh->numFaces; faceIndex++)
		{
			subID = maxMesh->faces[faceIndex].getMatID();
			if (subID >= subQuantity)
			{
				if (subQuantity > 0)
				{
					subID = subID % subQuantity;
				}
				else
				{
					subID = 0;
				}
			}
			//  将每个面按照材质分类
			faceIndexPartByMtl[subID].push_back(faceIndex);
		}

		// 对每种材质类型,分配网格
		for (subID=0; subID<=maxSubID; subID++)
		{
			if (faceIndexPartByMtl[subID].size() == 0)
			{
				// 这种材质没有三角形面
				continue;
			}

			// 为每种材质新建一个mesh
			UniMaterialMesh *triMesh = new0 UniMaterialMesh;
			if (mtlIndex >= 0)
			{
				if (subQuantity > 0)
				{
					MtlTree &subtree = tree.GetMChild(subID);
					triMesh->SetShineProperty(subtree.GetShine());
					triMesh->SetMaterialInstance(subtree.GetMaterialInstance());
				}
				else
				{
					triMesh->SetShineProperty(tree.GetShine());
					triMesh->SetMaterialInstance(tree.GetMaterialInstance());
				}
			}

			PackVertices(triMesh, maxMesh, faceIndexPartByMtl[subID], normalsAll);

			if (mSettings->IncludeVertexColors && maxMesh->numCVerts>0)
			{
				PackColors(triMesh, maxMesh, faceIndexPartByMtl[subID]);
			}

			if (mSettings->IncludeTargentBiNormal && maxMesh->numTVerts>0)
			{
				triMesh->SetExportTargentBinormal(true);
			}
			else
			{
				triMesh->SetExportTargentBinormal(false);
			}

			if (mSettings->IncludeTexCoords && maxMesh->numTVerts>0)
			{
				triMesh->SetNumTexcoordToExport(mSettings->NumTexCoords);
				PackTextureCoords(triMesh, maxMesh, faceIndexPartByMtl[subID]);
			}

			uMeshes.push_back(triMesh);
		}

		delete1(faceIndexPartByMtl);

		for (i=0; i<(int)uMeshes.size(); i++)
		{
			uMeshes[i]->DuplicateGeometry();
		}
	}

	delete1(normalsAll);
}
Exemplo n.º 7
0
void ContEllipse2MinCR<Real>::MaxProduct (std::vector<Vector2<Real> >& A,
    Real D[2])
{
    // Keep track of which constraint lines have already been used in the
    // search.
    int numConstraints = (int)A.size();
    bool* used = new1<bool>(numConstraints);
    memset(used, 0, numConstraints*sizeof(bool));

    // Find the constraint line whose y-intercept (0,ymin) is closest to the
    // origin.  This line contributes to the convex hull of the constraints
    // and the search for the maximum starts here.  Also find the constraint
    // line whose x-intercept (xmin,0) is closest to the origin.  This line
    // contributes to the convex hull of the constraints and the search for
    // the maximum terminates before or at this line.
    int i, iYMin = -1;
    int iXMin = -1;
    Real axMax = (Real)0, ayMax = (Real)0;  // A[i] >= (0,0) by design
    for (i = 0; i < numConstraints; ++i)
    {
        // The minimum x-intercept is 1/A[iXMin].X() for A[iXMin].X() the
        // maximum of the A[i].X().
        if (A[i].X() > axMax)
        {
            axMax = A[i].X();
            iXMin = i;
        }

        // The minimum y-intercept is 1/A[iYMin].Y() for A[iYMin].Y() the
        // maximum of the A[i].Y().
        if (A[i].Y() > ayMax)
        {
            ayMax = A[i].Y();
            iYMin = i;
        }
    }
    assertion(iXMin != -1 && iYMin != -1, "Unexpected condition\n");
    WM5_UNUSED(iXMin);

    used[iYMin] = true;

    // The convex hull is searched in a clockwise manner starting with the
    // constraint line constructed above.  The next vertex of the hull occurs
    // as the closest point to the first vertex on the current constraint
    // line.  The following loop finds each consecutive vertex.
    Real x0 = (Real)0, xMax = ((Real)1)/axMax;
    int j;
    for (j = 0; j < numConstraints; ++j)
    {
        // Find the line whose intersection with the current line is closest
        // to the last hull vertex.  The last vertex is at (x0,y0) on the
        // current line.
        Real x1 = xMax;
        int line = -1;
        for (i = 0; i < numConstraints; ++i)
        {
            if (!used[i])
            {
                // This line not yet visited, process it.  Given current
                // constraint line a0*x+b0*y =1 and candidate line
                // a1*x+b1*y = 1, find the point of intersection.  The
                // determinant of the system is d = a0*b1-a1*b0.  We only
                // care about lines that have more negative slope than the
                // previous one, that is, -a1/b1 < -a0/b0, in which case we
                // process only lines for which d < 0.
                Real det = A[iYMin].DotPerp(A[i]);
                if (det < (Real)0)  // TO DO.  Need epsilon test here?
                {
                    // Compute the x-value for the point of intersection,
                    // (x1,y1).  There may be floating point error issues in
                    // the comparision 'D[0] <= fX1'.  Consider modifying to
                    // 'D[0] <= fX1+epsilon'.
                    D[0] = (A[i].Y() - A[iYMin].Y())/det;
                    if (x0 < D[0] && D[0] <= x1)
                    {
                        line = i;
                        x1 = D[0];
                    }
                }
            }
        }

        // Next vertex is at (x1,y1) whose x-value was computed above.  First
        // check for the maximum of x*y on the current line for x in [x0,x1].
        // On this interval the function is f(x) = x*(1-a0*x)/b0.  The
        // derivative is f'(x) = (1-2*a0*x)/b0 and f'(r) = 0 when
        // r = 1/(2*a0).  The three candidates for the maximum are f(x0),
        // f(r), and f(x1).  Comparisons are made between r and the end points
        // x0 and x1.  Since a0 = 0 is possible (constraint line is horizontal
        // and f is increasing on line), the division in r is not performed
        // and the comparisons are made between 1/2 = a0*r and a0*x0 or a0*x1.

        // Compare r < x0.
        if ((Real)0.5 < A[iYMin].X()*x0)
        {
            // The maximum is f(x0) since the quadratic f decreases for
            // x > r.
            D[0] = x0;
            D[1] = ((Real)1 - A[iYMin].X()*D[0])/A[iYMin].Y();  // = f(x0)
            break;
        }

        // Compare r < x1.
        if ((Real)0.5 < A[iYMin].X()*x1)
        {
            // The maximum is f(r).  The search ends here because the
            // current line is tangent to the level curve of f(x)=f(r)
            // and x*y can therefore only decrease as we traverse further
            // around the hull in the clockwise direction.
            D[0] = ((Real)0.5)/A[iYMin].X();
            D[1] = ((Real)0.5)/A[iYMin].Y();  // = f(r)
            break;
        }

        // The maximum is f(x1).  The function x*y is potentially larger
        // on the next line, so continue the search.
        assertion(line != -1, "Unexpected condition\n");
        x0 = x1;
        x1 = xMax;
        used[line] = true;
        iYMin = line;
    }

    assertion(j < numConstraints, "Unexpected condition\n");

    delete1(used);
}
Exemplo n.º 8
0
MeshCurvature<Real>::MeshCurvature (int numVertices,
    const Vector3<Real>* vertices, int numTriangles, const int* indices)
{
    mNumVertices = numVertices;
    mVertices = vertices;
    mNumTriangles = numTriangles;
    mIndices = indices;

    // Compute normal vectors.
    mNormals = new1<Vector3<Real> >(mNumVertices);
    memset(mNormals, 0, mNumVertices*sizeof(Vector3<Real>));
    int i, v0, v1, v2;
    for (i = 0; i < mNumTriangles; ++i)
    {
        // Get vertex indices.
        v0 = *indices++;
        v1 = *indices++;
        v2 = *indices++;

        // Compute the normal (length provides a weighted sum).
        Vector3<Real> edge1 = mVertices[v1] - mVertices[v0];
        Vector3<Real> edge2 = mVertices[v2] - mVertices[v0];
        Vector3<Real> normal = edge1.Cross(edge2);

        mNormals[v0] += normal;
        mNormals[v1] += normal;
        mNormals[v2] += normal;
    }
    for (i = 0; i < mNumVertices; ++i)
    {
        mNormals[i].Normalize();
    }

    // Compute the matrix of normal derivatives.
    Matrix3<Real>* DNormal = new1<Matrix3<Real> >(mNumVertices);
    Matrix3<Real>* WWTrn = new1<Matrix3<Real> >(mNumVertices);
    Matrix3<Real>* DWTrn = new1<Matrix3<Real> >(mNumVertices);
    bool* DWTrnZero = new1<bool>(mNumVertices);
    memset(WWTrn, 0, mNumVertices*sizeof(Matrix3<Real>));
    memset(DWTrn, 0, mNumVertices*sizeof(Matrix3<Real>));
    memset(DWTrnZero, 0, mNumVertices*sizeof(bool));

    int row, col;
    indices = mIndices;
    for (i = 0; i < mNumTriangles; ++i)
    {
        // Get vertex indices.
        int V[3];
        V[0] = *indices++;
        V[1] = *indices++;
        V[2] = *indices++;

        for (int j = 0; j < 3; j++)
        {
            v0 = V[j];
            v1 = V[(j+1)%3];
            v2 = V[(j+2)%3];

            // Compute edge from V0 to V1, project to tangent plane of vertex,
            // and compute difference of adjacent normals.
            Vector3<Real> E = mVertices[v1] - mVertices[v0];
            Vector3<Real> W = E - (E.Dot(mNormals[v0]))*mNormals[v0];
            Vector3<Real> D = mNormals[v1] - mNormals[v0];
            for (row = 0; row < 3; ++row)
            {
                for (col = 0; col < 3; ++col)
                {
                    WWTrn[v0][row][col] += W[row]*W[col];
                    DWTrn[v0][row][col] += D[row]*W[col];
                }
            }

            // Compute edge from V0 to V2, project to tangent plane of vertex,
            // and compute difference of adjacent normals.
            E = mVertices[v2] - mVertices[v0];
            W = E - (E.Dot(mNormals[v0]))*mNormals[v0];
            D = mNormals[v2] - mNormals[v0];
            for (row = 0; row < 3; ++row)
            {
                for (col = 0; col < 3; ++col)
                {
                    WWTrn[v0][row][col] += W[row]*W[col];
                    DWTrn[v0][row][col] += D[row]*W[col];
                }
            }
        }
    }

    // Add in N*N^T to W*W^T for numerical stability.  In theory 0*0^T gets
    // added to D*W^T, but of course no update is needed in the
    // implementation.  Compute the matrix of normal derivatives.
    for (i = 0; i < mNumVertices; ++i)
    {
        for (row = 0; row < 3; ++row)
        {
            for (col = 0; col < 3; ++col)
            {
                WWTrn[i][row][col] = ((Real)0.5)*WWTrn[i][row][col] +
                    mNormals[i][row]*mNormals[i][col];
                DWTrn[i][row][col] *= (Real)0.5;
            }
        }

        // Compute the max-abs entry of D*W^T.  If this entry is (nearly)
        // zero, flag the DNormal matrix as singular.
        Real maxAbs = (Real)0;
        for (row = 0; row < 3; ++row)
        {
            for (col = 0; col < 3; ++col)
            {
                Real absEntry = Math<Real>::FAbs(DWTrn[i][row][col]);
                if (absEntry > maxAbs)
                {
                    maxAbs = absEntry;
                }
            }
        }
        if (maxAbs < (Real)1e-07)
        {
            DWTrnZero[i] = true;
        }

        DNormal[i] = DWTrn[i]*WWTrn[i].Inverse();
    }

    delete1(WWTrn);
    delete1(DWTrn);

    // If N is a unit-length normal at a vertex, let U and V be unit-length
    // tangents so that {U, V, N} is an orthonormal set.  Define the matrix
    // J = [U | V], a 3-by-2 matrix whose columns are U and V.  Define J^T
    // to be the transpose of J, a 2-by-3 matrix.  Let dN/dX denote the
    // matrix of first-order derivatives of the normal vector field.  The
    // shape matrix is
    //   S = (J^T * J)^{-1} * J^T * dN/dX * J = J^T * dN/dX * J
    // where the superscript of -1 denotes the inverse.  (The formula allows
    // for J built from non-perpendicular vectors.) The matrix S is 2-by-2.
    // The principal curvatures are the eigenvalues of S.  If k is a principal
    // curvature and W is the 2-by-1 eigenvector corresponding to it, then
    // S*W = k*W (by definition).  The corresponding 3-by-1 tangent vector at
    // the vertex is called the principal direction for k, and is J*W.
    mMinCurvatures = new1<Real>(mNumVertices);
    mMaxCurvatures = new1<Real>(mNumVertices);
    mMinDirections = new1<Vector3<Real> >(mNumVertices);
    mMaxDirections = new1<Vector3<Real> >(mNumVertices);
    for (i = 0; i < mNumVertices; ++i)
    {
        // Compute U and V given N.
        Vector3<Real> U, V;
        Vector3<Real>::GenerateComplementBasis(U, V, mNormals[i]);

        if (DWTrnZero[i])
        {
            // At a locally planar point.
            mMinCurvatures[i] = (Real)0;
            mMaxCurvatures[i] = (Real)0;
            mMinDirections[i] = U;
            mMaxDirections[i] = V;
            continue;
        }

        // Compute S = J^T * dN/dX * J.  In theory S is symmetric, but
        // because we have estimated dN/dX, we must slightly adjust our
        // calculations to make sure S is symmetric.
        Real s01 = U.Dot(DNormal[i]*V);
        Real s10 = V.Dot(DNormal[i]*U);
        Real sAvr = ((Real)0.5)*(s01 + s10);
        Matrix2<Real> S
        (
            U.Dot(DNormal[i]*U), sAvr,
            sAvr, V.Dot(DNormal[i]*V)
        );

        // Compute the eigenvalues of S (min and max curvatures).
        Real trace = S[0][0] + S[1][1];
        Real det = S[0][0]*S[1][1] - S[0][1]*S[1][0];
        Real discr = trace*trace - ((Real)4.0)*det;
        Real rootDiscr = Math<Real>::Sqrt(Math<Real>::FAbs(discr));
        mMinCurvatures[i] = ((Real)0.5)*(trace - rootDiscr);
        mMaxCurvatures[i] = ((Real)0.5)*(trace + rootDiscr);

        // Compute the eigenvectors of S.
        Vector2<Real> W0(S[0][1], mMinCurvatures[i] - S[0][0]);
        Vector2<Real> W1(mMinCurvatures[i] - S[1][1], S[1][0]);
        if (W0.SquaredLength() >= W1.SquaredLength())
        {
            W0.Normalize();
            mMinDirections[i] = W0.X()*U + W0.Y()*V;
        }
        else
        {
            W1.Normalize();
            mMinDirections[i] = W1.X()*U + W1.Y()*V;
        }

        W0 = Vector2<Real>(S[0][1], mMaxCurvatures[i] - S[0][0]);
        W1 = Vector2<Real>(mMaxCurvatures[i] - S[1][1], S[1][0]);
        if (W0.SquaredLength() >= W1.SquaredLength())
        {
            W0.Normalize();
            mMaxDirections[i] = W0.X()*U + W0.Y()*V;
        }
        else
        {
            W1.Normalize();
            mMaxDirections[i] = W1.X()*U + W1.Y()*V;
        }
    }

    delete1(DWTrnZero);
    delete1(DNormal);
}
Exemplo n.º 9
0
void NaturalSpline3<Real>::CreateFreeSpline ()
{
    Real* dt = new1<Real>(mNumSegments);
    int i;
    for (i = 0; i < mNumSegments; ++i)
    {
        dt[i] = mTimes[i+1] - mTimes[i];
    }

    Real* d2t = new1<Real>(mNumSegments);
    for (i = 1; i < mNumSegments; ++i)
    {
        d2t[i] = mTimes[i+1] - mTimes[i-1];
    }

    Vector3<Real>* alpha = new1<Vector3<Real> >(mNumSegments);
    for (i = 1; i < mNumSegments; ++i)
    {
        Vector3<Real> numer = ((Real)3)*(dt[i-1]*mA[i+1] - d2t[i]*mA[i] +
            dt[i]*mA[i-1]);
        Real invDenom = ((Real)1)/(dt[i-1]*dt[i]);
        alpha[i] = invDenom*numer;
    }

    Real* ell = new1<Real>(mNumSegments + 1);
    Real* mu = new1<Real>(mNumSegments);
    Vector3<Real>* z = new1<Vector3<Real> >(mNumSegments + 1);
    Real inv;

    ell[0] = (Real)1;
    mu[0] = (Real)0;
    z[0] = Vector3<Real>::ZERO;
    for (i = 1; i < mNumSegments; ++i)
    {
        ell[i] = ((Real)2)*d2t[i] - dt[i-1]*mu[i-1];
        inv = ((Real)1)/ell[i];
        mu[i] = inv*dt[i];
        z[i] = inv*(alpha[i] - dt[i-1]*z[i-1]);
    }
    ell[mNumSegments] = (Real)1;
    z[mNumSegments] = Vector3<Real>::ZERO;

    mB = new1<Vector3<Real> >(mNumSegments);
    mC = new1<Vector3<Real> >(mNumSegments + 1);
    mD = new1<Vector3<Real> >(mNumSegments);

    mC[mNumSegments] = Vector3<Real>::ZERO;

    const Real oneThird = ((Real)1)/(Real)3;
    for (i = mNumSegments-1; i >= 0; --i)
    {
        mC[i] = z[i] - mu[i]*mC[i+1];
        inv = ((Real)1)/dt[i];
        mB[i] = inv*(mA[i+1] - mA[i]) - oneThird*dt[i]*(mC[i+1] +
            ((Real)2)*mC[i]);
        mD[i] = oneThird*inv*(mC[i+1] - mC[i]);
    }

    delete1(dt);
    delete1(d2t);
    delete1(alpha);
    delete1(ell);
    delete1(mu);
    delete1(z);
}
Exemplo n.º 10
0
MassSpringCurve<Real,TVector>::~MassSpringCurve ()
{
    delete1(mConstants);
    delete1(mLengths);
}
Exemplo n.º 11
0
void NaturalSpline3<Real>::CreateClosedSpline ()
{
    // TO DO.  A general linear system solver is used here.  The matrix
    // corresponding to this case is actually "cyclic banded", so a faster
    // linear solver can be used.  The current linear system code does not
    // have such a solver.

    Real* dt = new1<Real>(mNumSegments);
    int i;
    for (i = 0; i < mNumSegments; ++i)
    {
        dt[i] = mTimes[i+1] - mTimes[i];
    }

    // Construct matrix of system.
    GMatrix<Real> mat(mNumSegments + 1, mNumSegments + 1);
    mat[0][0] = (Real)1;
    mat[0][mNumSegments] = (Real)-1;
    for (i = 1; i <= mNumSegments-1; ++i)
    {
        mat[i][i-1] = dt[i-1];
        mat[i][i  ] = ((Real)2)*(dt[i-1] + dt[i]);
        mat[i][i+1] = dt[i];
    }
    mat[mNumSegments][mNumSegments - 1] = dt[mNumSegments - 1];
    mat[mNumSegments][0] = ((Real)2)*(dt[mNumSegments - 1] + dt[0]);
    mat[mNumSegments][1] = dt[0];

    // Construct right-hand side of system.
    mC = new1<Vector3<Real> >(mNumSegments + 1);
    mC[0] = Vector3<Real>::ZERO;
    Real inv0, inv1;
    for (i = 1; i <= mNumSegments-1; ++i)
    {
        inv0 = ((Real)1)/dt[i];
        inv1 = ((Real)1)/dt[i-1];
        mC[i] = ((Real)3)*(inv0*(mA[i+1] - mA[i]) - inv1*(mA[i] - mA[i-1]));
    }
    inv0 = ((Real)1)/dt[0];
    inv1 = ((Real)1)/dt[mNumSegments-1];
    mC[mNumSegments] = ((Real)3)*(inv0*(mA[1] - mA[0]) -
        inv1*(mA[0] - mA[mNumSegments-1]));

    // Solve the linear systems.
    Real* input = new1<Real>(mNumSegments + 1);
    Real* output = new1<Real>(mNumSegments + 1);

    for (i = 0; i <= mNumSegments; ++i)
    {
        input[i] = mC[i].X();
    }
    LinearSystem<Real>().Solve(mat, input, output);
    for (i = 0; i <= mNumSegments; ++i)
    {
        mC[i].X() = output[i];
    }

    for (i = 0; i <= mNumSegments; ++i)
    {
        input[i] = mC[i].Y();
    }
    LinearSystem<Real>().Solve(mat, input, output);
    for (i = 0; i <= mNumSegments; ++i)
    {
        mC[i].Y() = output[i];
    }

    for (i = 0; i <= mNumSegments; ++i)
    {
        input[i] = mC[i].Z();
    }
    LinearSystem<Real>().Solve(mat, input, output);
    for (i = 0; i <= mNumSegments; ++i)
    {
        mC[i].Z() = output[i];
    }

    delete1(input);
    delete1(output);
    // End linear system solving.

    const Real oneThird = ((Real)1)/(Real)3;
    mB = new1<Vector3<Real> >(mNumSegments);
    mD = new1<Vector3<Real> >(mNumSegments);
    for (i = 0; i < mNumSegments; ++i)
    {
        inv0 = ((Real)1)/dt[i];
        mB[i] = inv0*(mA[i+1] - mA[i]) - oneThird*(mC[i+1] +
            ((Real)2)*mC[i])*dt[i];
        mD[i] = oneThird*inv0*(mC[i+1] - mC[i]);
    }

    delete1(dt);
}
Exemplo n.º 12
0
void NaturalSpline3<Real>::CreateClampedSpline (
    const Vector3<Real>& derivativeStart, const Vector3<Real>& derivativeFinal)
{
    Real* dt = new1<Real>(mNumSegments);
    int i;
    for (i = 0; i < mNumSegments; ++i)
    {
        dt[i] = mTimes[i+1] - mTimes[i];
    }

    Real* d2t = new1<Real>(mNumSegments);
    for (i = 1; i < mNumSegments; ++i)
    {
        d2t[i] = mTimes[i+1] - mTimes[i-1];
    }

    Vector3<Real>* alpha = new1<Vector3<Real> >(mNumSegments + 1);
    Real inv = ((Real)1)/dt[0];
    alpha[0] = ((Real)3)*(inv*(mA[1] - mA[0]) - derivativeStart);
    inv = ((Real)1)/dt[mNumSegments-1];
    alpha[mNumSegments] = ((Real)3)*(derivativeFinal -
        inv*(mA[mNumSegments] - mA[mNumSegments-1]));
    for (i = 1; i < mNumSegments; ++i)
    {
        Vector3<Real> numer = ((Real)3)*(dt[i-1]*mA[i+1] - d2t[i]*mA[i] +
            dt[i]*mA[i-1]);
        Real invDenom = ((Real)1)/(dt[i-1]*dt[i]);
        alpha[i] = invDenom*numer;
    }

    Real* ell = new1<Real>(mNumSegments + 1);
    Real* mu = new1<Real>(mNumSegments);
    Vector3<Real>* z = new1<Vector3<Real> >(mNumSegments + 1);

    ell[0] = ((Real)2)*dt[0];
    mu[0] = (Real)0.5;
    inv = ((Real)1)/ell[0];
    z[0] = inv*alpha[0];

    for (i = 1; i < mNumSegments; ++i)
    {
        ell[i] = ((Real)2)*d2t[i] - dt[i-1]*mu[i-1];
        inv = ((Real)1)/ell[i];
        mu[i] = inv*dt[i];
        z[i] = inv*(alpha[i] - dt[i-1]*z[i-1]);
    }
    ell[mNumSegments] = dt[mNumSegments-1]*(((Real)2) - mu[mNumSegments-1]);
    inv = ((Real)1)/ell[mNumSegments];
    z[mNumSegments] = inv*(alpha[mNumSegments] - dt[mNumSegments-1]*
        z[mNumSegments-1]);

    mB = new1<Vector3<Real> >(mNumSegments);
    mC = new1<Vector3<Real> >(mNumSegments + 1);
    mD = new1<Vector3<Real> >(mNumSegments);

    mC[mNumSegments] = z[mNumSegments];

    const Real oneThird = ((Real)1)/(Real)3;
    for (i = mNumSegments-1; i >= 0; --i)
    {
        mC[i] = z[i] - mu[i]*mC[i+1];
        inv = ((Real)1)/dt[i];
        mB[i] = inv*(mA[i+1] - mA[i]) - oneThird*dt[i]*(mC[i+1] +
            ((Real)2)*mC[i]);
        mD[i] = oneThird*inv*(mC[i+1] - mC[i]);
    }

    delete1(dt);
    delete1(d2t);
    delete1(alpha);
    delete1(ell);
    delete1(mu);
    delete1(z);
}
Exemplo n.º 13
0
EigenDecomposition<Real>::~EigenDecomposition ()
{
    delete1(mDiagonal);
    delete1(mSubdiagonal);
}
Exemplo n.º 14
0
MinBox3<Real>::MinBox3 (int numPoints, const Vector3<Real>* points,
    Real epsilon, Query::Type queryType)
{
    // Get the convex hull of the points.
    ConvexHull3<Real> kHull(numPoints,(Vector3<Real>*)points, epsilon, false,
        queryType);
    int hullDim = kHull.GetDimension();

    if (hullDim == 0)
    {
        mMinBox.Center = points[0];
        mMinBox.Axis[0] = Vector3<Real>::UNIT_X;
        mMinBox.Axis[1] = Vector3<Real>::UNIT_Y;
        mMinBox.Axis[2] = Vector3<Real>::UNIT_Z;
        mMinBox.Extent[0] = (Real)0;
        mMinBox.Extent[1] = (Real)0;
        mMinBox.Extent[2] = (Real)0;
        return;
    }

    if (hullDim == 1)
    {
        ConvexHull1<Real>* pkHull1 = kHull.GetConvexHull1();
        const int* hullIndices = pkHull1->GetIndices();

        mMinBox.Center =
            ((Real)0.5)*(points[hullIndices[0]] + points[hullIndices[1]]);
        Vector3<Real> diff =
            points[hullIndices[1]] - points[hullIndices[0]];
        mMinBox.Extent[0] = ((Real)0.5)*diff.Normalize();
        mMinBox.Extent[1] = (Real)0;
        mMinBox.Extent[2] = (Real)0;
        mMinBox.Axis[0] = diff;
        Vector3<Real>::GenerateComplementBasis(mMinBox.Axis[1],
            mMinBox.Axis[2], mMinBox.Axis[0]);

        delete0(pkHull1);
        return;
    }

    int i, j;
    Vector3<Real> origin, diff, U, V, W;
    Vector2<Real>* points2;
    Box2<Real> box2;

    if (hullDim == 2)
    {
        // When ConvexHull3 reports that the point set is 2-dimensional, the
        // caller is responsible for projecting the points onto a plane and
        // calling ConvexHull2.  ConvexHull3 does provide information about
        // the plane of the points.  In this application, we need only
        // project the input points onto that plane and call ContMinBox in
        // two dimensions.

        // Get a coordinate system relative to the plane of the points.
        origin = kHull.GetPlaneOrigin();
        W = kHull.GetPlaneDirection(0).Cross(kHull.GetPlaneDirection(1));
        Vector3<Real>::GenerateComplementBasis(U, V, W);

        // Project the input points onto the plane.
        points2 = new1<Vector2<Real> >(numPoints);
        for (i = 0; i < numPoints; ++i)
        {
            diff = points[i] - origin;
            points2[i].X() = U.Dot(diff);
            points2[i].Y() = V.Dot(diff);
        }

        // Compute the minimum area box in 2D.
        box2 = MinBox2<Real>(numPoints, points2, epsilon, queryType, false);
        delete1(points2);

        // Lift the values into 3D.
        mMinBox.Center = origin + box2.Center.X()*U + box2.Center.Y()*V;
        mMinBox.Axis[0] = box2.Axis[0].X()*U + box2.Axis[0].Y()*V;
        mMinBox.Axis[1] = box2.Axis[1].X()*U + box2.Axis[1].Y()*V;
        mMinBox.Axis[2] = W;
        mMinBox.Extent[0] = box2.Extent[0];
        mMinBox.Extent[1] = box2.Extent[1];
        mMinBox.Extent[2] = (Real)0;
        return;
    }

    int hullQuantity = kHull.GetNumSimplices();
    const int* hullIndices = kHull.GetIndices();
    Real volume, minVolume = Math<Real>::MAX_REAL;

    // Create the unique set of hull vertices to minimize the time spent
    // projecting vertices onto planes of the hull faces.
    std::set<int> uniqueIndices;
    for (i = 0; i < 3*hullQuantity; ++i)
    {
        uniqueIndices.insert(hullIndices[i]);
    }

    // Use the rotating calipers method on the projection of the hull onto
    // the plane of each face.  Also project the hull onto the normal line
    // of each face.  The minimum area box in the plane and the height on
    // the line produce a containing box.  If its volume is smaller than the
    // current volume, this box is the new candidate for the minimum volume
    // box.  The unique edges are accumulated into a set for use by a later
    // step in the algorithm.
    const int* currentHullIndex = hullIndices;
    Real height, minHeight, maxHeight;
    std::set<EdgeKey> edges;
    points2 = new1<Vector2<Real> >(uniqueIndices.size());
    for (i = 0; i < hullQuantity; ++i)
    {
        // Get the triangle.
        int v0 = *currentHullIndex++;
        int v1 = *currentHullIndex++;
        int v2 = *currentHullIndex++;

        // Save the edges for later use.
        edges.insert(EdgeKey(v0, v1));
        edges.insert(EdgeKey(v1, v2));
        edges.insert(EdgeKey(v2, v0));

        // Get 3D coordinate system relative to plane of triangle.
        origin = (points[v0] + points[v1] + points[v2])/(Real)3.0;
        Vector3<Real> edge1 = points[v1] - points[v0];
        Vector3<Real> edge2 = points[v2] - points[v0];
        W = edge2.UnitCross(edge1);  // inner-pointing normal
        if (W == Vector3<Real>::ZERO)
        {
            // The triangle is needle-like, so skip it.
            continue;
        }
        Vector3<Real>::GenerateComplementBasis(U, V, W);

        // Project points onto plane of triangle, onto normal line of plane.
        // TO DO.  In theory, minHeight should be zero since W points to the
        // interior of the hull.  However, the snap rounding used in the 3D
        // convex hull finder involves loss of precision, which in turn can
        // cause a hull facet to have the wrong ordering (clockwise instead
        // of counterclockwise when viewed from outside the hull).  The
        // height calculations here trap that problem (the incorrectly ordered
        // face will not affect the minimum volume box calculations).
        minHeight = (Real)0;
        maxHeight = (Real)0;
        j = 0;
        std::set<int>::const_iterator iter = uniqueIndices.begin();
        while (iter != uniqueIndices.end())
        {
            int index = *iter++;
            diff = points[index] - origin;
            points2[j].X() = U.Dot(diff);
            points2[j].Y() = V.Dot(diff);
            height = W.Dot(diff);
            if (height > maxHeight)
            {
                maxHeight = height;
            }
            else if (height < minHeight)
            {
                minHeight = height;
            }

            j++;
        }
        if (-minHeight > maxHeight)
        {
            maxHeight = -minHeight;
        }

        // Compute minimum area box in 2D.
        box2 = MinBox2<Real>((int)uniqueIndices.size(), points2, epsilon,
            queryType, false);

        // Update current minimum-volume box (if necessary).
        volume = maxHeight*box2.Extent[0]*box2.Extent[1];
        if (volume < minVolume)
        {
            minVolume = volume;

            // Lift the values into 3D.
            mMinBox.Extent[0] = box2.Extent[0];
            mMinBox.Extent[1] = box2.Extent[1];
            mMinBox.Extent[2] = ((Real)0.5)*maxHeight;
            mMinBox.Axis[0] = box2.Axis[0].X()*U + box2.Axis[0].Y()*V;
            mMinBox.Axis[1] = box2.Axis[1].X()*U + box2.Axis[1].Y()*V;
            mMinBox.Axis[2] = W;
            mMinBox.Center = origin + box2.Center.X()*U + box2.Center.Y()*V
                + mMinBox.Extent[2]*W;
        }
    }

    // The minimum-volume box can also be supported by three mutually
    // orthogonal edges of the convex hull.  For each triple of orthogonal
    // edges, compute the minimum-volume box for that coordinate frame by
    // projecting the points onto the axes of the frame.
    std::set<EdgeKey>::const_iterator e2iter;
    for (e2iter = edges.begin(); e2iter != edges.end(); e2iter++)
    {
        W = points[e2iter->V[1]] - points[e2iter->V[0]];
        W.Normalize();

        std::set<EdgeKey>::const_iterator e1iter = e2iter;
        for (++e1iter; e1iter != edges.end(); e1iter++)
        {
            V = points[e1iter->V[1]] - points[e1iter->V[0]];
            V.Normalize();
            Real dot = V.Dot(W);
            if (Math<Real>::FAbs(dot) > Math<Real>::ZERO_TOLERANCE)
            {
                continue;
            }

            std::set<EdgeKey>::const_iterator e0iter = e1iter;
            for (++e0iter; e0iter != edges.end(); e0iter++)
            {
                U = points[e0iter->V[1]] - points[e0iter->V[0]];
                U.Normalize();
                dot = U.Dot(V);
                if (Math<Real>::FAbs(dot) > Math<Real>::ZERO_TOLERANCE)
                {
                    continue;
                }
                dot = U.Dot(W);
                if (Math<Real>::FAbs(dot) > Math<Real>::ZERO_TOLERANCE)
                {
                    continue;
                }
    
                // The three edges are mutually orthogonal.  Project the
                // hull points onto the lines containing the edges.  Use
                // hull point zero as the origin.
                Real umin = (Real)0, umax = (Real)0;
                Real vmin = (Real)0, vmax = (Real)0;
                Real wmin = (Real)0, wmax = (Real)0;
                origin = points[hullIndices[0]];

                std::set<int>::const_iterator iter = uniqueIndices.begin();
                while (iter != uniqueIndices.end())
                {
                    int index = *iter++;
                    diff = points[index] - origin;

                    Real fU = U.Dot(diff);
                    if (fU < umin)
                    {
                        umin = fU;
                    }
                    else if (fU > umax)
                    {
                        umax = fU;
                    }

                    Real fV = V.Dot(diff);
                    if (fV < vmin)
                    {
                        vmin = fV;
                    }
                    else if (fV > vmax)
                    {
                        vmax = fV;
                    }

                    Real fW = W.Dot(diff);
                    if (fW < wmin)
                    {
                        wmin = fW;
                    }
                    else if (fW > wmax)
                    {
                        wmax = fW;
                    }
                }

                Real uExtent = ((Real)0.5)*(umax - umin);
                Real vExtent = ((Real)0.5)*(vmax - vmin);
                Real wExtent = ((Real)0.5)*(wmax - wmin);

                // Update current minimum-volume box (if necessary).
                volume = uExtent*vExtent*wExtent;
                if (volume < minVolume)
                {
                    minVolume = volume;

                    mMinBox.Extent[0] = uExtent;
                    mMinBox.Extent[1] = vExtent;
                    mMinBox.Extent[2] = wExtent;
                    mMinBox.Axis[0] = U;
                    mMinBox.Axis[1] = V;
                    mMinBox.Axis[2] = W;
                    mMinBox.Center = origin +
                        ((Real)0.5)*(umin+umax)*U +
                        ((Real)0.5)*(vmin+vmax)*V +
                        ((Real)0.5)*(wmin+wmax)*W;
                }
            }
        }
    }

    delete1(points2);
}
Exemplo n.º 15
0
ExtremalQuery3BSP<Real>::~ExtremalQuery3BSP ()
{
    delete1(mNodes);
}
Exemplo n.º 16
0
//----------------------------------------------------------------------------
Castle::~Castle ()
{
	delete1(mCos);
	delete1(mSin);
	delete1(mTolerance);
}
Exemplo n.º 17
0
PolynomialFit2<Real>::~PolynomialFit2 ()
{
    delete1(mPowers);
    delete1(mXPowers);
    delete1(mCoefficients);
}
Exemplo n.º 18
0
void MeshSmoother<Real>::Destroy ()
{
    delete1(mNormals);
    delete1(mMeans);
    delete1(mNeighborCounts);
}
Exemplo n.º 19
0
//----------------------------------------------------------------------------
void WaterDropFormation::Configuration0 ()
{
    // Application loops between Configuration0() and Configuration1().
    // Delete all the objects from "1" when restarting with "0".
    delete1(mCtrlPoints);
    delete1(mTargets);
    delete0(mSpline);
    delete0(mCircle);
    mCircle = 0;
    mSimTime = 0.0f;
    mSimDelta = 0.05f;

    mWaterRoot->DetachChildAt(0);
    mWaterRoot->DetachChildAt(1);
    mWaterSurface = 0;
    mWaterDrop = 0;

    // Create water surface curve of revolution.
    const int numCtrlPoints = 13;
    const int degree = 2;
    mCtrlPoints = new1<Vector2f>(numCtrlPoints);
    mTargets = new1<Vector2f>(numCtrlPoints);
    int i;
    for (i = 0; i < numCtrlPoints; ++i)
    {
        mCtrlPoints[i] = Vector2f(0.125f + 0.0625f*i, 0.0625f);
    }

    float h = 0.5f;
    float d = 0.0625f;
    float extra = 0.1f;

    mTargets[ 0] = mCtrlPoints[ 0];
    mTargets[ 1] = mCtrlPoints[ 6];
    mTargets[ 2] = Vector2f(mCtrlPoints[6].X(), h - d - extra);
    mTargets[ 3] = Vector2f(mCtrlPoints[5].X(), h - d - extra);
    mTargets[ 4] = Vector2f(mCtrlPoints[5].X(), h);
    mTargets[ 5] = Vector2f(mCtrlPoints[5].X(), h + d);
    mTargets[ 6] = Vector2f(mCtrlPoints[6].X(), h + d);
    mTargets[ 7] = Vector2f(mCtrlPoints[7].X(), h + d);
    mTargets[ 8] = Vector2f(mCtrlPoints[7].X(), h);
    mTargets[ 9] = Vector2f(mCtrlPoints[7].X(), h - d - extra);
    mTargets[10] = Vector2f(mCtrlPoints[6].X(), h - d - extra);
    mTargets[11] = mCtrlPoints[ 6];
    mTargets[12] = mCtrlPoints[12];

    float* weights = new1<float>(numCtrlPoints);
    for (i = 0; i < numCtrlPoints; ++i)
    {
        weights[i] = 1.0f;
    }

    const float modWeight = 0.3f;
    weights[3] = modWeight;
    weights[5] = modWeight;
    weights[7] = modWeight;
    weights[9] = modWeight;

    mSpline = new0 NURBSCurve2f(numCtrlPoints, mCtrlPoints, weights, degree,
        false, true);

    // Restrict evaluation to a subinterval of the domain.
    mSpline->SetTimeInterval(0.5f, 1.0f);

    delete1(weights);

    // Create the water surface.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

    mWaterSurface = new0 RevolutionSurface(mSpline, mCtrlPoints[6].X(),
        RevolutionSurface::REV_DISK_TOPOLOGY, 32, 16, false, true, vformat);
    mWaterSurface->SetEffectInstance(
        mWaterEffect->CreateInstance(mWaterTexture));

    mWaterRoot->AttachChild(mWaterSurface);
    mWaterRoot->Update();
}