c-如何使用Nvidia Flex设置模拟



我已经通读了文档https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/flex/manual.html?ncid=afm-chs-44270&ranMID=44270&ranEAID=a1LgFw09t88&ranSiteID=a1LgFw09t88-TGVNs5HtsNwQmL1xZ5XT8A#粒子

但我仍然无法获得工作模拟。有没有我不知道的调试选项?

我从https://github.com/NVIDIAGameWorks/FleX

这是我的代码:

#pragma once
#include "FlexPhysics.h"
#include "NvFlex.h"
#include "NvFlexExt.h"
#include <iostream>
NvFlexBuffer* particleBuffer;
NvFlexBuffer* velocityBuffer;
NvFlexBuffer* phaseBuffer;
struct Vec4struct {
float x, y, z, w;
};
void MyErrorCallback(NvFlexErrorSeverity severity, const char* msg, const char* file, int line)
{
std::cout << "Flex: %s - %s:%dn" << msg << file << line << std::endl;
}

int n = 10000;
int main() {
NvFlexLibrary* library = NvFlexInit(120, MyErrorCallback);
// create new solver
NvFlexSolverDesc solverDesc;
NvFlexSetSolverDescDefaults(&solverDesc);
solverDesc.maxParticles = n;
solverDesc.maxDiffuseParticles = 0;
NvFlexSolver* solver = NvFlexCreateSolver(library, &solverDesc);
particleBuffer = NvFlexAllocBuffer(library, n, sizeof(Vec4struct), eNvFlexBufferHost);
velocityBuffer = NvFlexAllocBuffer(library, n, sizeof(Vec4struct), eNvFlexBufferHost);
phaseBuffer = NvFlexAllocBuffer(library, n, sizeof(int), eNvFlexBufferHost);
//set params
NvFlexParams p;
p.gravity[0] = -10.0f;
p.radius = 0.01f;
p.drag = 0.1f;
p.damping = 0.0f;
NvFlexSetParams(solver, &p);
//spawn particles
int particle_count = 6;
float particle_mass = 100;
//map buffers
Vec4struct* particles = (Vec4struct*)NvFlexMap(particleBuffer, eNvFlexMapWait);
Vec4struct* velocities = (Vec4struct*)NvFlexMap(velocityBuffer, eNvFlexMapWait);
int* phases = (int*)NvFlexMap(phaseBuffer, eNvFlexMapWait);
for (int i = 0; i < particle_count; ++i)
{
particles[i] = { i * 5.0f,0,0, 1.0f / particle_mass };
velocities[i] = { 0.0f,0.0f,0.0f};
phases[i] = NvFlexMakePhase(0, 1);
}
//unmap buffers
NvFlexUnmap(particleBuffer);
NvFlexUnmap(velocityBuffer);
NvFlexUnmap(phaseBuffer);
NvFlexSetParticles(solver, particleBuffer, NULL);
NvFlexSetVelocities(solver, velocityBuffer, NULL);
NvFlexSetPhases(solver, phaseBuffer, NULL);
float delta_time = 1 / 60.0f;
while (true)
{
//map buffers
Vec4struct* particles = (Vec4struct*)NvFlexMap(particleBuffer, eNvFlexMapWait);
Vec4struct* velocities = (Vec4struct*)NvFlexMap(velocityBuffer, eNvFlexMapWait);
int* phases = (int*)NvFlexMap(phaseBuffer, eNvFlexMapWait);
//"draw" particles
std::cout << "x:" << particles[0].x << " y:" << particles[0].y << " z:" << particles[0].z << std::endl;

//unmap buffers
NvFlexUnmap(particleBuffer);
NvFlexUnmap(velocityBuffer);
NvFlexUnmap(phaseBuffer);
// set active count
NvFlexSetActiveCount(solver, particle_count);
// tick
NvFlexUpdateSolver(solver, delta_time, 1, false);
// read back (async)
NvFlexGetParticles(solver, particleBuffer, NULL);
NvFlexGetVelocities(solver, velocityBuffer, NULL);
NvFlexGetPhases(solver, phaseBuffer, NULL);
}

NvFlexFreeBuffer(particleBuffer);
NvFlexFreeBuffer(velocityBuffer);
NvFlexFreeBuffer(phaseBuffer);
NvFlexDestroySolver(solver);
NvFlexShutdown(library);
return 0;
}

以下是一些输出:

x:0 y:0 z:0
x:0 y:0 z:0
x:0 y:0 z:0
x:0 y:0 z:0
x:0 y:0 z:0
x:0 y:0 z:0
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00274073 y:1.26542e+06 z:1.26542e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06
x:0.00550891 y:2.53083e+06 z:2.53083e+06

