Unreal Engine 4 C++ Change StaticMeshComponent of AStaticMeshActor - c++

I am trying to change every Static Mesh Actor's Material property. I know I need to iterate over each Actor and find Static Mesh Component. However, I can not modify Material properly.
Here is my code,
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("START Modeling()"));
//Find Actor and change Material
UWorld* world = GetWorld();
//Material Path
FString matPath = "Material'/Game/StarterContent/Materials/M_Metal_Gold.M_Metal_Gold'";
//Material Instance
UMaterialInstanceConstant* material = Cast<UMaterialInstanceConstant>(StaticLoadObject(UMaterialInstanceConstant::StaticClass(), nullptr, *(matPath)));
//Iterate Every Static Mesh Actor
for (TActorIterator<AStaticMeshActor> ActorItr(world); ActorItr; ++ActorItr)
{
AStaticMeshActor *Mesh = *ActorItr;
//Just for Degbuging Purpose
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Actor: %s"), *(ActorItr->GetName())));
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Location: %s"), *(ActorItr->GetActorLocation().ToString())));
//Get Static Mesh Component
TArray<UStaticMeshComponent*> MaterialComps;
Mesh->GetComponents(MaterialComps);
//I get this code from community answer. I do not know how it works.
for (int32 Index = 0; Index != MaterialComps.Num(); ++Index)
{
UStaticMeshComponent* targetComp = MaterialComps[Index];
int32 mCnt = targetComp->GetNumMaterials();
for (int i = 0; i < mCnt; i++)
//This is the core code which actually changing material.
targetComp->SetMaterial(0, material);
}
}
Before
After
It is occurred to me because I am changing every actor by iteration.
However, It only change floor actor's material.

You are changing only the material with the index 0.
Change targetComp->SetMaterial(0, material); to targetComp->SetMaterial(i, material);. It should fix your problem.

Related

How could I create a rigid body from a triangle mesh in PhysX?

I have recently been working on a project that involves the PhysX library. I need to create a PxRigidDynamic actor from a triangle mesh. I saw the example that the documentation provided, but I have some issues with this method.
The issues that I had were mainly:
The object wasn't effected by gravity, and would just sit there and vibrate (Although, I have a feeling I did something else wrong)
From what I have read, to create a rigid body from a triangle mesh, the object needs to be kinematic. This then throws an error when I try to change the object's velocity.
Here is how I am currently creating the triangle mesh:
PhysX::PxTriangleMeshDesc meshDesc;
meshDesc.points.count = numVertices;
meshDesc.points.stride = sizeof(float) * 3;
meshDesc.points.data = vertices;
meshDesc.triangles.count = numIndices;
meshDesc.triangles.stride = 3 * sizeof(uint32_t);
meshDesc.triangles.data = indices;
PhysX::PxDefaultMemoryOutputStream writeBuffer;
PhysX::PxTriangleMeshCookingResult::Enum result;
bool status = cooking->cookTriangleMesh(meshDesc, writeBuffer, &result);
if (!status)
return false;
PhysX::PxDefaultMemoryInputData readBuffer(writeBuffer.getData(),
writeBuffer.getSize());
PhysX::PxTriangleMesh* triangleMesh =
physics->createTriangleMesh(readBuffer);
dynamicObject = physics->createRigidDynamic(PhysX::PxTransform(PhysX::PxVec3(0.0f)));
if (!dynamicObject)
return false;
dynamicObject->setMass(10.0f);
dynamicObject->setRigidBodyFlag(
PhysX::PxRigidBodyFlag::eKINEMATIC, true);
material = physics->createMaterial(0.5f, 0.5f, 0.6f);
if (!material)
return false;
shape = PhysX::PxRigidActorExt::createExclusiveShape(
*dynamicObject,
PhysX::PxTriangleMeshGeometry(triangleMesh,
PhysX::PxMeshScale(PhysX::PxVec3(scale.x, scale.y, scale.z))),
*material
);
if (!shape)
return false;
How can I solve these issues?
If this isn't possible, I would like to know how to convert a triangle mesh into a convex mesh.

opengl update model position while camera position not updated in time causes blinking (model fly out of view)

