Scene& GlassModelExample::createScene(Scene& scene, const double aspectRatio)
{
	scene = createMaterials(scene);

	std::cout << "Creating scene..." << std::endl;

	Background* background = new GradientBackground(Color(1, 1, 1), Color(0.0, 0.0, 0.0));
	scene.setBackground(background);

	Transform Tcam =  Transform::Translate(0,-3,2) * Transform::RotateXdeg(80);
	Camera* camera = new PinholeCamera(aspectRatio);
	SimpleCameraMount* mount = new SimpleCameraMount(Tcam, camera);

	scene.setCameraMount(mount);

	scene.addElement(new Object(Transform::Translate(0,0,-1), GeoPtr(new Plane()), "white"));

	TriangleMesh *mesh = LoadASC("nudobult.asc", 0.02);
	if (mesh)
	{
		GeoPtr pMesh(mesh);
		scene.addElement(new Object(Transform::Translate(0,4,0.5) *Transform::RotateZdeg(15), pMesh, "glass"));
	}

 	SkyLight* skyLight = new SkyLight(0.5, Color(0.800, 0.930, 1));
 	skyLight->setSampling(4,16,0.05);
 	scene.addElement(skyLight);

	SphereAreaLight *areaLight = NULL;
	areaLight = new SphereAreaLight(Transform::Translate(-6,-2,7),1.0, Color(0.8,0.7,0.6), 1, true, SphereAreaLight::ATT_NONE);
	areaLight->setSampling(4,16);
	scene.addElement(areaLight);

	return scene;
}
Esempio n. 2
0
int main(int argc, char *argv[])
{

#   include "setRootCase.H"

#   include "createTime.H"
#   include "createMesh.H"

    pointMesh pMesh(mesh);

    pointVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        pMesh,
        dimensionedVector("fvmU", dimLength, vector::zero),
        pointPatchVectorField::calculatedType()
    );

    pointVectorField V(U + 2*U);

    Info<< "End\n" << endl;

    return 0;
}
Esempio n. 3
0
void LoadMeshes(FbxNode* pFbxNode, packed_freelist<Mesh>& sceneMeshes)
{
    // Material
    const uint32_t materialCount = pFbxNode->GetMaterialCount();
    for (uint32_t i = 0; i < materialCount; ++i) {
        FbxSurfaceMaterial* pFbxMaterial = pFbxNode->GetMaterial(i);
        if (pFbxMaterial && !pFbxMaterial->GetUserDataPtr()) {
            FbxAutoPtr<Material> pMaterial(new Material);
            if (pMaterial->init(pFbxMaterial)) {
                pFbxMaterial->SetUserDataPtr(pMaterial.Release());
            }
        }
    }

    FbxNodeAttribute* nodeAttribute = pFbxNode->GetNodeAttribute();
    if (nodeAttribute) {
        // Mesh
        if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) {
            FbxMesh* pFbxMesh = pFbxNode->GetMesh();
            if (pFbxMesh && !pFbxMesh->GetUserDataPtr()) {
                Mesh mesh;
                if (mesh.init(pFbxMesh)) {
                    sceneMeshes.insert(mesh);
                }
                // TODO:
                FbxAutoPtr<Mesh> pMesh(new Mesh);
                if (pMesh->init(pFbxMesh)) {
                    pFbxMesh->SetUserDataPtr(pMesh.Release());
                }
            }
        }
        // Light
        else if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) {
            FbxLight* pFbxLight = pFbxNode->GetLight();
            if (pFbxLight && !pFbxLight->GetUserDataPtr()) {
                FbxAutoPtr<Light> pLight(new Light);
                if (pLight->init(pFbxLight)) {
                    pFbxLight->SetUserDataPtr(pLight.Release());
                }
            }
        }
    }

    const int childCount = pFbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i) {
        LoadMeshes(pFbxNode->GetChild(i), sceneMeshes);
    }
}
    MeshWeakPtr	CMeshManager::CreateMesh(xst_castring& strName, const IInputLayout* pIL,  xst_castring& strGroupName)
    {
        bool bCreated = true;
        ResourceWeakPtr pRes;
        {
            //XSTSimpleProfiler2( "--GetOrCreateResource" );
        pRes = this->GetOrCreateResource( strName, strGroupName, &bCreated );//this->CreateResource( strName, strGroupName );
        }
        if( pRes.IsNull() )
        {
            return MeshWeakPtr();
        }

        MeshWeakPtr pMesh( pRes );
        pMesh->SetInputLayout( pIL );

        if( !bCreated )
        {
            return this->CloneMesh( pMesh, strGroupName );
        }

        return pMesh;
    }
