TEST_F(LocalIds, using_entities)
{
    if (get_parallel_size() == 1)
    {
        setup_mesh("generated:2x2x2", stk::mesh::BulkData::AUTO_AURA);
        BulkDataHelper bulkDataHelper(get_bulk());

        typedef stk::mesh::Field<double, stk::mesh::Cartesian3d> CoordFieldType;
        CoordFieldType *coords = get_meta().get_field<CoordFieldType>(stk::topology::NODE_RANK, "coordinates");

        unsigned elemIndex = 0;
        const stk::mesh::BucketVector& elemBuckets = get_bulk().buckets(stk::topology::ELEM_RANK);
        for(size_t i=0;i<elemBuckets.size();++i)
        {
            const stk::mesh::Bucket& bucket = *elemBuckets[i];
            for(size_t j=0;j<bucket.size();++j)
            {
                Entities nodes = bulkDataHelper.get_nodes(bucket[j]);
                for(unsigned k=0;k<nodes.size();++k)
                {
                    double *node_data = stk::mesh::field_data(*coords, nodes[k]);
                    EXPECT_NEAR(gold_x_coordinates[elemIndex][k], node_data[0], 1.e-6);
                }
                ++elemIndex;
            }
        }
    }
}
void Collisionhandler::collisionBetweenEntities(Entities &entities){
	for (Entities::size_type i = 0; i < entities.size(); i++){
		Entity *e0 = entities[i];
		for (Entities::size_type j = i + 1; j < entities.size(); j++){
			Entity *e1 = entities[j];
			if (e0->isOnScreen() && e1->isOnScreen()) {
				if (hasCollided(e0, e1)) {
					if (e0->getType() != e1->getType() && e0->getType() == Entity::PLAYER) {
						checkCollisionDirection(e0, e1);
						//checkCollisionDirection(e1, e0);
					}
				}
			}
		}
	}
}
void Collisionhandler::collisionBetweenEntitiesAndTerrains(Entities &entities, Terrains &terrains){
	for (Entities::size_type i = 0; i < entities.size(); i++){
		Entity *e0 = entities[i];
		for (Terrains::size_type j = 0; j < terrains.size(); j++){
			Terrain *e1 = terrains[j];
			if (e0->isOnScreen() && e1->isOnScreen()) {
				if (hasCollided(e0, e1)) {
					checkCollisionDirection(e0, e1);
				}
			}
		}
	}
}
Exemple #4
0
void PhysicsSystem::update(GameComponents& components, Entities const& entities, float dt) {
    std::vector<Contact> contacts;
    std::vector<StaticContact> static_contacts;
    std::vector<Collider*> colliders(entities.size());
    int collider_index = 0;
    
    float top = 600.0f;
    float bottom = 40.0f;
    
    // find contacts
    for (Entities::const_iterator it0 = entities.begin(); it0 != entities.end(); ++it0) {
        Entity entity0 = *it0;
        Collider* collider0 = &components.get<ColliderComponent>(entity0);
        collider0->touching.clear();
        colliders[collider_index++] = collider0;
        
        static_contacts.push_back({
            top - collider0->position(1) - collider0->radius,
            Mth::make_cvector(0.0f, 1.0f),
            collider0,
            entity0,
            0.0f
        });
        static_contacts.push_back({
            collider0->position(1) - bottom - collider0->radius,
            Mth::make_cvector(0.0f, -1.0f),
            collider0,
            entity0,
            0.0f
        });
        
        Entities::const_iterator it1 = it0; ++it1;
        for (; it1 != entities.end(); ++it1) {
            Entity entity1 = *it1;
            Collider* collider1 = &components.get<ColliderComponent>(entity1);
            
            if ((collider0->group == CG_PB && collider1->group == CG_PB) ||
                (collider0->group == CG_EB && collider1->group == CG_EB) ||
                (collider0->group == CG_PB && collider1->group == CG_EB) ||
                (collider0->group == CG_EB && collider1->group == CG_PB) ||
                (collider0->group == CG_P && collider1->group == CG_PB) ||
                (collider0->group == CG_PB && collider1->group == CG_P) ||
                (collider0->group == CG_E && collider1->group == CG_EB) ||
                (collider0->group == CG_EB && collider1->group == CG_E)) {
                continue;
            }
            
            Mth::CVector<float, 2> d = collider1->position - collider0->position;
            
            Contact c {
                Mth::length(d) - collider0->radius - collider1->radius,
                Mth::normal(d),
                collider0,
                collider1,
                entity0,
                entity1,
                0.0f
            };
            
            contacts.push_back(c);
        }
    }
    
    // solve contacts
    int iterations = 4;
    for (int i = 0; i < iterations; ++i) {
        for (auto& contact : static_contacts) {
            float relative_velocity = Mth::dot(-contact.collider->velocity, contact.normal);
            float remove_impuls = contact.distance / dt + relative_velocity;
            float new_impuls = std::min(contact.impuls + remove_impuls, 0.0f);
            float impuls_change = new_impuls - contact.impuls;
            contact.impuls = new_impuls;
            contact.collider->velocity += contact.normal * impuls_change;
        }
        
        for (auto& contact : contacts) {
            float relative_velocity = Mth::dot(contact.collider1->velocity - contact.collider0->velocity, contact.normal);
            float remove = contact.distance / dt + relative_velocity;
            float remove_impuls = remove / 2.0f;
            float new_impuls = std::min(contact.impuls + remove_impuls, 0.0f);
            float impuls_change = new_impuls - contact.impuls;
            
            contact.impuls = new_impuls;
            contact.collider0->velocity += contact.normal * impuls_change;
            contact.collider1->velocity -= contact.normal * impuls_change;
            
            if (i == iterations-1) {
                if (new_impuls < 0.0f) {
                    contact.collider0->touching.push_back(contact.entity1);
                    contact.collider1->touching.push_back(contact.entity0);
                }
            }
        }
    }
    
    // evaluate simulation
    for (Collider* collider : colliders) {
        collider->position += collider->velocity * dt;
        collider->velocity = Mth::make_cvector(0.0f, 0.0f);
    }
}
boost::iterator_range<ElementIterator> make_range(Entities& entities)
{
  ElementIterator begin(entities);
  return boost::make_iterator_range(begin,begin+entities.size());
}