I rendered a scene having earth and a satellite. The position of the satellite is collected and updated by a thread. The position data is provided by an background calculation program.
// main.cpp
void CollectCraft(void)
{
SetupChannel();
int iFlag = 1;
while(iFlag > 0)
{
iFlag = CollectData();
Sleep(10);
}
CloseChannel();
}
int main(void)
{
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CollectCraft, 0, NULL, NULL); // in collect.cpp
RenderMainWindow(); // in render.cpp
return 1;
}
The CollectCraft function receives data from a background program. Once it receives any data, it stores in a double
// collect.cpp
double Craft_R[3] = {0.0};
...
int CollectData(void)
{
char chrMessage[255] = {0};
int iFlag = CollectSocket(&sListen, &sServer, chrMessage);
if (iFlag <= 0) return iFlag;
else
{
unsigned char i = 0, j = 0;
unsigned short usLength = 0;
for ( i = 0; i < dimCraft; i++)
{
for (j=0; j<3; j++)
{
memcpy(&Craft_R[j], &chrMessage[usLength], 8);
usLength += 8;
}
}
}
return iFlag;
}
I fixed my camera on one of the satellite (following it and staring at it). It updates its position and the view matrix according to the position of the satellite.
The satellite updated it's position according to the latest received data (I simply get it through a extern double Craft_R).
// render.cpp
extern double Craft_R[3]; // directly get latest satellite position data
...
RenderMainWindow()
{
...
while (!glfwWindowShouldClose(MainWindow))
{
glm::dmat4 view = camera.GetViewMatrix();
...
Sate1Pos = glm::dvec3(Craft_R[0], Craft_R[1], Craft_R[2]); // update satellite position
glm::dmat4 model_sate1(1.0);
model_sate1 = glm::translate(model_sate1, Sate1Pos);
...
switch (CameraPosID)
{
case 0:
camera.Focus(EarthPos);
break;
case 1:
camera.Focus(Sate1Pos); // update camera position
}
glfwSwapBuffers(MainWindow);
glfwPollEvents();
}
}
The problem is, the collection of the latest satellite position data always happens BETWEEN the update of the camera position and the update of the satellite position. It means my satellite flies to the latest position but my camera still stays at the last position. After glfwSwapBuffers(), the next while (!glfwWindowShouldClose(MainWindow)) will render the satellite far away out of the field of view of the camera. And it will last until the next while for the camera to update its position and get the satellite back to its field of view.
If the background program keeps sending the satellite position, the scene will render as if the satellite is blinking. And if the background program stops sending the satellite position, everything is ok and stable. If I control the background program to send the satellite position once, the satellite in the scene will blink one time and then remains stable.
My question is if there is a way to simultaneously update position of the camera and the satellite? Many thanks and sorry for my poor English since it is not my mother tongue.

Atached Actor Mesh dont stick to Parent Actor

Context:
I'm creating some Actors (Shields) using C++ in ActorComponent (ShieldComponent) which is attached to Actor (Ship).
When I move my Ship, Actors (Shields) stay in place on world (don't move with Ship).
What can be important: I don't call CreateShieldActor in Constructor, so I can't use ConstructorHelpers::FObjectFinder instead of StaticLoadObject/LoadObject to load Mesh/Material.
My C++ code for creation looks like this:
AShieldPart* UShieldComponent::CreateShieldActor(AActor* Owner, FString MeshName)
{
//Create Shield Actor
FVector Location = Owner->GetActorLocation();
FRotator Rotator(0, 0, 0);
FVector Scale(10, 10, 10);
FActorSpawnParameters SpawnInfo;
SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
SpawnInfo.Owner = Owner;
FTransform Transform(Rotator, Location, Scale);
UClass * MeshClass = AShieldPart::StaticClass();
AShieldPart* ShieldPart = GetWorld()->SpawnActor<AShieldPart>(MeshClass, Transform, SpawnInfo);
//Attach Mesh to Shield Actor
ShieldPart->AttachToActor(Owner, FAttachmentTransformRules(EAttachmentRule::KeepRelative, false));
//Set Mesh for Shield
ShieldPart->SetNewMesh(MeshName);
//Set Material
UMaterial* Material = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("/some/path")));
ShieldPart->MeshComponent->SetMaterial(0, Material);
return ShieldPart;
}
AShieldPart::AShieldPart()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
SetRootComponent(RootComponent);
MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
MeshComponent->SetupAttachment(RootComponent);
}
void AShieldPart::SetNewMesh(FString MeshName)
{
UStaticMesh* Mesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, *MeshName));
//UStaticMesh* Mesh = LoadObject<UStaticMesh>(nullptr, *MeshName);
MeshComponent->SetStaticMesh(Mesh);
MeshComponent->SetCollisionProfileName(TEXT("BlockAll"));
MeshComponent->SetNotifyRigidBodyCollision(true);
MeshComponent->SetSimulatePhysics(true);
MeshComponent->SetEnableGravity(false);
MeshComponent->RegisterComponent();
}
That it would be more interesting, when I create that Actors (Shields) using BP all works fine...
The solution turned out to be eliminating the USceneComponent as a RootElement. The main element must be UStaticMeshComponent, then it can attached to the parent element (Ship).
AShieldPart::AShieldPart()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Creating MeshComponent and attach to RootComponent
MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
RootComponent = MeshComponent;
MeshComponent->AttachToComponent(RootComponent, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true));
...

