diff --git a/binary/src/flex_renderer.cpp b/binary/src/flex_renderer.cpp index 2cbdf49..948d73f 100644 --- a/binary/src/flex_renderer.cpp +++ b/binary/src/flex_renderer.cpp @@ -187,9 +187,9 @@ IMesh* _build_cloth(int id, FlexRendererThreadData data) { void FlexRenderer::build_meshes(FlexSolver* flex, float diffuse_radius) { // Clear previous imeshes since they are being rebuilt destroy_meshes(); - update_water(); - update_cloth(); - update_diffuse(); + //update_water(); + //update_cloth(); + //update_diffuse(); int active_particles = flex->get_active_particles(); if (active_particles == 0) return; @@ -208,15 +208,15 @@ void FlexRenderer::build_meshes(FlexSolver* flex, float diffuse_radius) { ///// Water particles ///// FlexRendererThreadData water_data; water_data.view_projection_matrix = view_projection_matrix; - water_data.particle_positions = flex->get_parameter("smoothing") != 0 ? (Vector4D*)flex->get_host("particle_smooth") : (Vector4D*)flex->get_host("particle_pos"); - water_data.particle_phases = (int*)flex->get_host("particle_phase"); + water_data.particle_positions = flex->get_parameter("smoothing") != 0 ? flex->hosts.particle_smooth : (Vector4D*)flex->hosts.particle_pos; + water_data.particle_phases = flex->hosts.particle_phase; water_data.max_particles = active_particles; water_data.radius = flex->get_parameter("radius"); water_data.eye_pos = eye_pos; if (flex->get_parameter("anisotropy_scale") != 0) { // Should we do anisotropy calculations? - water_data.particle_ani0 = (Vector4D*)flex->get_host("particle_ani0"); - water_data.particle_ani1 = (Vector4D*)flex->get_host("particle_ani1"); - water_data.particle_ani2 = (Vector4D*)flex->get_host("particle_ani2"); + water_data.particle_ani0 = flex->hosts.particle_ani0; + water_data.particle_ani1 = flex->hosts.particle_ani1; + water_data.particle_ani2 = flex->hosts.particle_ani2; } else { water_data.particle_ani0 = nullptr; water_data.particle_ani1 = nullptr; @@ -235,10 +235,10 @@ void FlexRenderer::build_meshes(FlexSolver* flex, float diffuse_radius) { FlexRendererThreadData diffuse_data; diffuse_data.eye_pos = eye_pos; diffuse_data.view_projection_matrix = view_projection_matrix; - diffuse_data.particle_positions = (Vector4D*)flex->get_host("diffuse_pos"); + diffuse_data.particle_positions = flex->hosts.diffuse_pos; diffuse_data.max_particles = active_diffuse; diffuse_data.radius = flex->get_parameter("radius") / flex->get_parameter("diffuse_lifetime") * diffuse_radius; - diffuse_data.particle_ani0 = (Vector4D*)flex->get_host("diffuse_vel"); + diffuse_data.particle_ani0 = flex->hosts.diffuse_vel; for (int mesh_index = 0; mesh_index < ceil(active_diffuse / (float)MAX_PRIMATIVES); mesh_index++) { diffuse_queue.push_back(threads->enqueue(_build_diffuse, mesh_index, diffuse_data)); @@ -250,10 +250,10 @@ void FlexRenderer::build_meshes(FlexSolver* flex, float diffuse_radius) { if (active_triangles > 0) { // update thread data FlexRendererThreadData cloth_data; - cloth_data.particle_positions = (Vector4D*)flex->get_host("particle_pos"); + cloth_data.particle_positions = flex->hosts.particle_pos; cloth_data.max_particles = active_triangles; - cloth_data.particle_ani0 = (Vector4D*)flex->get_host("triangle_normals"); - cloth_data.particle_phases = (int*)flex->get_host("triangle_indices"); + cloth_data.particle_ani0 = flex->hosts.triangle_normals; + cloth_data.particle_phases = flex->hosts.triangle_indices; for (int mesh_index = 0; mesh_index < ceil(active_triangles / (float)MAX_PRIMATIVES); mesh_index++) { triangle_queue.push_back(threads->enqueue(_build_cloth, mesh_index, cloth_data)); @@ -290,19 +290,19 @@ void FlexRenderer::update_cloth() { // Renders water meshes void FlexRenderer::draw_water() { - //update_water(); + update_water(); for (IMesh* mesh : water_meshes) mesh->Draw(); }; void FlexRenderer::draw_diffuse() { - //update_diffuse(); + update_diffuse(); for (IMesh* mesh : diffuse_meshes) mesh->Draw(); }; void FlexRenderer::draw_cloth() { - //update_cloth(); + update_cloth(); for (IMesh* mesh : triangle_meshes) mesh->Draw(); }; diff --git a/binary/src/flex_solver.cpp b/binary/src/flex_solver.cpp index 76fc95e..7459370 100644 --- a/binary/src/flex_solver.cpp +++ b/binary/src/flex_solver.cpp @@ -3,20 +3,22 @@ #define MAX_COLLIDERS 8192 // source can't go over this number of props so.. might as well just have it as the limit -// Struct that holds FleX solver data -void FlexSolver::add_buffer(std::string name, int type, int count) { - NvFlexBuffer* buffer = NvFlexAllocBuffer(library, count, type, eNvFlexBufferHost); - buffers[name] = buffer; +template NvFlexBuffer* FlexBuffers::init(NvFlexLibrary* library, T** host, int count) { + NvFlexBuffer* buffer = NvFlexAllocBuffer(library, count, sizeof(T), eNvFlexBufferHost); // Initialize CPU buffer memory // this memory is automatically updated when 'NvFlexGet' is called - hosts[name] = NvFlexMap(buffer, eNvFlexMapWait); - memset(hosts[name], 0, type * count); + void* mapped = NvFlexMap(buffer, eNvFlexMapWait); + memset(mapped, 0, sizeof(T) * count); NvFlexUnmap(buffer); -}; -NvFlexBuffer* FlexSolver::get_buffer(std::string name) { - return buffers[name]; + buffers.push_back(buffer); + if (host != nullptr) *host = (T*)mapped; + return buffer; +} + +void FlexBuffers::destroy() { + for (NvFlexBuffer* buffer : buffers) NvFlexFreeBuffer(buffer); } //int diff = Max(n - copy_description->elementCount, 0); @@ -32,7 +34,7 @@ void FlexSolver::reset() { // clear diffuse NvFlexSetDiffuseParticles(solver, NULL, NULL, 0); - ((int*)hosts["diffuse_count"])[0] = 0; + hosts.diffuse_count[0] = 0; } void FlexSolver::reset_cloth() { @@ -50,7 +52,7 @@ int FlexSolver::get_active_triangles() { } int FlexSolver::get_active_diffuse() { - return ((int*)hosts["diffuse_count"])[0]; + return hosts.diffuse_count[0]; } int FlexSolver::get_max_particles() { @@ -65,24 +67,20 @@ int FlexSolver::get_max_contacts() { return solver_description.maxContactsPerParticle; } -inline void* FlexSolver::get_host(std::string name) { - return hosts[name]; -} - std::vector* FlexSolver::get_meshes() { return &meshes; } // Resets particle to base parameters void FlexSolver::set_particle(int index, Particle particle) { - ((Vector4D*)get_host("particle_pos"))[index] = particle.pos; - ((Vector*)get_host("particle_vel"))[index] = particle.vel; - ((int*)get_host("particle_phase"))[index] = particle.phase; - ((int*)get_host("particle_active"))[index] = index; - ((Vector4D*)get_host("particle_smooth"))[index] = particle.pos; - ((Vector4D*)get_host("particle_ani0"))[index] = Vector4D(0, 0, 0, 0); - ((Vector4D*)get_host("particle_ani1"))[index] = Vector4D(0, 0, 0, 0); - ((Vector4D*)get_host("particle_ani2"))[index] = Vector4D(0, 0, 0, 0); + hosts.particle_pos[index] = particle.pos; + hosts.particle_smooth[index] = particle.pos; + hosts.particle_vel[index] = particle.vel; + hosts.particle_phase[index] = particle.phase; + hosts.particle_active[index] = index; + hosts.particle_ani0[index] = Vector4D(0, 0, 0, 0); + hosts.particle_ani1[index] = Vector4D(0, 0, 0, 0); + hosts.particle_ani2[index] = Vector4D(0, 0, 0, 0); } void FlexSolver::add_particle(Particle particle) { @@ -105,14 +103,14 @@ void FlexSolver::add_cloth(Particle particle, Vector2D size) { desc.elementCount = 0; // ridiculous amount of buffers to map - int* triangle_indices = (int*)NvFlexMap(get_buffer("triangle_indices"), eNvFlexMapWait); - Vector4D* particle_pos = (Vector4D*)NvFlexMap(get_buffer("particle_pos"), eNvFlexMapWait); - Vector* particle_vel = (Vector*)NvFlexMap(get_buffer("particle_vel"), eNvFlexMapWait); - int* particle_phase = (int*)NvFlexMap(get_buffer("particle_phase"), eNvFlexMapWait); - int* particle_active = (int*)NvFlexMap(get_buffer("particle_active"), eNvFlexMapWait); - int* spring_indices = (int*)NvFlexMap(get_buffer("spring_indices"), eNvFlexMapWait); - float* spring_restlengths = (float*)NvFlexMap(get_buffer("spring_restlengths"), eNvFlexMapWait); - float* spring_stiffness = (float*)NvFlexMap(get_buffer("spring_stiffness"), eNvFlexMapWait); + int* triangle_indices = (int*)NvFlexMap(buffers.triangle_indices, eNvFlexMapWait); + Vector4D* particle_pos = (Vector4D*)NvFlexMap(buffers.particle_pos, eNvFlexMapWait); + Vector* particle_vel = (Vector*)NvFlexMap(buffers.particle_vel, eNvFlexMapWait); + int* particle_phase = (int*)NvFlexMap(buffers.particle_phase, eNvFlexMapWait); + int* particle_active = (int*)NvFlexMap(buffers.particle_active, eNvFlexMapWait); + int* spring_indices = (int*)NvFlexMap(buffers.spring_indices, eNvFlexMapWait); + float* spring_restlengths = (float*)NvFlexMap(buffers.spring_restlengths, eNvFlexMapWait); + float* spring_stiffness = (float*)NvFlexMap(buffers.spring_stiffness, eNvFlexMapWait); for (int y = 0; y < size.y; y++) { for (int x = 0; x < size.x; x++) { @@ -163,23 +161,23 @@ void FlexSolver::add_cloth(Particle particle, Vector2D size) { } } - NvFlexUnmap(get_buffer("triangle_indices")); - NvFlexUnmap(get_buffer("particle_pos")); - NvFlexUnmap(get_buffer("particle_vel")); - NvFlexUnmap(get_buffer("particle_phase")); - NvFlexUnmap(get_buffer("particle_active")); - NvFlexUnmap(get_buffer("spring_indices")); - NvFlexUnmap(get_buffer("spring_restlengths")); - NvFlexUnmap(get_buffer("spring_stiffness")); + NvFlexUnmap(buffers.triangle_indices); + NvFlexUnmap(buffers.particle_pos); + NvFlexUnmap(buffers.particle_vel); + NvFlexUnmap(buffers.particle_phase); + NvFlexUnmap(buffers.particle_active); + NvFlexUnmap(buffers.spring_indices); + NvFlexUnmap(buffers.spring_restlengths); + NvFlexUnmap(buffers.spring_stiffness); // Update particle information - NvFlexSetParticles(solver, get_buffer("particle_pos"), &desc); - NvFlexSetVelocities(solver, get_buffer("particle_vel"), &desc); - NvFlexSetPhases(solver, get_buffer("particle_phase"), &desc); - NvFlexSetActive(solver, get_buffer("particle_active"), &desc); + NvFlexSetParticles(solver, buffers.particle_pos, &desc); + NvFlexSetVelocities(solver, buffers.particle_vel, &desc); + NvFlexSetPhases(solver, buffers.particle_phase, &desc); + NvFlexSetActive(solver, buffers.particle_active, &desc); NvFlexSetActiveCount(solver, copy_particles.elementCount); - NvFlexSetDynamicTriangles(solver, get_buffer("triangle_indices"), NULL, copy_triangles.elementCount); - NvFlexSetSprings(solver, get_buffer("spring_indices"), get_buffer("spring_restlengths"), get_buffer("spring_stiffness"), copy_springs.elementCount); + NvFlexSetDynamicTriangles(solver, buffers.triangle_indices, NULL, copy_triangles.elementCount); + NvFlexSetSprings(solver, buffers.spring_indices, buffers.spring_restlengths, buffers.spring_stiffness, copy_springs.elementCount); } void FlexSolver::add_force_field(NvFlexExtForceField force_field) { @@ -191,32 +189,26 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { if (solver == nullptr) return false; // Update collision geometry - NvFlexCollisionGeometry* geometry = (NvFlexCollisionGeometry*)get_host("geometry"); - Vector4D* geometry_pos = (Vector4D*)get_host("geometry_pos"); - Vector4D* geometry_prevpos = (Vector4D*)get_host("geometry_prevpos"); - Vector4D* geometry_ang = (Vector4D*)get_host("geometry_quat"); - Vector4D* geometry_prevang = (Vector4D*)get_host("geometry_prevquat"); - int* geometry_flags = (int*)get_host("geometry_flags"); - + //NvFlexCollisionGeometry* geometry = (NvFlexCollisionGeometry*)get_host("geometry"); for (int i = 0; i < meshes.size(); i++) { FlexMesh mesh = meshes[i]; - geometry_flags[i] = mesh.get_flags(); - geometry[i].triMesh.mesh = mesh.get_id(); - geometry[i].triMesh.scale[0] = 1; - geometry[i].triMesh.scale[1] = 1; - geometry[i].triMesh.scale[2] = 1; + hosts.geometry_flags[i] = mesh.get_flags(); + hosts.geometry[i].triMesh.mesh = mesh.get_id(); + hosts.geometry[i].triMesh.scale[0] = 1; + hosts.geometry[i].triMesh.scale[1] = 1; + hosts.geometry[i].triMesh.scale[2] = 1; - geometry[i].convexMesh.mesh = mesh.get_id(); - geometry[i].convexMesh.scale[0] = 1; - geometry[i].convexMesh.scale[1] = 1; - geometry[i].convexMesh.scale[2] = 1; + hosts.geometry[i].convexMesh.mesh = mesh.get_id(); + hosts.geometry[i].convexMesh.scale[0] = 1; + hosts.geometry[i].convexMesh.scale[1] = 1; + hosts.geometry[i].convexMesh.scale[2] = 1; - geometry_prevpos[i] = mesh.get_ppos(); - geometry_pos[i] = mesh.get_pos(); + hosts.geometry_prevpos[i] = mesh.get_ppos(); + hosts.geometry_pos[i] = mesh.get_pos(); - geometry_prevang[i] = mesh.get_pang(); - geometry_ang[i] = mesh.get_ang(); + hosts.geometry_prevang[i] = mesh.get_pang(); + hosts.geometry_ang[i] = mesh.get_ang(); meshes[i].update(); } @@ -226,19 +218,19 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { if (dt > 0 && get_active_particles() > 0) { // Map positions to CPU memory - Vector4D* particle_pos = (Vector4D*)NvFlexMap(get_buffer("particle_pos"), wait); + Vector4D* particle_pos = (Vector4D*)NvFlexMap(buffers.particle_smooth, wait); if (particle_pos) { if (particle_queue.empty()) { - NvFlexUnmap(get_buffer("particle_pos")); + NvFlexUnmap(buffers.particle_smooth); } else { // Add queued particles for (int i = 0; i < particle_queue.size(); i++) { int particle_index = copy_particles.elementCount + i; - particle_pos[particle_index] = particle_queue[i].pos; - //set_particle(particle_index, particle_queue[i]); + //particle_pos[particle_index] = particle_queue[i].pos; + set_particle(particle_index, particle_queue[i]); } - NvFlexUnmap(get_buffer("particle_pos")); + NvFlexUnmap(buffers.particle_smooth); // Only copy what we just added NvFlexCopyDesc desc; @@ -247,10 +239,10 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { desc.srcOffset = desc.dstOffset; // Update particle information - NvFlexSetParticles(solver, get_buffer("particle_pos"), &desc); - NvFlexSetVelocities(solver, get_buffer("particle_vel"), &desc); - NvFlexSetPhases(solver, get_buffer("particle_phase"), &desc); - NvFlexSetActive(solver, get_buffer("particle_active"), &desc); + NvFlexSetParticles(solver, buffers.particle_pos, &desc); + NvFlexSetVelocities(solver, buffers.particle_vel, &desc); + NvFlexSetPhases(solver, buffers.particle_phase, &desc); + NvFlexSetActive(solver, buffers.particle_active, &desc); NvFlexSetActiveCount(solver, get_active_particles()); copy_particles.elementCount += particle_queue.size(); @@ -263,12 +255,12 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { // write to device (async) NvFlexSetShapes( solver, - get_buffer("geometry"), - get_buffer("geometry_pos"), - get_buffer("geometry_quat"), - get_buffer("geometry_prevpos"), - get_buffer("geometry_prevquat"), - get_buffer("geometry_flags"), + buffers.geometry, + buffers.geometry_pos, + buffers.geometry_quat, + buffers.geometry_prevpos, + buffers.geometry_prevquat, + buffers.geometry_flags, meshes.size() ); NvFlexSetParams(solver, params); @@ -278,24 +270,24 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { NvFlexUpdateSolver(solver, dt, (int)get_parameter("substeps"), false); // read back (async) - NvFlexGetParticles(solver, get_buffer("particle_pos"), ©_particles); - NvFlexGetDiffuseParticles(solver, get_buffer("diffuse_pos"), get_buffer("diffuse_vel"), get_buffer("diffuse_count")); + NvFlexGetParticles(solver, buffers.particle_pos, ©_particles); + NvFlexGetDiffuseParticles(solver, buffers.diffuse_pos, buffers.diffuse_vel, buffers.diffuse_count); if (get_active_triangles() > 0) { - NvFlexGetNormals(solver, get_buffer("triangle_normals"), ©_particles); + NvFlexGetNormals(solver, buffers.triangle_normals, ©_particles); } if (get_parameter("anisotropy_scale") != 0) { - NvFlexGetAnisotropy(solver, get_buffer("particle_ani0"), get_buffer("particle_ani1"), get_buffer("particle_ani2"), ©_particles); + NvFlexGetAnisotropy(solver, buffers.particle_ani0, buffers.particle_ani1, buffers.particle_ani2, ©_particles); } if (get_parameter("smoothing") != 0) { - NvFlexGetSmoothParticles(solver, get_buffer("particle_smooth"), ©_particles); + NvFlexGetSmoothParticles(solver, buffers.particle_smooth, ©_particles); } if (get_parameter("reaction_forces") > 1) { - NvFlexGetVelocities(solver, get_buffer("particle_vel"), ©_particles); - NvFlexGetContacts(solver, get_buffer("contact_planes"), get_buffer("contact_vel"), get_buffer("contact_indices"), get_buffer("contact_count")); + NvFlexGetVelocities(solver, buffers.particle_vel, ©_particles); + NvFlexGetContacts(solver, buffers.contact_planes, buffers.contact_vel, buffers.contact_indices, buffers.contact_count); } force_field_queue.clear(); @@ -519,38 +511,38 @@ FlexSolver::FlexSolver(NvFlexLibrary* library, int particles) { param_map["reaction_forces"] = new float(1); // FleX GPU Buffers - add_buffer("particle_pos", sizeof(Vector4D), particles); - add_buffer("particle_vel", sizeof(Vector), particles); - add_buffer("particle_phase", sizeof(int), particles); - add_buffer("particle_active", sizeof(int), particles); - add_buffer("particle_smooth", sizeof(Vector4D), particles); - - add_buffer("geometry", sizeof(NvFlexCollisionGeometry), MAX_COLLIDERS); - add_buffer("geometry_pos", sizeof(Vector4D), MAX_COLLIDERS); - add_buffer("geometry_prevpos", sizeof(Vector4D), MAX_COLLIDERS); - add_buffer("geometry_quat", sizeof(Vector4D), MAX_COLLIDERS); - add_buffer("geometry_prevquat", sizeof(Vector4D), MAX_COLLIDERS); - add_buffer("geometry_flags", sizeof(int), MAX_COLLIDERS); - - add_buffer("contact_planes", sizeof(Vector4D), particles * get_max_contacts()); - add_buffer("contact_vel", sizeof(Vector4D), particles * get_max_contacts()); - add_buffer("contact_count", sizeof(int), particles); - add_buffer("contact_indices", sizeof(int), particles); - - add_buffer("particle_ani0", sizeof(Vector4D), particles); - add_buffer("particle_ani1", sizeof(Vector4D), particles); - add_buffer("particle_ani2", sizeof(Vector4D), particles); - - add_buffer("diffuse_pos", sizeof(Vector4D), solver_description.maxDiffuseParticles); - add_buffer("diffuse_vel", sizeof(Vector4D), solver_description.maxDiffuseParticles); - add_buffer("diffuse_count", sizeof(int), 1); // "this may be updated by the GPU which is why it is passed back in a buffer" - - add_buffer("triangle_indices", sizeof(int), particles * 3 * 2); // 3 indices per triangle, maximum of 2 triangles per particle - add_buffer("triangle_normals", sizeof(Vector4D), particles); // per-particle normals - - add_buffer("spring_indices", sizeof(int), particles * 2 * 2); // 2 spring indices, max of 2 springs per particle - add_buffer("spring_restlengths", sizeof(float), particles * 2); - add_buffer("spring_stiffness", sizeof(float), particles * 2); + buffers.particle_pos = buffers.init(library, &hosts.particle_pos, particles); + buffers.particle_vel = buffers.init(library, &hosts.particle_vel, particles); + buffers.particle_phase = buffers.init(library, &hosts.particle_phase, particles); + buffers.particle_active = buffers.init(library, &hosts.particle_active, particles); + buffers.particle_smooth = buffers.init(library, &hosts.particle_smooth, particles); + + buffers.geometry = buffers.init(library, &hosts.geometry, MAX_COLLIDERS); + buffers.geometry_pos = buffers.init(library, &hosts.geometry_pos, MAX_COLLIDERS); + buffers.geometry_prevpos = buffers.init(library, &hosts.geometry_prevpos, MAX_COLLIDERS); + buffers.geometry_quat = buffers.init(library, &hosts.geometry_ang, MAX_COLLIDERS); + buffers.geometry_prevquat = buffers.init(library, &hosts.geometry_prevang, MAX_COLLIDERS); + buffers.geometry_flags = buffers.init(library, &hosts.geometry_flags, MAX_COLLIDERS); + + buffers.contact_planes = buffers.init(library, &hosts.contact_planes, particles * get_max_contacts()); + buffers.contact_vel = buffers.init(library, &hosts.contact_vel, particles * get_max_contacts()); + buffers.contact_count = buffers.init(library, &hosts.contact_count, particles); + buffers.contact_indices = buffers.init(library, &hosts.contact_indices, particles); + + buffers.particle_ani0 = buffers.init(library, &hosts.particle_ani0, particles); + buffers.particle_ani1 = buffers.init(library, &hosts.particle_ani1, particles); + buffers.particle_ani2 = buffers.init(library, &hosts.particle_ani2, particles); + + buffers.diffuse_pos = buffers.init(library, &hosts.diffuse_pos, solver_description.maxDiffuseParticles); + buffers.diffuse_vel = buffers.init(library, &hosts.diffuse_vel, solver_description.maxDiffuseParticles); + buffers.diffuse_count = buffers.init(library, &hosts.diffuse_count, 1); // "this may be updated by the GPU which is why it is passed back in a buffer" + + buffers.triangle_indices = buffers.init(library, &hosts.triangle_indices, particles * 3 * 2); // 3 indices per triangle, maximum of 2 triangles per particle + buffers.triangle_normals = buffers.init(library, &hosts.triangle_normals, particles); // per-particle normals + + buffers.spring_indices = buffers.init(library, &hosts.spring_indices, particles * 2 * 2); // 2 spring indices, max of 2 springs per particle + buffers.spring_restlengths = buffers.init(library, &hosts.spring_restlengths, particles * 2); + buffers.spring_stiffness = buffers.init(library, &hosts.spring_stiffness, particles * 2); force_field_callback = NvFlexExtCreateForceFieldCallback(solver); }; @@ -572,8 +564,7 @@ FlexSolver::~FlexSolver() { NvFlexExtDestroyForceFieldCallback(force_field_callback); // Free buffers / hosts - for (std::pair buffer : buffers) - NvFlexFreeBuffer(buffer.second); + buffers.destroy(); NvFlexDestroySolver(solver); // bye bye solver solver = nullptr; diff --git a/binary/src/flex_solver.h b/binary/src/flex_solver.h index a90ba36..00704e5 100644 --- a/binary/src/flex_solver.h +++ b/binary/src/flex_solver.h @@ -17,6 +17,84 @@ struct Particle { int phase = 0; }; +// Holds flex buffer information +// TODO(?): Should this be defined as an std::pair, so the host and FleX buffers are always together? +struct FlexBuffers { + NvFlexBuffer* particle_pos; + NvFlexBuffer* particle_vel; + NvFlexBuffer* particle_phase; + NvFlexBuffer* particle_active; + NvFlexBuffer* particle_smooth; + + NvFlexBuffer* particle_ani0; + NvFlexBuffer* particle_ani1; + NvFlexBuffer* particle_ani2; + + NvFlexBuffer* geometry; + NvFlexBuffer* geometry_pos; + NvFlexBuffer* geometry_prevpos; + NvFlexBuffer* geometry_quat; + NvFlexBuffer* geometry_prevquat; + NvFlexBuffer* geometry_flags; + + NvFlexBuffer* contact_planes; + NvFlexBuffer* contact_vel; + NvFlexBuffer* contact_count; + NvFlexBuffer* contact_indices; + + NvFlexBuffer* diffuse_pos; + NvFlexBuffer* diffuse_vel; + NvFlexBuffer* diffuse_count; + + NvFlexBuffer* triangle_indices; + NvFlexBuffer* triangle_normals; + + NvFlexBuffer* spring_indices; + NvFlexBuffer* spring_restlengths; + NvFlexBuffer* spring_stiffness; + + std::vector buffers; + + template NvFlexBuffer* init(NvFlexLibrary* library, T** host, int count); + void destroy(); +}; + +// Holds CPU mapped NvFlexBuffer* data +struct FlexHosts { + Vector4D* particle_pos; + Vector* particle_vel; + int* particle_phase; + int* particle_active; + Vector4D* particle_smooth; + + Vector4D* particle_ani0; + Vector4D* particle_ani1; + Vector4D* particle_ani2; + + NvFlexCollisionGeometry* geometry; + Vector4D* geometry_pos; + Vector4D* geometry_prevpos; + Vector4D* geometry_ang; + Vector4D* geometry_prevang; + int* geometry_flags; + + Vector4D* contact_planes; + Vector4D* contact_vel; + int* contact_count; + int* contact_indices; + + Vector4D* diffuse_pos; + Vector4D* diffuse_vel; + int* diffuse_count; + + int* triangle_indices; + Vector4D* triangle_normals; + + int* spring_indices; + float* spring_restlengths; + float* spring_stiffness; +}; + // Struct that holds FleX solver data class FlexSolver { private: @@ -29,17 +107,15 @@ class FlexSolver { NvFlexCopyDesc copy_triangles = NvFlexCopyDesc(); NvFlexCopyDesc copy_springs = NvFlexCopyDesc(); NvFlexSolverDesc solver_description = NvFlexSolverDesc(); // stores stuff such as max particles - std::map buffers; std::map param_map; // TODO: figure out if this is the best way to do this... Would a set/get switch statement be better..? - std::map hosts; std::vector meshes; // physics meshes.. not visual! - std::vector particle_queue; // Doesnt actually hold particles. Just a queue + std::vector particle_queue; std::vector force_field_queue; - - void add_buffer(std::string name, int type, int count); - //NvFlexBuffer* get_buffer(std::string name); public: + FlexBuffers buffers; + FlexHosts hosts; + void reset(); void reset_cloth(); int get_active_particles(); @@ -50,9 +126,6 @@ class FlexSolver { int get_max_contacts(); std::vector* get_meshes(); - inline NvFlexBuffer* get_buffer(std::string name); - inline void* get_host(std::string name); // Returns a host (pointer of float4s) where FleX buffer data is transferred to. - void add_particle(Particle particle); void add_cloth(Particle particle, Vector2D size); void set_particle(int index, Particle particle); diff --git a/binary/src/main.cpp b/binary/src/main.cpp index 071ae60..46e79dc 100644 --- a/binary/src/main.cpp +++ b/binary/src/main.cpp @@ -399,7 +399,7 @@ LUA_FUNCTION(FLEXSOLVER_RenderParticles) { LUA->CheckType(2, Type::Function); FlexSolver* flex = GET_FLEXSOLVER(1); - Vector4D* host = (Vector4D*)flex->get_host("particle_smooth"); + Vector4D* host = flex->hosts.particle_smooth; for (int i = 0; i < flex->get_active_particles(); i++) { // render function LUA->Push(2); @@ -467,8 +467,8 @@ LUA_FUNCTION(FLEXSOLVER_ApplyContacts) { FlexSolver* flex = GET_FLEXSOLVER(1); if (flex->get_parameter("reaction_forces") < 2) return 0; // Coupling planes arent being generated.. bail - Vector4D* particle_pos = (Vector4D*)flex->get_host("particle_pos"); - Vector* particle_vel = (Vector*)flex->get_host("particle_vel"); + Vector4D* particle_pos = flex->hosts.particle_pos; + Vector* particle_vel = flex->hosts.particle_vel; /* Vector4D* contact_vel = (Vector4D*)flex->get_host("contact_vel"); Vector4D* contact_planes = (Vector4D*)flex->get_host("contact_planes"); @@ -480,11 +480,11 @@ LUA_FUNCTION(FLEXSOLVER_ApplyContacts) { //Vector* particle_vel = (Vector*)NvFlexMap(flex->get_buffer("particle_vel"), eNvFlexMapWait); // mapping planes stops random spazzing, but eats perf - Vector4D* contact_vel = (Vector4D*)NvFlexMap(flex->get_buffer("contact_vel"), eNvFlexMapWait); - Vector4D* contact_planes = (Vector4D*)NvFlexMap(flex->get_buffer("contact_planes"), eNvFlexMapWait); + Vector4D* contact_vel = (Vector4D*)NvFlexMap(flex->buffers.contact_vel, eNvFlexMapWait); + Vector4D* contact_planes = (Vector4D*)NvFlexMap(flex->buffers.contact_planes, eNvFlexMapWait); - int* contact_count = (int*)NvFlexMap(flex->get_buffer("contact_count"), eNvFlexMapWait); - int* contact_indices = (int*)NvFlexMap(flex->get_buffer("contact_indices"), eNvFlexMapWait); + int* contact_count = (int*)NvFlexMap(flex->buffers.contact_count, eNvFlexMapWait); + int* contact_indices = (int*)NvFlexMap(flex->buffers.contact_indices, eNvFlexMapWait); int max_contacts = flex->get_max_contacts(); float radius = flex->get_parameter("radius"); @@ -540,10 +540,10 @@ LUA_FUNCTION(FLEXSOLVER_ApplyContacts) { //NvFlexUnmap(flex->get_buffer("particle_pos")); //NvFlexUnmap(flex->get_buffer("particle_vel")); - NvFlexUnmap(flex->get_buffer("contact_vel")); - NvFlexUnmap(flex->get_buffer("contact_planes")); - NvFlexUnmap(flex->get_buffer("contact_count")); - NvFlexUnmap(flex->get_buffer("contact_indices")); + NvFlexUnmap(flex->buffers.contact_vel); + NvFlexUnmap(flex->buffers.contact_planes); + NvFlexUnmap(flex->buffers.contact_count); + NvFlexUnmap(flex->buffers.contact_indices); // Now that we have all our contact data, iterate and apply forces for (std::pair force : forces) { @@ -609,7 +609,7 @@ LUA_FUNCTION(FLEXSOLVER_GetParticlesInRadius) { int num_particles = 0; if (flex->get_parameter("reaction_forces") > 0) { - Vector4D* particle_pos = (Vector4D*)flex->get_host("particle_pos"); + Vector4D* particle_pos = flex->hosts.particle_pos; for (int i = 0; i < flex->get_active_particles(); i++) { if (particle_pos[i].AsVector3D().DistToSqr(pos) > radius) continue; diff --git a/binary/src/shaders/GWaterFinalpass.h b/binary/src/shaders/GWaterFinalpass.h index faa70ce..8442c14 100644 --- a/binary/src/shaders/GWaterFinalpass.h +++ b/binary/src/shaders/GWaterFinalpass.h @@ -13,7 +13,7 @@ BEGIN_SHADER_PARAMS SHADER_PARAM(SCREENTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "lights/white", "Texture of screen") SHADER_PARAM(DEPTHTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "lights/white", "Depth texture") SHADER_PARAM(IOR, SHADER_PARAM_TYPE_FLOAT, "1.333", "Ior of water") - SHADER_PARAM(COLOR2, SHADER_PARAM_TYPE_VEC4, "1.0 1.0 1.0 1.0", "Color of water. Alpha channel represents absorption amount") + SHADER_PARAM(COLOR2, SHADER_PARAM_TYPE_COLOR, "[1.0 1.0 1.0 1.0]", "Color of water. Alpha channel represents absorption amount") //SHADER_PARAM(ABSORPTIONMULTIPLIER, SHADER_PARAM_TYPE_FLOAT, "1", "Absorbsion multiplier") SHADER_PARAM(REFLECTANCE, SHADER_PARAM_TYPE_FLOAT, "0.5", "Reflectance of water") SHADER_PARAM(ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap") @@ -99,15 +99,6 @@ SHADER_DRAW { } DYNAMIC_STATE { - // constants - int scr_x, scr_y = 1; pShaderAPI->GetBackBufferDimensions(scr_x, scr_y); - const float scr_s[2] = {1.0 / scr_x, 1.0 / scr_y}; - float radius = params[RADIUS]->GetFloatValue(); - float ior = params[IOR]->GetFloatValue(); - float reflectance = params[REFLECTANCE]->GetFloatValue(); - const float* color2 = params[COLOR2]->GetVecValue(); - const float color2_normalized[4] = { color2[0] / 255.0, color2[1] / 255.0, color2[2] / 255.0, color2[3] / 255.0 }; - LightState_t lightState = { 0, false, false }; bool bFlashlightShadows = false; if (bHasFlashlight) { @@ -129,6 +120,15 @@ SHADER_DRAW { pShaderAPI->GetDX9LightState(&lightState); } + // constants + int scr_x, scr_y = 1; pShaderAPI->GetBackBufferDimensions(scr_x, scr_y); + const float scr_s[2] = { 1.0 / scr_x, 1.0 / scr_y }; + float radius = params[RADIUS]->GetFloatValue(); + float ior = params[IOR]->GetFloatValue(); + float reflectance = params[REFLECTANCE]->GetFloatValue(); + const float* color2 = params[COLOR2]->GetVecValue(); + const float color2_normalized[4] = { color2[0] / 255.0, color2[1] / 255.0, color2[2] / 255.0, color2[3] / 255.0 }; + pShaderAPI->SetPixelShaderConstant(0, scr_s); pShaderAPI->SetPixelShaderConstant(1, &radius); pShaderAPI->SetPixelShaderConstant(2, &ior); diff --git a/lua/autorun/client/gwater_menu2.lua b/lua/autorun/client/gwater_menu2.lua index e11c8d5..63923b6 100644 --- a/lua/autorun/client/gwater_menu2.lua +++ b/lua/autorun/client/gwater_menu2.lua @@ -19,7 +19,7 @@ local options = { absorption = CreateClientConVar("gwater2_absorption", "1", true), depth_fix = CreateClientConVar("gwater2_depth_fix", "0", true), menu_key = CreateClientConVar("gwater2_menukey", KEY_G, true), - color = Color(209, 237, 255, 25), + color = Color(255, 255, 255, 255), parameter_tab_header = "Parameter Tab", parameter_tab_text = "This tab is where you can change how the water interacts with itself and the environment.\n\nHover over a parameter to reveal its functionality.", adv_parameter_tab_header = "Adv. Parameter Tab", @@ -74,10 +74,15 @@ local options = { ["Force Dampening"] = {text = "Dampening force applied to props.\n\nHelps a little bit if props tend to bounce on the water surface."}, } +local finalpass = Material("gwater2/finalpass") +local volumetric = Material("gwater2/volumetric") +local normals = Material("gwater2/normals") + -- garry, sincerely... fuck you timer.Simple(0, function() - Material("gwater2/volumetric"):SetFloat("$alpha", options.absorption:GetBool() and 0.125 or 0) - Material("gwater2/normals"):SetInt("$depthfix", options.depth_fix:GetBool() and 1 or 0) + volumetric:SetFloat("$alpha", options.absorption:GetBool() and 0.125 or 0) + normals:SetInt("$depthfix", options.depth_fix:GetBool() and 1 or 0) + options.color = Color(finalpass:GetVector4D("$color2")) end) options.solver:SetParameter("gravity", 15.24) -- flip gravity because y axis positive is down @@ -303,7 +308,6 @@ local function create_picker(self, text, dock) print("Undefined parameter '" .. text .. "'!") end - local finalpass = Material("gwater2/finalpass") local mixer = vgui.Create("DColorMixer", self) mixer:SetPos(65, dock + 5) mixer:SetSize(276, 110) @@ -820,10 +824,9 @@ I DO NOT take responsiblity for any hardware damage this may cause]], "DermaDefa box:SetPos(132, 200) box:SetSize(20, 20) box:SetChecked(options.absorption:GetBool()) - local water_volumetric = Material("gwater2/volumetric") function box:OnChange(val) options.absorption:SetBool(val) - water_volumetric:SetFloat("$alpha", val and 0.125 or 0) + volumetric:SetFloat("$alpha", val and 0.125 or 0) end -- Depth fix checkbox & label @@ -839,10 +842,9 @@ I DO NOT take responsiblity for any hardware damage this may cause]], "DermaDefa box:SetPos(132, 230) box:SetSize(20, 20) box:SetChecked(options.depth_fix:GetBool()) - local water_normals = Material("gwater2/normals") function box:OnChange(val) options.depth_fix:SetBool(val) - water_normals:SetInt("$depthfix", val and 1 or 0) + normals:SetInt("$depthfix", val and 1 or 0) end -- Solver checkbox diff --git a/lua/autorun/gwater2_init.lua b/lua/autorun/gwater2_init.lua index d48e9d1..0b452bc 100644 --- a/lua/autorun/gwater2_init.lua +++ b/lua/autorun/gwater2_init.lua @@ -187,7 +187,8 @@ end) hook.Add("InitPostEntity", "gwater2_addprop", gwater2.reset_solver) hook.Add("OnEntityCreated", "gwater2_addprop", function(ent) timer.Simple(0, function() add_prop(ent) end) end) // timer.0 so data values are setup correctly -hook.Add("gwater2_posttick", "gwater2_gravgun_grab", function() +hook.Add("gwater2_posttick", "gwater2_gravgun_grab", function(succ) + if !succ then return end local lp = LocalPlayer() if !lp:KeyDown(IN_ATTACK2) then return end if IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "weapon_physcannon" then diff --git a/lua/gwater2_shaders.lua b/lua/gwater2_shaders.lua index 21490c0..bef7581 100644 --- a/lua/gwater2_shaders.lua +++ b/lua/gwater2_shaders.lua @@ -50,7 +50,8 @@ local function unfuck_lighting(pos0, pos1) render.OverrideDepthEnable(false, false) render.PopRenderTarget() end - +local wtf = FlexSolver(1) +wtf:AddParticle(Vector()) -- gwater2 shader pipeline hook.Add("PostDrawOpaqueRenderables", "gwater2_render", function(depth, sky, sky3d) --PreDrawViewModels if gwater2.solver:GetActiveParticles() < 1 then return end @@ -71,7 +72,7 @@ hook.Add("PostDrawOpaqueRenderables", "gwater2_render", function(depth, sky, sky local scrh = ScrH() local water = gwater2.material local radius = gwater2.solver:GetParameter("radius") - + --wtf:Tick(1/60, 0) gwater2.renderer:BuildMeshes(gwater2.solver, 0.2) --render.SetMaterial(Material("models/props_combine/combine_interface_disp")) diff --git a/lua/weapons/weapon_gw2_watergun.lua b/lua/weapons/weapon_gw2_watergun.lua index 58087fe..39e814b 100644 --- a/lua/weapons/weapon_gw2_watergun.lua +++ b/lua/weapons/weapon_gw2_watergun.lua @@ -36,8 +36,7 @@ SWEP.WorldModel = "models/weapons/w_pistol.mdl" SWEP.UseHands = true function SWEP:Initialize() - self:SetMaterial("hunter/myplastic") - self:SetModelScale(0.5) + end local function fuckgarry(w, s)