现在我希望粒子开始向右下落。我不确定我加载到particlebuffer中的数据是否正确,我该如何检查?所有的医生都说[foat x,float y,float z,inverse_mass]。我应该检查哪些参数?

我所能找到的缓冲区是:

/**
* Opaque type representing a data buffer, type and contents depends on usage, see NvFlexAllocBuffer()
*/
typedef struct NvFlexBuffer NvFlexBuffer;

你必须初始化所有的Flex参数,否则它就无法工作,我认为这是因为它们保存在一个结构中。

#pragma once
#include "FlexPhysics.h"
#include "NvFlex.h"
#include "NvFlexExt.h"
#include <iostream>
NvFlexBuffer* particleBuffer;
NvFlexBuffer* velocityBuffer;
NvFlexBuffer* phaseBuffer;
struct Vec4struct {
float x, y, z, w;
};
void MyErrorCallback(NvFlexErrorSeverity severity, const char* msg, const char* file, int line)
{
std::cout << "Flex: %s - %s:%dn" << msg << file << line << std::endl;
}
int n = 10000;
int main() {
NvFlexLibrary* library = NvFlexInit(120, MyErrorCallback);
// create new solver
NvFlexSolverDesc solverDesc;
NvFlexSetSolverDescDefaults(&solverDesc);
solverDesc.maxParticles = n;
solverDesc.maxDiffuseParticles = 0;
NvFlexSolver* solver = NvFlexCreateSolver(library, &solverDesc);
particleBuffer = NvFlexAllocBuffer(library, n, sizeof(Vec4struct), eNvFlexBufferHost);
velocityBuffer = NvFlexAllocBuffer(library, n, sizeof(Vec4struct), eNvFlexBufferHost);
phaseBuffer = NvFlexAllocBuffer(library, n, sizeof(int), eNvFlexBufferHost);
//set params
NvFlexParams p;
int numIterations = 2;                  //!< Number of solver iterations to perform per-substep
p.gravity[0] = 0;
p.gravity[1] = -10.0f;
p.gravity[2] = 0;                       //!< Constant acceleration applied to all particles
p.radius = 0.01;                        //!< The maximum interaction radius for particles
p.solidRestDistance = 0.005;            //!< The distance non-fluid particles attempt to maintain from each other, must be in the range (0, radius]
p.fluidRestDistance = 0.001;            //!< The distance fluid particles are spaced at the rest density, must be in the range (0, radius], for fluids this should generally be 50-70% of mRadius, for rigids this can simply be the same as the particle radius
// common params
p.dynamicFriction = 1;              //!< Coefficient of friction used when colliding against shapes
p.staticFriction = 1;               //!< Coefficient of static friction used when colliding against shapes
p.particleFriction = 1;             //!< Coefficient of friction used when colliding particles
p.restitution = 1;                  //!< Coefficient of restitution used when colliding against shapes, particle collisions are always inelastic
p.adhesion = 1;                     //!< Controls how strongly particles stick to surfaces they hit, default 0.0, range [0.0, +inf]
p.sleepThreshold = 1;               //!< Particles with a velocity magnitude < this threshold will be considered fixed
p.maxSpeed = 1000;                      //!< The magnitude of particle velocity will be clamped to this value at the end of each step
p.maxAcceleration = 1000;               //!< The magnitude of particle acceleration will be clamped to this value at the end of each step (limits max velocity change per-second), useful to avoid popping due to large interpenetrations
p.shockPropagation = 0;             //!< Artificially decrease the mass of particles based on height from a fixed reference point, this makes stacks and piles converge faster
p.dissipation = 1;                  //!< Damps particle velocity based on how many particle contacts it has
p.damping = 10;                     //!< Viscous drag force, applies a force proportional, and opposite to the particle velocity
// cloth params
p.wind[0] = 0;
p.wind[0] = 0;
p.wind[0] = 0;                      //!< Constant acceleration applied to particles that belong to dynamic triangles, drag needs to be > 0 for wind to affect triangles
p.drag = 1;                         //!< Drag force applied to particles belonging to dynamic triangles, proportional to velocity^2*area in the negative velocity direction
p.lift = 1;                         //!< Lift force applied to particles belonging to dynamic triangles, proportional to velocity^2*area in the direction perpendicular to velocity and (if possible), parallel to the plane normal
// fluid params
p.cohesion = 0.025;                     //!< Control how strongly particles hold each other together, default: 0.025, range [0.0, +inf]
p.surfaceTension = 0;               //!< Controls how strongly particles attempt to minimize surface area, default: 0.0, range: [0.0, +inf]    
p.viscosity = 1;                    //!< Smoothes particle velocities using XSPH viscosity
p.vorticityConfinement = 0;         //!< Increases vorticity by applying rotational forces to particles
p.anisotropyScale = 0;              //!< Control how much anisotropy is present in resulting ellipsoids for rendering, if zero then anisotropy will not be calculated, see NvFlexGetAnisotropy()
p.anisotropyMin = 0;                //!< Clamp the anisotropy scale to this fraction of the radius
p.anisotropyMax = 0;                //!< Clamp the anisotropy scale to this fraction of the radius
p.smoothing = 1;                    //!< Control the strength of Laplacian smoothing in particles for rendering, if zero then smoothed positions will not be calculated, see NvFlexGetSmoothParticles()
p.solidPressure = 0;                //!< Add pressure from solid surfaces to particles
p.freeSurfaceDrag = 0;              //!< Drag force applied to boundary fluid particles
p.buoyancy = 0;                     //!< Gravity is scaled by this value for fluid particles
// diffuse params
p.diffuseThreshold = 0;             //!< Particles with kinetic energy + divergence above this threshold will spawn new diffuse particles
p.diffuseBuoyancy = 0;              //!< Scales force opposing gravity that diffuse particles receive
p.diffuseDrag = 0;                  //!< Scales force diffuse particles receive in direction of neighbor fluid particles
p.diffuseBallistic = 0;             //!< The number of neighbors below which a diffuse particle is considered ballistic
p.diffuseLifetime = 0;              //!< Time in seconds that a diffuse particle will live for after being spawned, particles will be spawned with a random lifetime in the range [0, diffuseLifetime]
// collision params
p.collisionDistance = 0.01;         //!< Distance particles maintain against shapes, note that for robust collision against triangle meshes this distance should be greater than zero
p.particleCollisionMargin = 1;      //!< Increases the radius used during neighbor finding, this is useful if particles are expected to move significantly during a single step to ensure contacts aren't missed on subsequent iterations
p.shapeCollisionMargin = 0;         //!< Increases the radius used during contact finding against kinematic shapes
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
p.planes[i][j] = 0;
}
}                                       //!< Collision planes in the form ax + by + cz + d = 0
p.numPlanes = 0;                        //!< Num collision planes
p.relaxationMode = NvFlexRelaxationMode::eNvFlexRelaxationGlobal;   //!< How the relaxation is applied inside the solver
p.relaxationFactor = 1;                                             //!< Control the convergence rate of the parallel solver, default: 1, values greater than 1 may lead to instability
NvFlexSetParams(solver, &p);
//spawn particles
int particle_count = 6;
float particle_mass = 100;
//map buffers
Vec4struct* particles = (Vec4struct*)NvFlexMap(particleBuffer, eNvFlexMapWait);
Vec4struct* velocities = (Vec4struct*)NvFlexMap(velocityBuffer, eNvFlexMapWait);
int* phases = (int*)NvFlexMap(phaseBuffer, eNvFlexMapWait);
for (int i = 0; i < particle_count; ++i)
{
particles[i] = { i * 5.0f,0,0, 1.0f / particle_mass };
velocities[i] = { 0.0f,0.0f,0.0f };
phases[i] = NvFlexMakePhase(0, 1);
}
//unmap buffers
NvFlexUnmap(particleBuffer);
NvFlexUnmap(velocityBuffer);
NvFlexUnmap(phaseBuffer);
NvFlexSetParticles(solver, particleBuffer, NULL);
NvFlexSetVelocities(solver, velocityBuffer, NULL);
NvFlexSetPhases(solver, phaseBuffer, NULL);
float delta_time = 1 / 60.0f;
while (true)
{
//map buffers
Vec4struct* particles = (Vec4struct*)NvFlexMap(particleBuffer, eNvFlexMapWait);
Vec4struct* velocities = (Vec4struct*)NvFlexMap(velocityBuffer, eNvFlexMapWait);
int* phases = (int*)NvFlexMap(phaseBuffer, eNvFlexMapWait);
//"draw" particles
std::cout << "x:" << particles[0].x << " y:" << particles[0].y << " z:" << particles[0].z << std::endl;
//unmap buffers
NvFlexUnmap(particleBuffer);
NvFlexUnmap(velocityBuffer);
NvFlexUnmap(phaseBuffer);
// set active count
NvFlexSetActiveCount(solver, particle_count);
// tick
NvFlexUpdateSolver(solver, delta_time, 1, false);
// read back (async)
NvFlexGetParticles(solver, particleBuffer, NULL);
NvFlexGetVelocities(solver, velocityBuffer, NULL);
NvFlexGetPhases(solver, phaseBuffer, NULL);
}
NvFlexFreeBuffer(particleBuffer);
NvFlexFreeBuffer(velocityBuffer);
NvFlexFreeBuffer(phaseBuffer);
NvFlexDestroySolver(solver);
NvFlexShutdown(library);
return 0;
}

最新更新