GamePlay3d engine won't show model imported from fbx

I am a newbie with gameplay3d and went through all tutorials, however I cant manage to display this simple(not much polygons and material) model that I encoded from Fbx. I checked the model with unity3D, and a closed source software that uses gameplay3d and all seems to fine. I guess I am missing some detail loading the scene.
This is the model file including also the original fbx file. I suspect if it has something to do with light
https://www.dropbox.com/sh/ohgpsfnkm3iv24s/AACApRcxwtbmpKu4_5nnp8rZa?dl=0
This is the class that loads the scene.
#include "Demo.h"
// Declare our game instance
Demo game;
Demo::Demo()
: _scene(NULL), _wireframe(false)
{
}
void Demo::initialize()
{
// Load game scene from file
Bundle* bundle = Bundle::create("KGN56AI30N.gpb");
_scene = bundle->loadScene();
SAFE_RELEASE(bundle);
// Get the box model and initialize its material parameter values and bindings
Camera* camera = Camera::createPerspective(45.0f, getAspectRatio(), 1.0f, 20.0f);
Node* cameraNode = _scene->addNode("camera");
// Attach the camera to a node. This determines the position of the camera.
cameraNode->setCamera(camera);
// Make this the active camera of the scene.
_scene->setActiveCamera(camera);
SAFE_RELEASE(camera);
// Move the camera to look at the origin.
cameraNode->translate(0,0, 10);
cameraNode->rotateX(MATH_DEG_TO_RAD(0.25f));
// Update the aspect ratio for our scene's camera to match the current device resolution
_scene->getActiveCamera()->setAspectRatio(getAspectRatio());
// Set the aspect ratio for the scene's camera to match the current resolution
_scene->getActiveCamera()->setAspectRatio(getAspectRatio());
Light* directionalLight = Light::createDirectional(Vector3::one());
_directionalLightNode = Node::create("directionalLight");
_directionalLightNode->setLight(directionalLight);
SAFE_RELEASE(directionalLight);
_scene->addNode(_directionalLightNode);
_scene->setAmbientColor(1.0, 1.0, 1.0);
_scene->visit(this, &Demo::initializeMaterials);
}
bool Demo::initializeMaterials(Node* node)
{
Model* model = dynamic_cast<Model*>(node->getDrawable());
if (model)
{
for(int i=0;i<model->getMeshPartCount();i++)
{
Material* material = model->getMaterial(i);
if(material)
{
// For this sample we will only bind a single light to each object in the scene.
MaterialParameter* colorParam = material->getParameter("u_directionalLightColor[0]");
colorParam->setValue(Vector3(0.75f, 0.75f, 0.75f));
MaterialParameter* directionParam = material->getParameter("u_directionalLightDirection[0]");
directionParam->setValue(Vector3(1, 1, 1));
}
}
}
return true;
}
void Demo::finalize()
{
SAFE_RELEASE(_scene);
}
void Demo::update(float elapsedTime)
{
// Rotate model
//_scene->findNode("box")->rotateY(MATH_DEG_TO_RAD((float)elapsedTime / 1000.0f * 180.0f));
}
void Demo::render(float elapsedTime)
{
// Clear the color and depth buffers
clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
// Visit all the nodes in the scene for drawing
_scene->visit(this, &Demo::drawScene);
}
bool Demo::drawScene(Node* node)
{
// If the node visited contains a drawable object, draw it
Drawable* drawable = node->getDrawable();
if (drawable)
drawable->draw(_wireframe);
return true;
}
void Demo::keyEvent(Keyboard::KeyEvent evt, int key)
{
if (evt == Keyboard::KEY_PRESS)
{
switch (key)
{
case Keyboard::KEY_ESCAPE:
exit();
break;
}
}
}
void Demo::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
switch (evt)
{
case Touch::TOUCH_PRESS:
_wireframe = !_wireframe;
break;
case Touch::TOUCH_RELEASE:
break;
case Touch::TOUCH_MOVE:
break;
};
}
I can't download your dropbox .fbx file. How many models do you have in the scene? Here's a simple way of doing what you want to do -- not optimal, but it'll get you started...
So first off, I can't see where in your code you actually assign a Shader to be used with the material. I use something like this:
material = model->setMaterial("Shaders/Animation/ADSVertexViewAnim.vsh", "Shaders/Animation/ADSVertexViewAnim.fsh");
You need to assign a Shader, and the above code will take the vertex and fragment shaders and use that when the object needs to be drawn.
I went about it a slightly different way by not loading the scene file automatically, but creating an empty scene and then extracting my model from the bundle and adding it to the scene manually. That way, I can see exactly what is happening and I'm in control of each step. GamePlay3D has some fancy property files, but use them only once you know how the process works manually..
Initially, I created a simple cube in a scene, and created a scene manually, and added the monkey to the node graph, as follows:
void GameMain::ExtractFromBundle()
{
/// Create a new empty scene.
_scene = Scene::create();
// Create the Model and its Node
Bundle* bundle = Bundle::create("res/monkey.gpb"); // Create the bundle from GPB file
/// Create the Cube
{
Mesh* meshMonkey = bundle->loadMesh("Character_Mesh"); // Load the mesh from the bundle
Model* modelMonkey = Model::create(meshMonkey);
Node* nodeMonkey = _scene->addNode("Monkey");
nodeMonkey->setTranslation(0,0,0);
nodeMonkey->setDrawable(modelMonkey);
}
}
Then I want to search the scene graph and only assign a material to the object that I want to draw (the monkey). Use this if you want to assign different materials to different objects manually...
bool GameMain::initializeScene(Node* node)
{
Material* material;
std::cout << node->getId() << std::endl;
// find the node in the scene
if (strcmp(node->getId(), "Monkey") != 0)
return false;
Model* model = dynamic_cast<Model*>(node->getDrawable());
if( !model )
return false;
material = model->setMaterial("Shaders/Animation/ADSVertexViewAnim.vsh", "Shaders/Animation/ADSVertexViewAnim.fsh");
material->getStateBlock()->setCullFace(true);
material->getStateBlock()->setDepthTest(true);
material->getStateBlock()->setDepthWrite(true);
// The World-View-Projection Matrix is needed to be able to see view the 3D world thru the camera
material->setParameterAutoBinding("u_worldViewProjectionMatrix", "WORLD_VIEW_PROJECTION_MATRIX");
// This matrix is necessary to calculate normals properly, but the WORLD_MATRIX would also work
material->setParameterAutoBinding("u_worldViewMatrix", "WORLD_VIEW_MATRIX");
material->setParameterAutoBinding("u_viewMatrix", "VIEW_MATRIX");
return true;
}
Now the object is ready to be drawn.... so I use these functions:
void GameMain::render(float elapsedTime)
{
// Clear the color and depth buffers
clear(CLEAR_COLOR_DEPTH, Vector4(0.0, 0.0, 0.0, 0.0), 1.0f, 0);
// Visit all the nodes in the scene for drawing
_scene->visit(this, &GameMain::drawScene);
}
bool GameMain::drawScene(Node* node)
{
// If the node visited contains a drawable object, draw it
Drawable* drawable = node->getDrawable();
if (drawable)
drawable->draw(_wireframe);
return true;
}
I use my own shaders, so I don't have to worry about Light and DirectionalLight and all that stuff. Once I can see the object, then I'll add dynamic lights, etc, but for starters, start simple.
Regards.