Esempio n. 5
0
void Foam::Cloud<ParticleType>::calcCellWallFaces() const
{
    cellWallFacesPtr_.reset(new PackedBoolList(pMesh().nCells(), false));

    PackedBoolList& cellWallFaces = cellWallFacesPtr_();

    const polyBoundaryMesh& patches = polyMesh_.boundaryMesh();

    forAll(patches, patchi)
    {
        if (isA<wallPolyPatch>(patches[patchi]))
        {
            const polyPatch& patch = patches[patchi];

            const labelList& pFaceCells = patch.faceCells();

            forAll(pFaceCells, pFCI)
            {
                cellWallFaces[pFaceCells[pFCI]] = true;
            }
        }
    }
}
    MeshWeakPtr	CMeshManager::CreateMesh(xst_castring& strName, GroupWeakPtr pGroup)
    {
        //XSTSimpleProfiler();
        xst_assert( pGroup != xst_null, "(CMeshManager::CreateMesh)" );
        
        bool bCreated = true;
        ResourceWeakPtr pRes;
        //{ XSTSimpleProfiler2( "CMeshManager: get or create resource" );
        pRes = this->GetOrCreateResource( strName, pGroup, &bCreated );
        //}
        if( pRes.IsNull() )
        {
            return MeshWeakPtr();
        }

        MeshWeakPtr pMesh( pRes );

        if( !bCreated )
        {
            return this->CloneMesh( pMesh );
        }

        return pMesh;
    }
