📄 ivp_collision_filter.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
// IVP_EXPORT_PUBLIC
#include <ivp_physics.hxx>
#include <string.h>
#include <ivu_vhash.hxx>
#include <ivp_collision_filter.hxx>
IVP_Collision_Filter::~IVP_Collision_Filter() {
return;
}
// ***************************************************************************
IVP_BOOL IVP_Collision_Filter_Coll_Group_Ident::check_objects_for_collision_detection(IVP_Real_Object *object0, IVP_Real_Object *object1) {
char *id0 = object0->nocoll_group_ident;
char *id1 = object1->nocoll_group_ident;
if (id0[0] == 0 || id1[0] == 0){
return IVP_TRUE;
}
if ( strncmp(id0, id1,IVP_NO_COLL_GROUP_STRING_LEN) == 0 ) {
return(IVP_FALSE);
}
return(IVP_TRUE);
}
IVP_Collision_Filter_Coll_Group_Ident::~IVP_Collision_Filter_Coll_Group_Ident() {
return;
}
IVP_Collision_Filter_Coll_Group_Ident::IVP_Collision_Filter_Coll_Group_Ident(IVP_BOOL delete_on_env_delete_in) {
this->delete_on_env_delete = delete_on_env_delete_in;
return;
}
void IVP_Collision_Filter_Coll_Group_Ident::environment_will_be_deleted(IVP_Environment *) {
if ( this->delete_on_env_delete ) {
P_DELETE_THIS(this);
}
return;
}
// ------------------------------------------------------------------------------
/********************************************************************************
* Class: IVP_CFEP_Objectpair
* Description: help-class for "Exclusive Pair" collision filter hash table
********************************************************************************/
class IVP_CFEP_Objectpair {
public:
IVP_Real_Object *object0;
IVP_Real_Object *object1;
};
/********************************************************************************
* Class: IVP_CFEP_Hash
* Description: hash table needed for fast storage of object pairs in
* "Exclusive Pair" collision filter
********************************************************************************/
class IVP_CFEP_Hash : protected IVP_VHash {
protected:
IVP_BOOL compare(void *elem0, void *elem1) const;
int pair_to_index(IVP_CFEP_Objectpair *pair);
public:
void add(IVP_CFEP_Objectpair *pair);
IVP_CFEP_Objectpair *remove(IVP_CFEP_Objectpair *pair);
IVP_CFEP_Objectpair *find(IVP_CFEP_Objectpair *pair);
IVP_CFEP_Hash(int create_size);
~IVP_CFEP_Hash();
};
IVP_BOOL IVP_CFEP_Hash::compare(void *elem0, void *elem1) const
{
IVP_CFEP_Objectpair *pair0 = (IVP_CFEP_Objectpair *)elem0;
IVP_CFEP_Objectpair *pair1 = (IVP_CFEP_Objectpair *)elem1;
if ( pair0->object0 != pair1->object0) return(IVP_FALSE);
if ( pair0->object1 != pair1->object1) return(IVP_FALSE);
return(IVP_TRUE);
}
int IVP_CFEP_Hash::pair_to_index(IVP_CFEP_Objectpair *pair)
{
return hash_index( (char *)pair, sizeof(pair));
};
void IVP_CFEP_Hash::add(IVP_CFEP_Objectpair *pair)
{
add_elem(pair, pair_to_index(pair));
}
IVP_CFEP_Objectpair *IVP_CFEP_Hash::remove(IVP_CFEP_Objectpair *pair)
{
return (IVP_CFEP_Objectpair *)remove_elem(pair, pair_to_index(pair));
}
IVP_CFEP_Objectpair *IVP_CFEP_Hash::find(IVP_CFEP_Objectpair *pair)
{
return (IVP_CFEP_Objectpair *)find_elem(pair, pair_to_index(pair));
}
IVP_CFEP_Hash::IVP_CFEP_Hash(int create_size) : IVP_VHash(create_size)
{
return;
}
IVP_CFEP_Hash::~IVP_CFEP_Hash()
{
// cleanup hash content
IVP_VHash_Enumerator<IVP_CFEP_Objectpair> enumerator(this);
int i;
for (i=0; i<this->n_elems(); i++) {
delete enumerator.get_next_element(this);
}
return;
}
/********************************************************************************
* Class: IVP_Collision_Filter_Exclusive_Pair
* Description: "Exclusive Pair" collision filter; stores pairs of object
* within a fast hash; collision detection will be disabled for
* these pairs
********************************************************************************/
void IVP_Collision_Filter_Exclusive_Pair::generate_hash_entry(IVP_Real_Object *obj0, IVP_Real_Object *obj1, IVP_CFEP_Objectpair *entry)
{
if ( obj1 > obj0 ) { // always sort objects by their memory address!
entry->object0 = obj0;
entry->object1 = obj1;
}
else {
entry->object0 = obj1;
entry->object1 = obj0;
}
return;
}
void IVP_Collision_Filter_Exclusive_Pair::disable_collision_between_objects(IVP_Real_Object *obj0, IVP_Real_Object *obj1)
{
IVP_CFEP_Objectpair *new_pair = new IVP_CFEP_Objectpair();
generate_hash_entry(obj0, obj1, new_pair);
if ( !this->hash_table->find(new_pair) ) { // pair already stored?
this->hash_table->add(new_pair); // no, then store now...
}
return;
}
void IVP_Collision_Filter_Exclusive_Pair::enable_collision_between_objects(IVP_Real_Object *obj0, IVP_Real_Object *obj1)
{
IVP_CFEP_Objectpair old_pair;
generate_hash_entry(obj0, obj1, &old_pair);
if ( this->hash_table->find(&old_pair) ) { // pair stored in hash?
IVP_CFEP_Objectpair *removed_pair = this->hash_table->remove(&old_pair); // yes, remove...
P_DELETE(removed_pair);
}
return;
}
IVP_BOOL IVP_Collision_Filter_Exclusive_Pair::check_objects_for_collision_detection(IVP_Real_Object *obj0, IVP_Real_Object *obj1)
{
IVP_CFEP_Objectpair pair;
generate_hash_entry(obj0, obj1, &pair);
if ( this->hash_table->find(&pair) ) { // pair stored in hash?
return(IVP_FALSE); // yes, skip collision...
}
return(IVP_TRUE);
}
void IVP_Collision_Filter_Exclusive_Pair::environment_will_be_deleted(IVP_Environment *)
{
delete(this);
return;
}
IVP_Collision_Filter_Exclusive_Pair::IVP_Collision_Filter_Exclusive_Pair()
{
this->hash_table = new IVP_CFEP_Hash(1024);
return;
}
IVP_Collision_Filter_Exclusive_Pair::~IVP_Collision_Filter_Exclusive_Pair()
{
P_DELETE(this->hash_table);
return;
}
//*******************************************************************************
void IVP_Meta_Collision_Filter::add_collision_filter(IVP_Collision_Filter *filter) {
filter_set.add( filter );
}
void IVP_Meta_Collision_Filter::remove_collision_filter(IVP_Collision_Filter *filter) {
filter_set.remove( filter );
}
IVP_BOOL IVP_Meta_Collision_Filter::check_objects_for_collision_detection(IVP_Real_Object *object0, IVP_Real_Object *object1) {
int do_collision=1;
int i;
for(i=filter_set.len()-1;i>=0;i--) {
IVP_Collision_Filter *coll_filter=filter_set.element_at(i);
do_collision=do_collision & (int)coll_filter->check_objects_for_collision_detection( object0, object1 );
}
return (IVP_BOOL)do_collision;
}
IVP_Meta_Collision_Filter::~IVP_Meta_Collision_Filter() {
return;
}
IVP_Meta_Collision_Filter::IVP_Meta_Collision_Filter(IVP_BOOL delete_on_env_delete_in) {
this->delete_on_env_delete = delete_on_env_delete_in;
return;
}
void IVP_Meta_Collision_Filter::environment_will_be_deleted(IVP_Environment *env) {
int i;
for(i=filter_set.len()-1;i>=0;i--) {
IVP_Collision_Filter *coll_filter=filter_set.element_at(i);
coll_filter->environment_will_be_deleted(env);
filter_set.remove_at(i);
}
if ( this->delete_on_env_delete ) {
P_DELETE_THIS(this);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -