コード例 #1
0
ファイル: contact.c プロジェクト: Teybeo/3D-Engine
void rameneEnContact(Particule* a, Particule* b, Vec3 normale, float valPenetration) {

    // On applique sur cet axe la moitié de la distance de pénetration;
    Vec3 separateur = Vec3_Mul_Scal_out(normale, -0.5*valPenetration);

    Vec3_Sub(&a->position, separateur);
    if (b != NULL)
        Vec3_Add(&b->position, separateur);
    else
        Vec3_Sub(&a->position, separateur);
}
コード例 #2
0
ファイル: contact.c プロジェクト: Teybeo/3D-Engine
void CollisionResolver_Resolve(ElemContact* tetepile) {

    ElemContact* curseur = tetepile;
    Particule* a = NULL;
    Particule* b = NULL;

    while (curseur != NULL) {

        a = curseur->contact.a;
        b = curseur->contact.b;

        // Vecteur de la vitesse de rapprochement de b vers a
        Vec3 vitRelative = a->vitesse;
        if (b != NULL)
            Vec3_Sub(&vitRelative, b->vitesse);

        // Projection de la vitesse relative sur la normale de la collision
        Vec3 impulsionA = Vec3_Project(vitRelative, curseur->contact.normale);

        float totalInverseMass = 1 / a->masse;
        if (b != NULL)
            totalInverseMass += (1 / b->masse);

        Vec3_Div_Scal(&impulsionA, totalInverseMass);

        Vec3 impulsionB = impulsionA;

        // En dessous d'un certain seuil de vitesse, on annule l'élasticité pour réduire les instabilités
        float coeffA = a->coeffRebond, coeffB;
        if (b != NULL)
            coeffB = b->coeffRebond;
//        if (abs(a->vitesse.y) + abs(a->vitesse.x) + abs(a->vitesse.z) < 0.001)
//            coeffA = 0;
//
//        if (abs(b->vitesse.y) + abs(b->vitesse.x) + abs(b->vitesse.z) < 0.001)
//            coeffB = 0;

        Vec3_Mul_Scal(&impulsionA, (1 + coeffA) / a->masse);
        if (b != NULL)
            Vec3_Mul_Scal(&impulsionB, (1 + coeffB) / b->masse);

        Vec3_Sub(&a->vitesse, impulsionA);
        if (b != NULL)
            Vec3_Add(&b->vitesse, impulsionB);

        rameneEnContact(a, b, curseur->contact.normale, curseur->contact.interpenetration);
        curseur = curseur->suivant;
    }

}
コード例 #3
0
ファイル: mdtra_compact_pdb.cpp プロジェクト: MrXaeroX/MDTRA
float MDTRA_Compact_PDB_File :: get_distance( int atIndex1, int atIndex2 ) const
{
	const MDTRA_Compact_PDB_Atom* at1 = fetchAtomBySerialNumber( atIndex1 );
	const MDTRA_Compact_PDB_Atom* at2 = fetchAtomBySerialNumber( atIndex2 );

	if (!at1 || !at2)
		return 0.0f;

	float vecDist[3];
	float len;

	Vec3_Sub( vecDist, at1->original_xyz, at2->original_xyz );
	Vec3_Len( len, vecDist );

	return len;
}
コード例 #4
0
ファイル: player.c プロジェクト: mrDIMAS/OldTech
void Player_Update( float timeStep ) {
    if( player ) {
        TVec3 vAxis = Vec3_Set( 0.0f, 1.0f, 0.0f );
        
        // get correct vectors for moving
        TVec3 look = Entity_GetLookVector( player->pivot );
        TVec3 right = Entity_GetRightVector( player->pivot );
        TVec3 listenerPosition = Entity_GetGlobalPosition( player->cameraPivot );
        
        Lightprobe_LightEntity( player->weapon->model );

        player->onGround = false;
        for( int i = 0; i < player->body.contactCount; i++ ) {
            TContact * contact = &player->body.contacts[i];
            // check angle between contact normal and vertical axis, it must be less than 60 degrees
            if( Vec3_Angle( vAxis, contact->normal ) < M_PI / 3.0 ) {
                player->onGround = true;
            }
        }
        
        // ====================
        // moving
        player->destVelocity = Vec3_Zero();
        
        player->move = false;
        if( Input_IsKeyDown( KEY_W )) {
            player->destVelocity = Vec3_Add( player->destVelocity, look );
            player->move = true;
        }
        if( Input_IsKeyDown( KEY_S )) {
            player->destVelocity = Vec3_Sub( player->destVelocity, look );
            player->move = true;
        }
        if( Input_IsKeyDown( KEY_A )) {
            player->destVelocity = Vec3_Add( player->destVelocity, right );
            player->move = true;
        }
        if( Input_IsKeyDown( KEY_D )) {
            player->destVelocity = Vec3_Sub( player->destVelocity, right );
            player->move = true;
        }

        if( Input_IsKeyDown( KEY_C ) ) {
            player->crouch = true;
            if( player->body.shape->sphereRadius > player->crouchRadius ) {
                player->body.shape->sphereRadius -= 0.05f;
            } else {
                player->body.shape->sphereRadius = player->crouchRadius;
            }
        } else {
            player->crouch = false;
            char standUp = 1;
            // before stand up, we must trace ray up on player's head, to ensure, that
            // there enough space to stand up.
            TVec3 end = Vec3_Set( player->body.position.x, player->body.position.y + 1.0f, player->body.position.z );
            TRay headRay = Ray_Set( player->body.position, end );
            TRayTraceResult out;
            Ray_TraceWorldStatic( &headRay, &out );
            if( out.body ) {
                float maxRadius = player->shape.sphereRadius + 0.4f;
                if( Vec3_SqrDistance( out.position, player->body.position ) < maxRadius * maxRadius ) {
                    standUp = 0;
                    player->crouch = true;
                }
            }
            if( standUp ) {
                if( player->body.shape->sphereRadius < player->standRadius ) {
                    player->body.shape->sphereRadius += 0.04f;
                } else {
                    player->body.shape->sphereRadius = player->standRadius;
                }
            }
        }
        // sync step sound position with player position
        for( int i = 0; i < player->stepSoundGroup->count; i++ ) {
            SoundSource_SetPosition( &player->stepSoundGroup->sounds[i], &listenerPosition );
            if( player->crouch ) {
                SoundSource_SetVolume( &player->stepSoundGroup->sounds[i], 0.5f );
            } else {
                SoundSource_SetVolume( &player->stepSoundGroup->sounds[i], 1.0f );
            }
        }
        // emit step sound only if got contact with the ground
        if( player->body.contactCount > 0 ) {
            TContact * lowestContact = &player->body.contacts[0];
            for( int i = 0; i < player->body.contactCount; i++ ) {
                if( player->body.contacts[i].position.y < lowestContact->position.y ) {
                    lowestContact = &player->body.contacts[i];
                }
            }
            // select emittable sounds
            if( lowestContact->triangle ) {
                // iterate over all possible step sound groups
                for( int i = 0; i < STEP_GROUP_COUNT; i++ ) {
                    // iterate over each material in group
                    for( int j = 0; j < player->stepSounds[i].materialCount; j++ ) {
                        if( lowestContact->triangle->material == player->stepSounds[i].material[j] ) {
                            player->stepSoundGroup = &player->stepSounds[i];
                        }
                    }
                }
            }

            if( player->pathLength > 15 * player->speed ) {
                int randomSound = rand() % player->stepSoundGroup->count;
                if( randomSound >= 4 ) {
                    randomSound = 3;
                }
                SoundSource_Play( &player->stepSoundGroup->sounds[ randomSound ] );
                player->pathLength = 0.0f;
            }
        }

        float realSpeed = player->speed;

        player->run = false;
        if( Input_IsKeyDown( KEY_LeftShift ) && !player->crouch ) {
            realSpeed *= player->speedMultiplier;
            player->run = true;
        }
        
        if( player->crouch ) {
            realSpeed *= 0.65f;
        }

        if( player->move ) {
            // prevent divide by zero
            player->destVelocity = Vec3_Normalize( player->destVelocity );
            player->pathLength += realSpeed * 0.5f;
        }

        float interpCoeff = 0.25f;
        if( !player->onGround ) {
            interpCoeff = 0.0035f;
        }
        
        player->destVelocity.x *= realSpeed;
        player->destVelocity.z *= realSpeed;
        
        player->velocity.x += ( player->destVelocity.x - player->velocity.x ) * interpCoeff;
        player->velocity.z += ( player->destVelocity.z - player->velocity.z ) * interpCoeff;
        
        // do not overwrite gravity component (y), apply only x and z
        player->body.linearVelocity.x = player->velocity.x * timeStep;
        player->body.linearVelocity.z = player->velocity.z * timeStep;

        // ====================
        // jump   
        if( Input_IsKeyHit( KEY_Space ) ) {
            if( player->onGround ) {
                player->body.linearVelocity.y += player->jumpStrength;
            }
        }

        // sync pivot's position with physical body
        player->pivot->localPosition = player->body.position;

        // ====================
        // mouse look
        player->yaw -= Input_GetMouseXSpeed() * player->mouseSensivity * timeStep;
        player->pitch += Input_GetMouseYSpeed() * player->mouseSensivity * timeStep;

        // clamp pitch
        if( player->pitch > player->maxPitch ) {
            player->pitch = player->maxPitch;
        }
        if( player->pitch < -player->maxPitch ) {
            player->pitch = -player->maxPitch;
        }

        right = Vec3_Set( 1, 0, 0 );
        vAxis = Vec3_Set( 0, 1, 0 );
        player->pivot->localRotation = Quaternion_SetAxisAngle( vAxis, player->yaw );
        player->cameraPivot->localRotation = Quaternion_SetAxisAngle( right, player->pitch );

        // sound
        TVec3 up = Entity_GetUpVector( player->cameraPivot );
        SoundListener_SetPosition( &listenerPosition );        
        SoundListener_SetOrientation( &look, &up );
        
        // weapon
        Weapon_Update( player->weapon );
        if( Input_IsMouseDown( MB_Left )) {
            Weapon_Shoot( player->weapon );
        }
        player->weapon->moveSpeed = player->body.linearVelocity;
        
        Player_CameraShake( );
    }
}
コード例 #5
0
ファイル: octree.c プロジェクト: mrDIMAS/OldTech
void Octree_BuildRecursiveInternal( TOctreeNode * node, TTriangle * triangles, int triangleCount, int * indices, int indexCount, int maxTrianglesPerNode ) {
    if( indexCount < maxTrianglesPerNode ) {
        int sizeBytes = sizeof( int ) * indexCount;
        node->indexCount = indexCount;
        node->indices = Memory_AllocateClean( sizeBytes );
        memcpy( node->indices, indices, sizeBytes );
        return;
    }

    Octree_SplitNode( node );

    for( int childNum = 0; childNum < 8; childNum++ ) {
        TOctreeNode * child = node->childs[childNum];

        TVec3 middle = Vec3_Middle( child->min, child->max );
        TVec3 halfSize = Vec3_Scale( Vec3_Sub( child->max, child->min ), 0.5f );

        float center[3] = {middle.x, middle.y, middle.z};
        float half[3] = {halfSize.x, halfSize.y, halfSize.z};

        // count triangles in each leaf 
        int leafTriangleCount = 0;

        for( int i = 0; i < triangleCount; i++ ) {
            TTriangle * triangle = triangles + i;
            float triverts[3][3] = { 	{triangle->a.x,triangle->a.y, triangle->a.z},
                {triangle->b.x,triangle->b.y, triangle->b.z},
                {triangle->c.x,triangle->c.y, triangle->c.z}
            };
            if( triBoxOverlap( center, half, triverts ) ||
                    Octree_IsPointInsideNode( child, &triangle->a ) ||
                    Octree_IsPointInsideNode( child, &triangle->b ) ||
                    Octree_IsPointInsideNode( child, &triangle->c ) ) {
                leafTriangleCount++;
            }
        }

        // allocate memory for temporary leaf and fill it with data 
        int * leafIndices = Memory_NewCount( leafTriangleCount, int );
        int triangleNum = 0;
        for( int i = 0; i < triangleCount; i++ ) {
            TTriangle * triangle = triangles + i;

            float triverts[3][3] = { 	{triangle->a.x,triangle->a.y, triangle->a.z},
                {triangle->b.x,triangle->b.y, triangle->b.z},
                {triangle->c.x,triangle->c.y, triangle->c.z}
            };
            if( triBoxOverlap( center, half, triverts )||
                    Octree_IsPointInsideNode( child, &triangle->a ) ||
                    Octree_IsPointInsideNode( child, &triangle->b ) ||
                    Octree_IsPointInsideNode( child, &triangle->c ) ) {
                *(leafIndices + triangleNum) = i;
                triangleNum++;
            }
        }

        // recursively process childs of this node 
        Octree_BuildRecursiveInternal( child, triangles, triangleCount, leafIndices, triangleNum, maxTrianglesPerNode );

        // leafFaces data already copied to another node, so we can free temporary array 
        Memory_Free( leafIndices );
    }
}