Esempio n. 7
0
void starMesh::writeMesh()
{
    if (isShapeMesh_)
    {
        Info<< "This is a shapeMesh." << endl;

        Info<< "Default patch type set to empty" << endl;

        clearExtraStorage();

        polyMesh pShapeMesh
        (
            IOobject
            (
                polyMesh::defaultRegion,
                runTime_.constant(),
                runTime_
            ),
            xferCopy(points_),           // we could probably re-use the data
            cellShapes_,
            boundary_,
            patchNames_,
            patchTypes_,
            defaultFacesName_,
            defaultFacesType_,
            patchPhysicalTypes_
        );

        Info<< "Writing polyMesh" << endl;
        pShapeMesh.write();
    }
    else
    {
        // This is a polyMesh.

        createPolyMeshData();

        Info<< "This is a polyMesh" << endl;

        clearExtraStorage();

        polyMesh pMesh
        (
            IOobject
            (
                polyMesh::defaultRegion,
                runTime_.constant(),
                runTime_
            ),
            xferCopy(points_),           // we could probably re-use the data
            xferCopy(meshFaces_),
            xferCopy(cellPolys_)
        );

        // adding patches also checks the mesh
        pMesh.addPatches(polyBoundaryPatches(pMesh));

        Info<< "Writing polyMesh" << endl;
        pMesh.write();
    }
}
void uniformInterpolatedDisplacementPointPatchVectorField::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (!interpolatorPtr_.valid())
    {
        interpolatorPtr_ = interpolationWeights::New
        (
            interpolationScheme_,
            timeVals_
        );
    }

    const pointMesh& pMesh = this->dimensionedInternalField().mesh();
    const Time& t = pMesh().time();

    // Update indices of times and weights
    bool timesChanged = interpolatorPtr_->valueWeights
    (
        t.timeOutputValue(),
        currentIndices_,
        currentWeights_
    );

    const wordList currentTimeNames
    (
        UIndirectList<word>(timeNames_, currentIndices_)
    );


    // Load if necessary fields for this interpolation
    if (timesChanged)
    {
        objectRegistry& fieldsCache = const_cast<objectRegistry&>
        (
            pMesh.thisDb().subRegistry("fieldsCache", true)
        );
        // Save old times so we now which ones have been loaded and need
        // 'correctBoundaryConditions'. Bit messy.
        HashSet<word> oldTimes(fieldsCache.toc());

        ReadFields<pointVectorField>
        (
            fieldName_,
            pMesh,
            currentTimeNames
        );

        forAllConstIter(objectRegistry, fieldsCache, fieldsCacheIter)
        {
            if (!oldTimes.found(fieldsCacheIter.key()))
            {
                // Newly loaded fields. Make sure the internal
                // values are consistent with the boundary conditions.
                // This is quite often not the case since these
                // fields typically are constructed 'by hand'

                const objectRegistry& timeCache = dynamic_cast
                <
                    const objectRegistry&
                >(*fieldsCacheIter());


                pointVectorField& d = const_cast<pointVectorField&>
                (
                    timeCache.lookupObject<pointVectorField>
                    (
                        fieldName_
                    )
                );
                d.correctBoundaryConditions();
            }
        }
    }


    // Interpolate the whole field
    pointVectorField result
    (
        uniformInterpolate<pointVectorField>
        (
            IOobject
            (
                word("uniformInterpolate(")
              + this->dimensionedInternalField().name()
              + ')',
                pMesh.time().timeName(),
                pMesh.thisDb(),
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            fieldName_,
            currentTimeNames,
            currentWeights_
        )
    );


    // Extract back from the internal field
    this->operator==
    (
        this->patchInternalField(result.dimensionedInternalField())
    );

    fixedValuePointPatchField<vector>::updateCoeffs();
}
Esempio n. 9
0
int main ( int argc, char* argv[] )
{
	const bool verbose = false;
	const int procRank = 0;
	const int numProcs = 1;
	const OutputMessage::priority loggingLevel = OutputMessage::debugPriority;
	
	Logger* exeLog = Logger::Instance(loggingLevel, procRank, numProcs);
	
	const double maxR = 1.0;
	
	double nInv[7];
	double interpMaxErr[7];
	double interpAvgErr[7];
	double gradMaxErr[7];
	double gradAvgErr[7];
	double lapMaxErr[7];
	double lapAvgErr[7];
	
	
	const int scalarDim = 1;
	const int vectorDim = 2;
	
	std::stringstream ss;
	std::string s;
	
	for ( int iNest = 1; iNest < 8; ++iNest )
	{
		//
		// construct a mesh to use for testing
		//
		PolyMesh2d pMesh( iNest, PolyMesh2d::triHexSeed, maxR, procRank, numProcs);
		std::cout << "iNest = " << iNest << ", nParticles = " << pMesh.nParticles() << ", nFaces = " << pMesh.nFaces() << std::endl;
		
		if ( verbose )
		{
			LongMessage meshStatus("planar mesh built", OutputMessage::tracePriority, "main", pMesh.getInfo() );
			exeLog->logMessage(meshStatus);
		}
		
		nInv[iNest-1] = 1.0/pMesh.nFaces();
		
		//
		// construct scalar field to use for testing
		//
		Field gaussScalar("Gaussian", "n/a", scalarDim, pMesh.nParticles() );
		Field exactGradient( "grad Gaussian", "n/a", vectorDim, pMesh.nParticles() );
		Field exactLaplacian( "laplacian Gaussian", "n/a", scalarDim, pMesh.nParticles() );
		Particles* pp = pMesh.getParticles();
		const double b = 8.0;
		for (int i = 0; i < pMesh.nParticles(); ++i)
		{
			double x = pp->x[i];
			double y = pp->y[i];
			double expPart = exp(- b*b * ( x*x + y*y ) );
			gaussScalar.insertScalarToField( i, expPart );
			
			exactGradient.insertVectorToField( i, -2.0 * b * b * x * expPart, - 2.0 * b * b * y * expPart );
			
			exactLaplacian.insertScalarToField(i, 4.0 * b * b * expPart * (-1.0 + b*b * ( x*x + y*y )) );
		}
		
		std::cout << "exact Fields defined... " << std::endl;
		
		ss.str(s);
		ss << "gaussScalar_nest_" << iNest << ".m";
		gaussScalar.outputForMatlab( ss.str(), *pp );
		
		std::cout << "source data output complete... " << std::endl;
		
		//
		// initialize interpolation
		//
		TriCubicHermite gaussScalarInterp( &pMesh, &gaussScalar);
		//
		// compute gradient estimates for Hermite interpolation, set interpolation coefficients
		//
		const double w1 = 2.0;
		const double w2 = 1.0;
		Field gaussGrad = gaussScalarInterp.estimateScalarGradientAtVertices(w1, w2);
		gaussScalarInterp.findAllCoefficientsScalar( gaussGrad );
		
		std::cout << "interpolation coefficients set... " << std::endl;
		//
		// interpolate
		//
		Field interpolatedScalar("GaussInterp", "n/a", scalarDim, pMesh.nParticles() );
		Field interpolatedGradient("GaussInterpGrad", "n/a", vectorDim, pMesh.nParticles() );
		Field interpolatedLaplacian("GaussInterpLaplacian", "n/a", scalarDim, pMesh.nParticles() );
		
		for ( int i = 0; i < pMesh.nParticles(); ++i)
		{
			xyzVector loc( pp->x[i], pp->y[i] );
			
			interpolatedScalar.insertScalarToField( i, gaussScalarInterp.interpolateScalar( loc ) );			
			
			interpolatedGradient.insertVectorToField(i, gaussScalarInterp.scalarGradient( loc ) );
			
			interpolatedLaplacian.insertScalarToField( i, gaussScalarInterp.scalarLaplacian( loc ) );
		}
		std::cout << "interpolation complete... calculating error ..." << std::endl;
		
		Field interpError("interpolation error", "n/a", scalarDim, pMesh.nParticles() );
		Field gradError( "gradient estimation error", "n/a", vectorDim, pMesh.nParticles() );
		Field lapError("laplacian error", "n/a", scalarDim, pMesh.nParticles() );
		
		interpMaxErr[iNest-1] = 0.0;
		interpAvgErr[iNest-1] = 0.0;
		gradMaxErr[iNest-1] = 0.0;
		gradAvgErr[iNest-1] = 0.0;
		lapMaxErr[iNest-1] = 0.0;
		lapAvgErr[iNest-1] = 0.0;
		double interpDenom = 0.0;
		double gradDenom = 0.0;
		double lapDenom = 0.0;
		double sMax = 0.0;
		double gMax = 0.0;
		double lMax = 0.0;
		for ( int i = 0; i < pMesh.nParticles(); ++i)
		{
			interpError.scalar[i] = interpolatedScalar.scalar[i] - gaussScalar.scalar[i]; 
			double errI = std::abs(interpError.scalar[i]);
			interpAvgErr[iNest-1] += errI * errI * pp->area[i];
			interpDenom += gaussScalar.scalar[i] * gaussScalar.scalar[i]  * pp->area[i];
			if ( gaussScalar.scalar[i] > sMax )
				sMax = gaussScalar.scalar[i];
			if (  errI > interpMaxErr[iNest-1] )
				interpMaxErr[iNest-1] = errI;
			
			gradError.xComp[i] = interpolatedGradient.xComp[i] - exactGradient.xComp[i];
			gradError.yComp[i] = interpolatedGradient.yComp[i] - exactGradient.yComp[i];
			double errG = std::sqrt( gradError.xComp[i]*gradError.xComp[i] + gradError.yComp[i]*gradError.yComp[i] );
			gradAvgErr[iNest-1] += errG * errG * pp->area[i];
			gradDenom += ( exactGradient.xComp[i]*exactGradient.xComp[i] + exactGradient.yComp[i]*exactGradient.yComp[i]) * pp->area[i];
			if ( std::sqrt( exactGradient.xComp[i]*exactGradient.xComp[i] + exactGradient.yComp[i]*exactGradient.yComp[i]) > gMax )
				gMax = std::sqrt( exactGradient.xComp[i]*exactGradient.xComp[i] + exactGradient.yComp[i]*exactGradient.yComp[i]);
			if ( errG > gradMaxErr[iNest-1] )
				gradMaxErr[iNest-1] = errG;
			
			lapError.scalar[i] = interpolatedLaplacian.scalar[i] - exactLaplacian.scalar[i];
			double errL = std::abs( lapError.scalar[i] );
			lapAvgErr[iNest-1] += errL * errL * pp->area[i];
			lapDenom += exactLaplacian.scalar[i] * exactLaplacian.scalar[i] * pp->area[i];
			if ( exactLaplacian.scalar[i] > lMax )
				lMax = exactLaplacian.scalar[i];
			if ( errL > lapMaxErr[iNest-1] )
				lapMaxErr[iNest-1] = errL;
		}
		interpMaxErr[iNest-1] /= sMax;
		gradMaxErr[iNest-1] /= gMax;
		lapMaxErr[iNest-1] /= lMax;
		interpAvgErr[iNest-1] /= interpDenom;
		gradAvgErr[iNest-1] /= gradDenom;
		lapAvgErr[iNest-1] /= lapDenom;
		
		interpAvgErr[iNest-1] = std::sqrt( interpAvgErr[iNest-1] );
		gradAvgErr[iNest-1] = std::sqrt( gradAvgErr[iNest-1] );
		lapAvgErr[iNest-1] = std::sqrt( lapAvgErr[iNest-1] );
		
		std::cout << "error complete ..." << std::endl;
		
		
		
		
	}
	
	std::cout << "--- 1/N --- " << " --- interp max err ---- " << " --- interp avg err ---- " 
								<< " --- grad max err --- " << " --- grad avg err --- "
								<< " --- lap max err --- " << " --- lap avg err --- " << std::endl;
	for ( int i = 0; i < 7; ++i )
		std::cout << nInv[i] << " , "
				  << interpMaxErr[i] << " , "
				  << interpAvgErr[i] << " , "
				  << gradMaxErr[i] << " , "
				  << gradAvgErr[i] << " , "
				  << lapMaxErr[i] << " , "
				  << lapAvgErr[i] << std::endl;


return 0;
};
Esempio n. 10
0
int main(int argc, char ** argv)
{
	//int numTargetSE;
    std::vector<int> numTargetByLayers;
	std::string numTargetByLayersStr;
	std::string catalog, indName, crdName, mtrName, levelBase;
	po::options_description desc("Program options");
    bool verbouse = false;
    std::vector<double> maxImbalance;
    std::string maxImbalanceStr;
	desc.add_options()
					("help,h", "print help message")
					("num-se,n", po::value<std::string>(&numTargetByLayersStr)->default_value("16"), "target numbers of SE by layers i.e. '64,8,2'")
					("work-dir,w", po::value<std::string>(&catalog)->default_value(""), "work catalog")
					("ind-file,i", po::value<std::string>(&indName)->default_value("ind.sba"), "ind file")
					("crd-file,c", po::value<std::string>(&crdName)->default_value("crd.sba"), "crd file")
					("mtr-file,m", po::value<std::string>(&mtrName)->default_value("mtr001.sba"), "mtr file")
					("level-base,l", po::value<std::string>(&levelBase)->default_value("level"), "level files base name")
                    ("verbouse,v", "make verbouse output")
                    ("max-imbalance", po::value<std::string>(&maxImbalanceStr)->default_value("1.3"), "target maximum imbalance in SE layers i.e. '1.4,1.3,1.3'. Low values of this parameters can couse program to fail.")
					;
	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if (vm.count("help") || vm.count("h")) { std::cout << desc << "\n"; return 1; }

    if (vm.count("verbouse") || vm.count("v")) verbouse = true;

	//extract number of SE by layers from cmd string
    std::stringstream sstr(numTargetByLayersStr);
    std::string entry;
    while(getline(sstr, entry, ','))
        numTargetByLayers.push_back(std::stoi(entry));

    //extract max imbalance of SE by layers from cmd string
    {
        std::stringstream sstr(maxImbalanceStr);
        while(getline(sstr, entry, ','))
            maxImbalance.push_back(std::stod(entry));
    }

    std::stringstream iName, cName, mName, lName/*, oiName, ocName, omName*/;
	iName << catalog << indName;
	cName << catalog << crdName;
	mName << catalog << mtrName;
	lName << catalog << levelBase;
	//Creating mesh
    std::unique_ptr<sbfMesh> pMesh(new sbfMesh());
    if(pMesh->readMeshFromFiles(iName.str().c_str(), cName.str().c_str(), mName.str().c_str()))
    {std::cout << "error while mesh reading" << std::endl; return 1;}

	int numElems = pMesh->numElements();

	//Prepare zero level of SE - each SE contains only one regular element
    std::vector<int> regIndex;
	regIndex.resize(1);
	std::vector< std::vector<sbfSElement *> > selevels;
	selevels.resize(numTargetByLayers.size() + 1);
	selevels[0].reserve(numElems*10);
	for(int ct = 0; ct < numElems; ct++)
		selevels[0].push_back( new sbfSElement(pMesh.get(), ct));
	for(size_t ct = 0; ct < numTargetByLayers.size(); ct++){
        selevels[ct+1].reserve(numTargetByLayers[ct]*100);
		for(int ct1 = 0; ct1 < numTargetByLayers[ct]; ct1++)
			selevels[ct+1].push_back( new sbfSElement(pMesh.get(), ct1));
	}
	for(int ct = 0; ct < numElems; ct++){
		regIndex[0] = ct;
		selevels[0][ct]->setRegElemIndexes(regIndex);
	}

    generateLevels(selevels, numTargetByLayers, maxImbalance, verbouse);

	for(size_t ct = 0; ct < numTargetByLayers.size(); ct++){
		std::cout << "Level " << ct+1 << " contains " << selevels[ct+1].size() << std::endl;
		sbfSELevel level;
		level.setSize(selevels[ct].size());
		level.setLevelIndex(ct+1);
        for(size_t ctSE = 0; ctSE < selevels[ct].size(); ctSE++) level.setIndex(ctSE, selevels[ct][ctSE]->parent()->index());

		level.writeToFile(lName.str().c_str(), ct+1);
	}

	std::cout << "DONE" << std::endl;

	return 0;
}
Esempio n. 11
0
//////////////////////////////////////////////////////////////////////////
// buildBindPose
void MD5MeshLoader::buildBindPose( MdlNode* pNode, BcU32 iMesh )
{
	// Skin the mesh.
	MD5_Joint* pJoints = pJoint( 0 );
	MD5_Mesh* pMeshes = pMesh( iMesh );

	// This node is a mesh if we have 1 joint, skin if we have more.
	MdlMesh* pMesh = NULL;
	if( nJoints_ == 1 )
	{
		pNode->type( eNT_MESH );
		pMesh = pNode->pMeshObject();
		
	}
	else
	{
		pNode->type( eNT_SKIN );
		pMesh = pNode->pSkinObject();
	}
	// Add material.
	MdlMaterial Material;
	Material.default3d();
	Material.Name_ = pMeshes->Shader_;
	BcU32 iMaterial = pMesh->addMaterial( Material );

	// Add indices.
	for( BcU32 i = 0; i < pMeshes->nIndices_; ++i )
	{
		MdlIndex Index;
		Index.iMaterial_ = iMaterial;
		Index.iVertex_ = pMeshes->pIndices_[ i ];
		pMesh->addIndex( Index );
	}

	BcVec3d WeightPos;

	for ( BcU32 i = 0; i < pMeshes->nVerts_; ++i )
	{
		MD5_Vert* pMD5Vert = &pMeshes->pVerts_[ i ];
		BcVec3d Position( 0.0f, 0.0f, 0.0f );

		// Setup vertex.
		MdlVertex Vert;

		Vert.bUV_ = BcTrue;
		Vert.UV_.x( pMD5Vert->U_ );
		Vert.UV_.y( pMD5Vert->V_ );

		for ( BcU32 j = 0; j < 4; ++j )
		{
			Vert.Weights_[ j ] = 0.0f;
			Vert.iJoints_[ j ]  = 0;
		}

		// Get bind pose vertex.
		Vert.nWeights_ = 0;

		for ( BcU32 j = 0; j < pMD5Vert->nWeights_; ++j )
		{
			if ( j > 4 ) 
			{
				break;
			}

			BcU32 WeightIndex = pMD5Vert->WeightIndex_ + j;
			MD5_Weight* pMD5Weight = &pMeshes->pWeights_[ WeightIndex ];

			// Fix up a joint.
			MD5_Joint* pJoint = &pJoints[ pMD5Weight->JointID_ ];
			BcVec3d JointTran( pJoint->TX_, pJoint->TY_, pJoint->TZ_ );
			BcQuat JointRot( pJoint->QX_, pJoint->QY_, pJoint->QZ_, 0.0f );
			JointRot.calcFromXYZ();

			//
			const BcReal WeightVal = pMD5Weight->Weight_;

			WeightPos.set( pMD5Weight->X_, pMD5Weight->Y_, pMD5Weight->Z_ );

			JointRot.rotateVector( WeightPos );
			Position += ( WeightPos + JointTran ) * WeightVal;

			// Setup vertex indices and weights:
			Vert.iJoints_[ j ] = pMD5Weight->JointID_;
			Vert.Weights_[ j ] = WeightVal;
			Vert.nWeights_++;
		}

		// Correct weights.
		BcReal WeightTotal = 0.0f;

		for( BcU32 j = 0; j < Vert.nWeights_; ++j )
		{
			WeightTotal += Vert.Weights_[ j ];
		}

		for( BcU32 j = 0; j < Vert.nWeights_; ++j )
		{
			Vert.Weights_[ j ] = Vert.Weights_[ j ] / WeightTotal;
		}


		Vert.bPosition_ = BcTrue;
		Vert.Position_ = Position;

		pMesh->addVertex( Vert );
	}

	pMesh->sortIndicesByMaterial();
	pMesh->buildNormals();
	pMesh->buildTangents();

	// Setup AABB to be larger than the skin to account for motion.
	BcAABB AABB = pMesh->findAABB();

	AABB.min( AABB.min() * 1.5f );
	AABB.max( AABB.max() * 1.5f );

	pNode->aabb( AABB );

	// TODO: Refine into bone palettes properly.
}
Esempio n. 12
0
std::shared_ptr<Surface> LoadMesh(const char *file_name, float scale, const Vector3f& offset) {
	std::shared_ptr<Group> pMesh(new Group());

	FILE *fp;
	errno_t err = fopen_s(&fp, file_name, "r");
	char line[MESH_LINE_MAX];
	char delims[] = " ";
	char *type = NULL;
	char *param1 = NULL;
	char *param2 = NULL;
	char *param3 = NULL;
	char *next = NULL;

	float minX = std::numeric_limits<float>::infinity();
	float maxX = -std::numeric_limits<float>::infinity();
	float minY = std::numeric_limits<float>::infinity();
	float maxY = -std::numeric_limits<float>::infinity();
	float minZ = std::numeric_limits<float>::infinity();
	float maxZ = -std::numeric_limits<float>::infinity();

	if (err == 0) {
		std::vector<Point3f> positionList;

		while (fgets(line, MESH_LINE_MAX, fp) != NULL) {
			if (strlen(line) == 0 || line[0] == '#') {
				continue;
			}

			type = strtok_s(line, delims, &next);
			param1 = strtok_s(NULL, delims, &next);
			param2 = strtok_s(NULL, delims, &next);
			param3 = strtok_s(NULL, delims, &next);

			if (strcmp(type, "v") == 0) {          // A vertex
				float p1 = static_cast<float>(atof(param1)) * scale;
				float p2 = static_cast<float>(atof(param2)) * scale;
				float p3 = static_cast<float>(atof(param3)) * scale;

				p1 += offset.x;
				p2 += offset.y;
				p3 += offset.z;

				if (p1 < minX) minX = p1;
				if (p1 > maxX) maxX = p1;
				if (p2 < minY) minY = p2;
				if (p2 > maxY) maxY = p2;
				if (p3 < minZ) minZ = p3;
				if (p3 > maxZ) maxZ = p3;

				Point3f point(p1, p2, p3);
				positionList.push_back(point);
			}
			else if (strcmp(type, "f") == 0) {     // A face
				std::string face_str_1(param1);
				std::string face_str_2(param2);
				std::string face_str_3(param3);

				int vertexIndex1 = GetVertexIndexFromString(face_str_1);
				int vertexIndex2 = GetVertexIndexFromString(face_str_2);
				int vertexIndex3 = GetVertexIndexFromString(face_str_3);

				std::shared_ptr<Triangle> tri(new Triangle(positionList[vertexIndex1], positionList[vertexIndex2], positionList[vertexIndex3]));
				pMesh->AddObject(tri);
			}
			else {
				// Just ignore.
			}
		}

		// End of the file has been reached.
		fclose(fp);
	}
	else {
		perror("Error opening the mesh file");
		return nullptr;
	}

	Point3f center((minX + maxX) / 2.0f, (minY + maxY) / 2.0f, (minZ + maxZ) / 2.0f);
	float radius = (maxX - minX) > (maxY - minY) && (maxX - minX) > (maxZ - minZ) ? (maxX - minX) / 2.0f :
		(maxY - minY) > (maxZ - minZ) ? (maxY - minY) / 2.0f : (maxZ - minZ) / 2.0f;
	radius += 0.001f;

	pMesh->SetEnclosingSphere(center, radius);

	return pMesh;
}