open_toontown_panda3d/panda/src/physx/physxMeshHash.cxx

264 lines
6.6 KiB
C++

// Filename: physxMeshHash.cxx
// Created by: enn0x (13Sep10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "physxMeshHash.h"
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::quick_sort
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
quick_sort(pvector<int> &itemIndices, int l, int r) {
int i, j, mi;
int k, m;
i = l; j = r; mi = (l + r)/2;
m = itemIndices[mi];
while (i <= j) {
while(itemIndices[i] < m) i++;
while(m < itemIndices[j]) j--;
if (i <= j) {
k = itemIndices[i]; itemIndices[i] = itemIndices[j]; itemIndices[j] = k;
i++; j--;
}
}
if (l < j) quick_sort(itemIndices, l, j);
if (i < r) quick_sort(itemIndices, i, r);
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::compress_indices
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
compress_indices(pvector<int> &itemIndices) {
if (itemIndices.size() == 0) return;
// Sort results
quick_sort(itemIndices, 0, itemIndices.size() - 1);
// Mark duplicates
int i = 0;
while (i < (int)itemIndices.size()) {
int j = i+1;
while (j < (int)itemIndices.size() && itemIndices[i] == itemIndices[j]) {
itemIndices[j] = -1; j++;
}
i = j;
}
// Remove duplicates
i = 0;
while (i < (int)itemIndices.size()) {
if (itemIndices[i] < 0) {
itemIndices[i] = itemIndices[itemIndices.size()-1];
itemIndices.pop_back();
}
else i++;
}
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::set_grid_spacing
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
set_grid_spacing(float spacing) {
_spacing = spacing;
_invSpacing = 1.0f / spacing;
reset();
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::reset
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
reset() {
_time++;
_entries.clear();
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::add
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
add(const NxBounds3 &bounds, int itemIndex) {
int x1,y1,z1;
int x2,y2,z2;
int x,y,z;
cell_coord_of(bounds.min, x1, y1, z1);
cell_coord_of(bounds.max, x2, y2, z2);
MeshHashEntry entry;
entry.itemIndex = itemIndex;
for (x = x1; x <= x2; x++) {
for (y = y1; y <= y2; y++) {
for (z = z1; z <= z2; z++) {
int h = hash_function(x, y, z);
MeshHashRoot &r = _hashIndex[h];
int n = _entries.size();
if (r.timeStamp != _time || r.first < 0)
entry.next = -1;
else
entry.next = r.first;
r.first = n;
r.timeStamp = _time;
_entries.push_back(entry);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::add
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
add(const NxVec3 &pos, int itemIndex) {
int x, y, z;
cell_coord_of(pos, x, y, z);
MeshHashEntry entry;
entry.itemIndex = itemIndex;
int h = hash_function(x, y, z);
MeshHashRoot &r = _hashIndex[h];
int n = _entries.size();
if (r.timeStamp != _time || r.first < 0)
entry.next = -1;
else
entry.next = r.first;
r.first = n;
r.timeStamp = _time;
_entries.push_back(entry);
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::query
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
query(const NxBounds3 &bounds, pvector<int> &itemIndices, int maxIndices) {
int x1, y1, z1;
int x2, y2, z2;
int x, y, z;
cell_coord_of(bounds.min, x1, y1, z1);
cell_coord_of(bounds.max, x2, y2, z2);
itemIndices.clear();
for (x=x1; x<=x2; x++) {
for (y=y1; y<=y2; y++) {
for (z=z1; z<=z2; z++) {
int h = hash_function(x, y, z);
MeshHashRoot &r = _hashIndex[h];
if (r.timeStamp != _time) continue;
int i = r.first;
while (i >= 0) {
MeshHashEntry &entry = _entries[i];
itemIndices.push_back(entry.itemIndex);
if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return;
i = entry.next;
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::query_unique
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
query_unique(const NxBounds3 &bounds, pvector<int> &itemIndices, int maxIndices) {
query(bounds, itemIndices, maxIndices);
compress_indices(itemIndices);
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::query
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
query(const NxVec3 &pos, pvector<int> &itemIndices, int maxIndices) {
int x, y, z;
cell_coord_of(pos, x, y, z);
itemIndices.clear();
int h = hash_function(x, y, z);
MeshHashRoot &r = _hashIndex[h];
if (r.timeStamp != _time) return;
int i = r.first;
while (i >= 0) {
MeshHashEntry &entry = _entries[i];
itemIndices.push_back(entry.itemIndex);
if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return;
i = entry.next;
}
}
////////////////////////////////////////////////////////////////////
// Function: PhysxMeshHash::query_unique
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PhysxMeshHash::
query_unique(const NxVec3 &pos, pvector<int> &itemIndices, int maxIndices) {
query(pos, itemIndices, maxIndices);
compress_indices(itemIndices);
}