PhysX - simulate() never ends if GPU used

Im still working on physics system for simulating fluids. I rewrote my application to use PhysX 3.3.0 and to be more objective and now i have a problem which i cant resolve for like a week or two.
This is my initiation of PhysX Context:
void PhysXSPH::initContext(void){
static LogPxErrorCallback gLogPxErrorCallback;
static PxDefaultAllocator gDefaultAllocatorCallback;
mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gLogPxErrorCallback);
check(mFoundation, "PxFoundation creating failed!");
static PxProfileZoneManager *mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation);
check(mProfileZoneManager, "PxProfileZoneManager creation failed!");
bool recordMemoryAllocations = true;
mPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *mFoundation,
PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager );
check(mPhysics, "PxPhysics creating failed!");
PxRegisterParticles(*mPhysics);
if(!PxInitExtensions(*mPhysics)){
check(NULL, "PxInitExtensions failed!");
}
static PxSimulationFilterShader gDefaultFilterShader = PxDefaultSimulationFilterShader;
PxSceneDesc sceneDesc(mPhysics->getTolerancesScale());
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
if(!sceneDesc.cpuDispatcher){
mCpuDispatcher = PxDefaultCpuDispatcherCreate(4);
check(mCpuDispatcher, "PxDefaultCpuDispatcherCreate failed!");
sceneDesc.cpuDispatcher = mCpuDispatcher;
}
if(!sceneDesc.filterShader){
sceneDesc.filterShader = gDefaultFilterShader;
}
#ifdef PX_WINDOWS
PxCudaContextManagerDesc cudaContextManagerDesc;
mCudaContextManager = PxCreateCudaContextManager(*mFoundation, cudaContextManagerDesc, mProfileZoneManager);
if( mCudaContextManager ){
if( !mCudaContextManager->contextIsValid() ){
mCudaContextManager->release();
mCudaContextManager = NULL;
CLOG(ERROR, "physX")<<"Invalid CUDA context.";
exit(EXIT_FAILURE);
}
if(!sceneDesc.gpuDispatcher){
sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher();
}
CLOG(INFO, "physX")<<"CUDA context created.";
} else {
CLOG(ERROR, "physX")<<"Creating CUDA context manager failed.";
exit(EXIT_FAILURE);
}
#endif
mScene = mPhysics->createScene(sceneDesc);
check(mScene, "createScene failed!");
createScene(mScene);
}
and initiation of a physX scene but problem occures even with an empty scene:
void PhysXSPH::createScene(PxScene *mScene){
mScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0);
mScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f);
createPlanes(mScene);
createParticles(mScene);
CLOG(INFO, "physX") << "PhysX scene created.";
}
void PhysXSPH::createPlanes(PxScene *mScene){
PxMaterial* mMaterial = mPhysics->createMaterial(0.5,0.5,0.5);
//Create actors
//1) Create ground plane
PxReal d = 0.0f;
PxTransform pose = PxTransform(PxVec3(0.0f, 0, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)));
PxRigidStatic* plane = mPhysics->createRigidStatic(pose);
check(plane, "Creating plane failed!");
//create 4 more planes for aquarium
PxRigidStatic* plane2 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(-4.0f, 0.0, 0.0), PxVec3(1.0, 0.0, 0.0)), *mMaterial);
PxRigidStatic* plane3 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(4.0f, 0.0, 0.0), PxVec3(-1.0, 0.0, 0.0)), *mMaterial);
PxRigidStatic* plane4 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, -4.0f), PxVec3(0.0, 0.0, 1.0)), *mMaterial);
PxRigidStatic* plane5 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, 4.0f), PxVec3(0.0, 0.0, -1.0)), *mMaterial);
// create shape
PxShape* shape = plane->createShape(PxPlaneGeometry(), *mMaterial);
check(shape, "Creating shape failed!");
mScene->addActor(*plane);
PxShape* shape2 = plane2->createShape(PxPlaneGeometry(), *mMaterial);
check(shape2, "Creating shape failed!");
mScene->addActor(*plane2);
PxShape* shape3 = plane3->createShape(PxPlaneGeometry(), *mMaterial);
check(shape3, "Creating shape failed!");
mScene->addActor(*plane3);
PxShape* shape4 = plane4->createShape(PxPlaneGeometry(), *mMaterial);
check(shape4, "Creating shape failed!");
mScene->addActor(*plane4);
PxShape* shape5 = plane5->createShape(PxPlaneGeometry(), *mMaterial);
check(shape5, "Creating shape failed!");
mScene->addActor(*plane5);
}
void PhysXSPH::createParticles(PxScene *mScene){
// set immutable properties.
bool perParticleRestOffset = false;
//get data from scene model
int maxParticles = scene->getMaxParticles();
int xDim = scene->getXDim();
int yDim = scene->getYDim();
int zDim = scene->getZDim();
// create particle system in PhysX SDK
particleSystem = mPhysics->createParticleFluid(maxParticles, perParticleRestOffset);
check(particleSystem, "Creating particle system failed!");
particleSystem->setRestOffset(particleRadius);
particleSystem->setRestParticleDistance(particleRadius);
particleSystem->setParticleBaseFlag(PxParticleBaseFlag::eGPU,true);
// TODO set fluid parameters
// add particle system to scene, in case creation was successful
if (particleSystem)
mScene->addActor(*particleSystem);
indexes = new PxU32[maxParticles];
particle_positions = new PxVec3[maxParticles];
int index=0;
for(int x=0; x<xDim ;x++){
for(int y=0; y<yDim ;y++){
for(int z=0; z<zDim; z++){
indexes[index]=(PxU32)index;
int v=3*index;
particle_positions[index]=PxVec3((physx::PxReal)(scene->m_vPos[v]), (physx::PxReal)(scene->m_vPos[v+1]), (physx::PxReal)(scene->m_vPos[v+2]));
//CLOG(INFO, "physX")<<index<<"["<<particle_positions[index].x<<"; "<<particle_positions[index].y<<"; "<<particle_positions[index].z<<"]";
index++;
}
}
}
PxParticleCreationData particleCreationData;
particleCreationData.numParticles = maxParticles;
particleCreationData.indexBuffer = PxStrideIterator<const PxU32>(indexes);
particleCreationData.positionBuffer = PxStrideIterator<const PxVec3>(particle_positions);
// create particles in *PxParticleSystem* ps
bool success = particleSystem->createParticles(particleCreationData);
if(!success){
CLOG(ERROR, "physX")<<"Creating particles failed.";
exit(EXIT_FAILURE);
}
}
If code in the #ifdef PX_WINDOWS is commented, everything works fine. Fluid flows like it should. But when I try to use my GPU, application freezes on first fetchResult() invokation (simulate() method never finishes its job). I have no error log, it just freezes. It happens no matter if its DEBUG or RELEASE, and if it is 32 or 64 build.
I have a GeForce 560Ti. I use Physx SDK 3.3.0. I link (eg. on win64 debug build) vs:
opengl32.lib glew32.lib glfw3.lib PhysX3DEBUG_x64.lib
PhysX3CommonDEBUG_x64.lib PxTaskDEBUG.lib PhysX3ExtensionsDEBUG.lib
PhysXProfileSDKDEBUG.lib
using:
nvToolsExt64_1.dll PhysX3XHECKED_x64.dll PhysX3CommonCHECKED_x64.dll
PhysX3GpuCHECKED_x64.dll PhysX3GpuDEBUG_x64.dll
I tried to use different versions of .libs and add .dlls wanted by the application, but every set ended up with a freezing on fetchResult().
I have no idea where to look for mistakes. Everything looks fine. I'd be thankful for any help!
I know this is an old thread but I had the exact same problem when I switched from 3.2.5 to 3.3.0.
I did find a solution. The problem is that you initialize the extensions twice here. You are using PxCreateBasePhysics to create your SDK object which does some extra work in the background. Namely it calls PxInitExtensions if I'm not mistaken.
The fix is to just change the PxCreateBasePhysics function to the standard PxCreatePhysics call with the exact same arguments. This one doesn't do any additional setups behind the scene. Just leaving out the InitExtensions call might work as well but I have only tried the first idea.
It is an odd thing that this only causes the freeze if GPU is in use, maybe nVidia should look at it.