Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

NSFW Best Thread Ever [No SJW-related posts allowed]

SwiftCrack

Arcane
Joined
Oct 3, 2012
Messages
1,836
I unironically didn't know MineCon was a thing.
 

dbx

Arcane
Patron
Joined
Dec 14, 2009
Messages
3,897
https://github.com/CRYTEK-CRYENGINE/CRYENGINE
That's right, it get open sourced. The first version.
I'm not a fan of their games but if that mean less usage of Unity the better...
Imagine dungeon crawlers in this engine.

It's called Cry Engine because the code makes you cry.

For example, this is ONE function
https://github.com/CRYTEK-CRYENGINE...e/CryEngine/CryPhysics/livingentity.cpp#L1300

Code:
int CLivingEntity::Step(float time_interval)
{
    if (time_interval<=0)
        return 1;
    float dt = m_timeStepFull-m_timeStepPerformed;
    time_interval = m_pWorld->m_bWorldStep==2 ? min(time_interval, dt) : dt;
    time_interval = max(time_interval, 0.001f);

    const int iCaller = get_iCaller_int();
    int i,j,jmin,ipartMin,nents,ncont,bFlying,bWasFlying,bUnprojected,idmat,iPrim, bHasExtraParts=0,
        bHasFastPhys,icnt,nUnproj,bStaticUnproj,bDynUnproj,bMoving=0,nPrecompEnts=0,nPrecompParts=0, nUsedPartsCount=0,
        &nNoResponseAllocLE=m_pWorld->m_threadData[iCaller].nNoResponseAllocLE,
        &nPrecompEntsAlloc=m_pWorld->m_threadData[iCaller].nPrecompEntsAllocLE,&nPrecompPartsAlloc=m_pWorld->m_threadData[iCaller].nPrecompPartsAllocLE;
    const Quat oldQRot = m_qrot;
    Vec3 pos,vel,pos0,vel0,newpos,move(ZERO),nslope,ncontactHist[4],ncontact,ptcontact,ncontactSum,BBoxInner[2],velGround,axis,sz,heightAdj=Vec3(0.f);
    float movelen,tmin,vrel,movesum,kInertia;
    le_precomp_entity *&pPrecompEnts=m_pWorld->m_threadData[iCaller].pTmpPrecompEntsLE;
    le_precomp_part *&pPrecompParts=m_pWorld->m_threadData[iCaller].pTmpPrecompPartsLE;
    le_tmp_contact *&pNoResponseContactLE=m_pWorld->m_threadData[iCaller].pTmpNoResponseContactLE, *pNRC;
    le_contact unproj[8];
    CCylinderGeom CylinderGeomOuter,*pCyl[2];
    geom_world_data gwd[3];
    intersection_params ip;
    CPhysicalEntity **pentlist, *pentmin=NULL;
    geom_contact *pcontacts;
    pe_action_impulse ai;
    pe_status_dynamics sd;
    WriteLockCond lockMain(m_lockStep,m_bStateReading^1);
    ip.bNoAreaContacts = true;

    IF (nNoResponseAllocLE==0, 0) pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE=16];

    if (m_timeForceInertia>0.0001f)
        kInertia = 6.0f;
    else if (m_kInertiaAccel && m_velRequested.len2()>0.1f)
        kInertia = m_kInertiaAccel;
    else
        kInertia = m_kInertia;

    pos = m_pWorld->m_bWorldStep==2 ? m_pos : SyncWithGroundCollider(time_interval);
    vel0=vel = m_vel;
    bWasFlying = bFlying = m_bFlying;
    if (!m_bStateReading) {
        m_timeUseLowCap -= time_interval;
        m_timeSinceStanceChange += time_interval;
        m_timeSinceImpulseContact += time_interval;
        m_timeForceInertia = max(0.0f,m_timeForceInertia-time_interval);
        m_timeStepPerformed += time_interval;
    }

    if (m_bActive &&
            (!(vel.len2()==0 && m_velRequested.len2()==0 && (!bFlying || m_gravity.len2()==0) && m_dhSpeed==0 && m_dhAcc==0) ||
            m_bActiveEnvironment || m_nslope.z<m_slopeSlide || m_velGround.len2()>0))  
    {
        FUNCTION_PROFILER( GetISystem(),PROFILE_PHYSICS );
        PHYS_ENTITY_PROFILER

        m_bActiveEnvironment = 0;
        //m_nslope.Set(0,0,1);
        if (kInertia==0 && !bFlying && !m_bJumpRequested || m_pWorld->m_vars.bFlyMode) {
            vel = m_velRequested;
            vel -= m_nslope*(m_nslope*vel);
        }
        if (bFlying && !m_pWorld->m_vars.bFlyMode && m_kAirControl>0)    {
            if (kInertia>0) {
                Vec3 velDelta = m_velRequested * (m_kInertia*time_interval*m_kAirControl);
                Vec3 velDiff = m_velRequested - vel;
                  
                const float kAirControlSelect = m_kAirControl-1.0f;

                velDelta.x = (float)__fsel(-(velDiff.x * velDelta.x), 0.0f, velDelta.x);
                velDelta.y = (float)__fsel(-(velDiff.y * velDelta.y), 0.0f, velDelta.y);
                velDelta.z = (float)__fsel(-(velDiff.z * velDelta.z), 0.0f, velDelta.z);

                velDelta.x = (float)__fsel(velDiff.x, min(velDiff.x, velDelta.x), max(velDiff.x, velDelta.x));
                velDelta.y = (float)__fsel(velDiff.y, min(velDiff.y, velDelta.y), max(velDiff.y, velDelta.y));
                velDelta.z = (float)__fsel(velDiff.z, min(velDiff.z, velDelta.z), max(velDiff.z, velDelta.z));
              
                velDelta.y = (float)__fsel(kAirControlSelect, velDiff.y, velDelta.y);
                velDelta.x = (float)__fsel(kAirControlSelect, velDiff.x, velDelta.x);              

                vel += velDelta;
            } else if (m_gravity.len2()>0)
                vel = m_gravity*(vel*m_gravity-m_velRequested*m_gravity)/m_gravity.len2()+m_velRequested;
            else
                vel = m_velRequested;
        }

        //filippo:m_forceFly is to let the game set a velocity no matter what is the status of the entity.
        if (m_forceFly)
            vel = m_velRequested;
         else if (bFlying && !m_bSwimming && !m_pWorld->m_vars.bFlyMode)
             move += m_gravity*sqr(time_interval)*0.5f;

        if (vel.len2() > sqr(m_pWorld->m_vars.maxVelPlayers))
            vel.normalize() *= m_pWorld->m_vars.maxVelPlayers;
      
        move += vel*time_interval;

        m_forceFly = false;
        bUnprojected = 0;
        axis = m_qrot*Vec3(0,0,1);
        if (_isnan(move.len2())) //necessary? Is there any way that this can occur? - Rich S
            return 1;
        --m_bSquashed; m_bSquashed-=m_bSquashed>>31;

        if (m_pWorld->m_vars.iCollisionMode!=0 && m_pWorld->m_vars.bFlyMode) {    //Rich S - is bFlyMode a cheat? Can we disable in release?
            pos+=move; bFlying=1; m_hLatest=0; ReleaseGroundCollider();
        } else {

            const float fSizeX = m_size.x;
            const float fSizeZ = m_size.z;
            movelen = move.len();
            const float fGap = (movelen+m_pWorld->m_vars.maxContactGapPlayer)*1.5f;
            const Vec3 posDiff = pos - m_pos;
            BBoxInner[0] = m_BBox[0]+(posDiff)-Vec3(fGap,fGap,fGap);
            BBoxInner[1] = m_BBox[1]+(posDiff)+Vec3(fGap,fGap,fGap);
            const float fGap2 = max(10.0f*time_interval,fGap); // adds a safety margin of m_size.x width
            const Vec3 BBoxOuter0 = m_BBox[0]+(posDiff)-Vec3(fGap2,fGap2,fGap2);
            const Vec3 BBoxOuter1 = m_BBox[1]+(posDiff)+Vec3(fGap2,fGap2,fGap2);

            nents = m_pWorld->GetEntitiesAround(BBoxOuter0,BBoxOuter1,
                pentlist, m_collTypes|ent_independent|ent_triggers|ent_sort_by_mass, this, 0,iCaller);

            if (m_vel.len2()) for(i=0;i<m_nColliders;i++) if (m_pColliders[i]->HasConstraintContactsWith(this,constraint_inactive))
                m_pColliders[i]->Awake();

            const float fMassInv = m_massinv;
            for(i=j=bHasFastPhys=0,vrel=0; i<nents; i++) if (!m_pForeignData || pentlist[i]->m_pForeignData!=m_pForeignData){
                Vec3 size = pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0];
                int bFastPhys = 0;
                if (IgnoreCollision(m_collisionClass, pentlist[i]->m_collisionClass))
                    continue;
                if (pentlist[i]->m_iSimClass==2) {
                    if (pentlist[i]->m_flags & ref_small_and_fast)
                        continue;
                    else if (pentlist[i]->GetMassInv()*0.4f<fMassInv) {
                        pentlist[i]->GetStatus(&sd);
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(size.x,size.y),size.z));;
                        bHasFastPhys |= (bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval));
                    }
                }
                if (!bFastPhys && !AABB_overlap(pentlist[i]->m_BBox,BBoxInner) && size.len2()>0)
                    continue;
                idmat = pentlist[i]->GetType();
                if (idmat==PE_SOFT || idmat==PE_ROPE)
                    pentlist[i]->Awake();
                else if (pentlist[i]->m_iSimClass<4 &&
                    (idmat!=PE_LIVING && !pentlist[i]->IgnoreCollisionsWith(this,1) ||
                     idmat==PE_LIVING && pentlist[i]->m_parts[0].flags&collider_flags &&
                     pentlist[i]!=this && m_pLivingEntToIgnore!=pentlist[i] && ((CLivingEntity*)pentlist[i])->m_pLivingEntToIgnore!=this))
                {
                    if (pentlist[i]->m_iSimClass==1 && m_timeSinceImpulseContact<0.2f && pentlist[i]->GetMassInv()>0)    {
                        int ipart; unsigned int flags;
                        for(ipart=0,flags=0; ipart<pentlist[i]->m_nParts; ipart++)
                            flags |= pentlist[i]->m_parts[ipart].flags;
                        if (flags & collider_flags)
                            pentlist[i]->Awake();
                    }
                    pentlist[j++] = pentlist[i];
                }
            }
            nents = j;
            pos0 = pos;
            bStaticUnproj = bDynUnproj = 0;
            newpos = pos+move;

            IF (nents>nPrecompEntsAlloc, 0) delete[] pPrecompEnts, pPrecompEnts=new le_precomp_entity[nPrecompEntsAlloc=nents];
            for(i=0; i<nents; i++) {
                le_precomp_entity &ent = pPrecompEnts[nPrecompEnts++];
                ent.BBox[0]=pentlist[i]->m_BBox[0];
                ent.BBox[1]=pentlist[i]->m_BBox[1];
                ent.sz=(sz=pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0]);
                ent.bCheckBBox=sz.len2()>0;
                ent.massinv=pentlist[i]->GetMassInv();
                ent.entType=pentlist[i]->GetType();
                ent.iSimClass=pentlist[i]->m_iSimClass;
                ent.pent=pentlist[i];
                ent.nParts=pentlist[i]->m_nParts;
                ent.ignoreCollisionsWith=pentlist[i]->IgnoreCollisionsWith(this,1);
                ent.iPartsBegin=nPrecompParts;
                ent.iPartsEnd=nPrecompParts+(nUsedPartsCount=pentlist[i]->GetUsedPartsCount(iCaller));
                IF (ent.iPartsEnd>nPrecompPartsAlloc, 0) {
                    ReallocateList(pPrecompParts, nPrecompParts, ent.iPartsEnd+128);
                    nPrecompPartsAlloc=ent.iPartsEnd+128;
                }
                for(int j1=0; j1<nUsedPartsCount; j1++) {
                    le_precomp_part &part = pPrecompParts[nPrecompParts++];
                    part.BBox[0]=pentlist[i]->m_parts[part.ipart=j=pentlist[i]->GetUsedPart(iCaller,j1)].BBox[0];
                    part.BBox[1]=pentlist[i]->m_parts[j].BBox[1];
                    part.partrot=pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q;
                    part.partoff=pentlist[i]->m_pos + pentlist[i]->m_qrot*pentlist[i]->m_parts[j].pos;
                    part.partscale=pentlist[i]->m_parts[j].scale;  
                    part.partflags=pentlist[i]->m_parts[j].flags;
                    part.pgeom=pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom;
                    part.surface_idx=pentlist[i]->m_parts[j].surface_idx;
                    ent.iLastPart=nPrecompParts-1;
                }
            }
      
            // first, check if we need unprojection in the initial position
            if (sqr(m_qrot.v.x)+sqr(m_qrot.v.y)<sqr(0.001f))
                gwd[0].R.SetIdentity();
            else
                gwd[0].R = Matrix33(m_qrot);
            gwd[0].centerOfMass = gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
            gwd[0].v.zero(); gwd[0].w.zero(); // since we check a static character against potentially moving environment here
            ip.vrel_min = fSizeX;
            ip.time_interval = time_interval*2;
            ip.maxUnproj = fSizeX*2.5f;
            ip.ptOutsidePivot[0] = gwd[0].offset;
            pCyl[0] = m_pCylinderGeom;
            if (bHasFastPhys) {
                cylinder cylOuter;
                cylOuter.r = fSizeX+min(fSizeX*1.5f,vrel*time_interval);
                cylOuter.hh = fSizeZ+min(fSizeZ,vrel*time_interval);
                cylOuter.center.zero();
                cylOuter.axis.Set(0,0,1);
                CylinderGeomOuter.CreateCylinder(&cylOuter);
                pCyl[1] = &CylinderGeomOuter;
            }

            retry_without_ground_sync:
            if (m_parts[0].flagsCollider) {
                for(i=nUnproj=0,ncontactSum.zero();i<nents;++i)
                    if (pPrecompEnts[i].entType!=PE_LIVING) {
                    const float minv = pPrecompEnts[i].massinv;
                    const int bHeavy = isneg(minv*0.4f-fMassInv);
                    const int iSimClass = pPrecompEnts[i].iSimClass;
                    CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                    int bFastPhys = 0;
                    if (bHasFastPhys && bHeavy && iSimClass==2 && pent!=m_pLastGroundCollider) {
                        pent->GetStatus(&sd);
                        const Vec3 &sz0 = pPrecompEnts[i].sz;
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(sz0.x,sz0.y),sz0.z));
                        bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval);
                        gwd[1].v = sd.v; gwd[1].w = sd.w;
                        gwd[1].centerOfMass = sd.centerOfMass;
                    }    else {
                        gwd[1].v.zero(); gwd[1].w.zero();
                    }

                    for(int iCyl=0; iCyl<bFastPhys+m_nParts; iCyl++) {
                        int igwd,flagsCollider;    IGeometry *pCurCyl;
                        if (iCyl<=bFastPhys) {
                            pCurCyl=pCyl[iCyl]; igwd=0;    flagsCollider=collider_flags;
                        } else {
                            pCurCyl = m_parts[iCyl-bFastPhys].pPhysGeom->pGeom;
                            gwd[igwd=2].R = Matrix33(m_qrot*m_parts[iCyl-bFastPhys].q);
                            gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[iCyl-bFastPhys].pos;
                            gwd[2].scale = m_parts[iCyl-bFastPhys].scale;
                            if (!((flagsCollider = m_parts[iCyl-bFastPhys].flagsCollider) & geom_colltype_solid))
                                continue;
                            bHasExtraParts = 1;
                        }
                        for(int j1=pPrecompEnts[i].iPartsBegin, bCheckBBox=pPrecompEnts[i].bCheckBBox; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                            if (pPrecompParts[j1].partflags & flagsCollider && (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))    {
                                //(pent->m_qrot*pentlist[i]->m_parts[j].q).getmatrix(gwd[1].R); //Q2M_IVO
                                gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                gwd[1].offset = pPrecompParts[j1].partoff;
                                gwd[1].scale = pPrecompParts[j1].partscale;
                                j = pPrecompParts[j1].ipart;
                                //if (m_pWorld->m_pRenderer) m_pWorld->m_pRenderer->DrawGeometry(pent->m_parts[j].pPhysGeomProxy->pGeom, &gwd[1], 4);

                                if (icnt=pCurCyl->Intersect(pPrecompParts[j1].pgeom, gwd+igwd,gwd+1, &ip, pcontacts)) {
                                    const uint32 uFlags = m_flags;
                                    for(ncont=0; ncont<icnt-1 && pcontacts[ncont].dir*(pcontacts[ncont].pt-gwd[0].offset)>0; ncont++);
                                    if ((pos0-m_pos).len2()>sqr(0.001f)) {//m_pos-posncont==icnt) {
                                        gwd[0].offset+=m_pos-pos; move-=m_pos-pos; pos=m_pos;
                                        pos0=m_pos; goto retry_without_ground_sync;    // if we made SyncWithGroundCollider and it caused intersections, roll it back
                                        //continue;
                                    }
                                    if (iCyl==0 && bHeavy && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                        const int bVeryHeavyFlags = (~(-isneg(minv*2-fMassInv))) | pent->m_flags;
                                        if (m_pWorld->m_bWorldStep==2) { // this means step induced by rigid bodies moving around
                                            // if the entity is rigid, store the contact
                                            int bPushOther;
                                            if (bPushOther = iSimClass>0 && minv>0) {// && pent->m_iGroup==m_pWorld->m_iCurGroup) {
                                                nUnproj = min(nUnproj+1,(int)(CRY_ARRAY_COUNT(unproj)));
                                                unproj[nUnproj-1].pent = pent;
                                                unproj[nUnproj-1].ipart = j;
                                                unproj[nUnproj-1].pt = pcontacts[ncont].pt;
                                                unproj[nUnproj-1].n = pcontacts[ncont].n;
                                                unproj[nUnproj-1].center = gwd[0].offset;
                                                unproj[nUnproj-1].penetration = pcontacts[ncont].t;
                                            }    else if (!(bVeryHeavyFlags & pef_cannot_squash_players))    {
                                                m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                                if (iSimClass>0)
                                                    ncontactSum = pcontacts[ncont].n;
                                            }

                                            // check previous contacts from this frame, register in entity if there are conflicts
                                            for(icnt=0; icnt<nUnproj-bPushOther; icnt++) {
                                                const float fUnprojDotContact = unproj[icnt].n*pcontacts[ncont].n;
                                                if (fUnprojDotContact<0) {
                                                    RegisterUnprojContact(unproj[icnt]);
                                                    if (bPushOther)
                                                        RegisterUnprojContact(unproj[nUnproj-1]);
                                                    if (!((bVeryHeavyFlags|unproj[icnt].pent->m_flags) & pef_cannot_squash_players))
                                                        m_bSquashed = min(5, m_bSquashed+5*isneg(max(5*minv-fMassInv, fUnprojDotContact+0.99f)));
                                                }  
                                            }
                                        } else if (!(bVeryHeavyFlags & pef_cannot_squash_players)) {
                                            m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                            if (iSimClass>0)
                                                ncontactSum = pcontacts[ncont].n;
                                        }

                                        if (uFlags & pef_pushable_by_players) {
                                            (minv==0 ? bStaticUnproj:bDynUnproj)++;
                                            Vec3 offs = pcontacts[ncont].dir*(pcontacts[ncont].t+m_pWorld->m_vars.maxContactGapPlayer);
                                            pos += offs; gwd[0].offset += offs;
                                            bUnprojected = 1;
                                            if (pcontacts[ncont].t>m_size.x)
                                                ip.ptOutsidePivot[0].Set(1E11f,1E11f,1E11f);
                                        }
                                    }

                                    if (iSimClass==2) {
                                        Matrix33 K;
                                        K.SetZero();
                                        if (uFlags & pef_pushable_by_players)
                                            GetContactMatrix(pcontacts[ncont].center, 0, K);
                                        int bPushOther = (uFlags & lef_push_objects) && (pent->m_flags & pef_pushable_by_players);
                                        bPushOther |= iszero(iSimClass-2);
                                        bPushOther &= iszero((int)(INT_PTR)pent-(int)(INT_PTR)m_pLastGroundCollider)^1;
                                        if (bPushOther)
                                            pent->GetContactMatrix(pcontacts[ncont].center, j, K);
                                        else if (!(uFlags & pef_pushable_by_players))
                                            continue;
                                        pcontacts[ncont].center -= pcontacts[ncont].dir*pcontacts[ncont].t;
                                        ncontact = -pcontacts[ncont].n;//(gwd[0].offset-pcontacts[ncont].center).normalized();
                                        if (fabs_tpl(ncontact.z)<0.5f) {
                                            ncontact.z=0; ncontact.normalize();
                                        }
                                        RigidBody *pbody = pent->GetRigidBody(j);
                                        vrel = ncontact*(pbody->v+(pbody->w^pcontacts[ncont].center-pbody->pos)-vel-m_velGround);
                                        if (iCyl==0 || fabs_tpl(vrel)*time_interval>m_size.x*0.2f) {
                                            vrel = max(0.0f,vrel-ncontact*(vel+m_velGround));
                                            float imp=vrel/max(1e-6f,ncontact*K*ncontact);
                                            ai.impulse = ncontact*imp;
                                            ai.point = pcontacts[ncont].center;    ai.ipart = 0;
                                            if (ai.impulse.len2()*sqr(fMassInv) > max(1.0f,sqr(vrel)))
                                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                                            if ((uFlags & (pef_pushable_by_players|geom_no_coll_response)) == pef_pushable_by_players)
                                                vel += ai.impulse*fMassInv;
                                            /*if (vel.z>-5) {
                                            vel.z = max(0.0f, vel.z); vel.z += ai.impulse.len()*fMassInv*0.1f;
                                            }*/
                                            bFlying = 1; m_timeFlying = 0;
                                            if (m_kInertia==0)
                                                m_timeForceInertia = m_timeImpulseRecover;
                                            if (bPushOther) {
                                                if (fabs_tpl(pcontacts[ncont].dir*axis)<0.7f)
                                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                                ai.impulse.Flip(); ai.ipart = j;
                                                //if (pent->GetType()<PE_LIVING)
                                                //    ai.impulse *= 0.2f;
                                                pent->Action(&ai,1);
                                                m_timeSinceImpulseContact = 0;
                                            }
                                            idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont].id[1]>>31 | max(pcontacts[ncont].id[1],0);
                                            RegisterContact(pos,pcontacts[ncont].pt,ncontact,pent,j,idmat,imp,0,pcontacts[ncont].iPrim[1]);
                                        }
                                    }
                                    //break;
                                }
                            }
                    }
                }
            }
            if (bStaticUnproj && bDynUnproj && m_bSquashed) {
                pos = pos0; // disable unprojection if we are being squashed
                bStaticUnproj = bDynUnproj = 0;
            }
            else if (bStaticUnproj+bDynUnproj>0) {
                newpos = pos+move;
            }
          
            float h = ShootRayDown(pPrecompEnts,nents,pPrecompParts,newpos,nslope);
            float hcur = newpos*axis-m_hPivot;
            const float fAxisDotSlope = axis*nslope;
            if (fAxisDotSlope>m_slopeFall &&
                    (hcur<h && hcur>h-(m_hCyl-m_size.z)*1.01f ||
                     hcur>h && sqr_signed(hcur-h)<vel.len2()*sqr(time_interval) && !bFlying && !m_bJumpRequested && !m_bSwimming))
            {
                if (h>hcur && m_nslope*axis<m_slopeSlide && m_nslope*nslope<m_slopeSlide &&
                        fAxisDotSlope<m_slopeSlide && m_velRequested.len2()==0)
                {  
                    newpos = pos; vel.zero();
                }    else
                    newpos += (heightAdj = axis*(h+m_hPivot-newpos*axis));
                move = newpos-pos; movelen = move.len();
            }
            pos0 = pos;
            if (m_bJumpRequested)
                AddLegsImpulse(-vel,m_nslope,true);
            m_bJumpRequested = 0;
            m_bStuck = 0; ncontactSum.zero();

            if (movelen>m_size.x*1E-4f && m_parts[0].flagsCollider!=0) {
                ip.bSweepTest = true;
                gwd[0].v = move/movelen;
                int iter = 0;
                float move0 = movelen; movesum = 0;
                pe_player_dimensions pd;

                do {
                    float tlim = 0.0f;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    ip.time_interval = movelen+m_pWorld->m_vars.maxContactGapPlayer; tmin = ip.time_interval*2;    iPrim = -1;
                    pNRC = pNoResponseContactLE; pNRC->pent = NULL; pNRC->tmin = tmin;
                    for(i=0; i<nents; ++i) {
                        if (pPrecompEnts[i].entType!=PE_LIVING ||
                                pPrecompEnts[i].nParts - iszero((int)(pPrecompParts[pPrecompEnts[i].iLastPart].partflags & collider_flags)) > 1-bHasExtraParts ||
                                max(sqr(m_qrot.v.x)+sqr(m_qrot.v.y),sqr(pPrecompEnts[i].pent->m_qrot.v.x)+sqr(pPrecompEnts[i].pent->m_qrot.v.y))>0.001f)
                        {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            int bCheckBBox=pPrecompEnts[i].bCheckBBox;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1) {
                                const uint32 uPartFlags = pPrecompParts[j1].partflags;
                                if (uPartFlags & (collider_flags|geom_log_interactions) &&
                                    (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))
                                {
                                    if (uPartFlags & geom_log_interactions) {
                                        EventPhysBBoxOverlap event;
                                        event.pEntity[0]=this; event.pForeignData[0]=m_pForeignData; event.iForeignData[0]=m_iForeignData;
                                        event.pEntity[1]=pent; event.pForeignData[1]=pent->m_pForeignData; event.iForeignData[1]=pent->m_iForeignData;
                                        m_pWorld->OnEvent(m_flags, &event);
                                        if (!(uPartFlags & collider_flags))
                                            continue;
                                    }
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;

                                    int ipart = 0;
                                    if((ncont = m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)))
                                        got_contact:
                                        if (pcontacts[ncont-1].t<tmin && pcontacts[ncont-1].n*gwd[0].v>0)    {
                                            if (!((pPrecompParts[j1].partflags | m_parts[ipart].flags)&geom_no_coll_response)) {
                                                // Solid contact
                                                tmin = pcontacts[ncont-1].t; tlim=0.0f; ncontact = -pcontacts[ncont-1].n; ptcontact = pcontacts[ncont-1].pt; iPrim = pcontacts[ncont-1].iPrim[1];
                                                pentmin=pent; jmin=pPrecompParts[j1].ipart; idmat=pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0); ipartMin=ipart;
                                            } else if (pcontacts[ncont-1].t<pNRC->tmin) {
                                                // Non-response contact
                                                pNRC->pent = pent; pNRC->tmin = pcontacts[ncont-1].t;
                                                pNRC->ptcontact = pcontacts[ncont-1].pt; pNRC->ncontact = -pcontacts[ncont-1].n;
                                                pNRC->ipart = pPrecompParts[j1].ipart; pNRC->iPrim = pcontacts[ncont-1].iPrim[1];
                                                pNRC->idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0);
                                            }
                                        }
                                    for(ipart++; ipart<(m_nParts&-bHasExtraParts); ipart++) if (m_parts[ipart].flagsCollider & uPartFlags) {
                                        gwd[2].R = Matrix33(m_qrot*m_parts[ipart].q);
                                        gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[ipart].pos;
                                        gwd[2].scale = m_parts[ipart].scale; gwd[2].v = gwd[0].v;
                                        if((ncont = m_parts[ipart].pPhysGeomProxy->pGeom->Intersect(pPrecompParts[j1].pgeom, gwd+2,gwd+1, &ip, pcontacts)))
                                            goto got_contact;
                                    }
                                }
                            }
                        }    else {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            pent->GetParams(&pd);
                            Vec2 dorigin,ncoll,move2d=(Vec2)gwd[0].v;
                            dorigin = Vec2(pos-pent->m_pos);
                            float kb=dorigin*move2d, kc=len2(dorigin)-sqr(m_size.x+pd.sizeCollider.x), kd=kb*kb-kc, zup0,zdown0,zup1,zdown1;
                            if (kd>=0) {
                                zup0 = (zdown0 = pos.z-m_hPivot)+m_hCyl+m_size.z+m_size.x*m_bUseCapsule;
                                zdown0 = max(zdown0, zup0-(m_size.x*m_bUseCapsule+m_size.z)*2);
                                zup1 = (zdown1 = pent->m_pos.z-pd.heightPivot)+pd.heightCollider+pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule;
                                zdown1 = max(zdown1, zup1-(pd.sizeCollider.x*pd.bUseCapsule+pd.sizeCollider.z)*2);
                                kd=sqrt_tpl(kd);
                                float tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                bool bSideContact = min(zup0+gwd[0].v.z*tfirst,zup1)>max(zdown0+gwd[0].v.z*tfirst,zdown1);
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d>=0 && bSideContact)
                                    continue;    // if entities separate during this timestep, ignore other collisions
                                tfirst=-kb-kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                /*if (tfirst<-m_size.x || min(zup0+gwd[0].v.z*tfirst,zup1)<max(zdown0+gwd[0].v.z*tfirst,zdown1) || ncoll*move2d>=0) {
                                    tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                }*/
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d<0 && bSideContact) {
                                    tlim = (tmin = tfirst)*iszero(iter); ncontact.Set(ncoll.x,ncoll.y,0).normalize(); ptcontact = pos+gwd[0].v*tfirst-ncontact*m_size.x;
                                    pentmin=pent; jmin=0; idmat=m_surface_idx; iPrim=-1; ipartMin=0;
                                }
                                // also check for cap-cap contact
                                if (fabs_tpl(gwd[0].v.z)>m_size.z*1E-5f) {
                                    int nSignZ = sgnnz(gwd[0].v.z);    //Could be float?
                                    zup0 = pos.z-m_hPivot+m_hCyl+(m_size.z+m_size.x*m_bUseCapsule)*nSignZ;
                                    zdown1 = pent->m_pos.z-pd.heightPivot+pd.heightCollider-(pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule)*nSignZ;
                                    tfirst = zdown1-zup0;
                                    if (inrange(tfirst,-m_size.x*gwd[0].v.z,tmin*gwd[0].v.z) &&
                                            len2(dorigin*gwd[0].v.z+move2d*tfirst)<sqr((m_size.x+pd.sizeCollider.x)*gwd[0].v.z))
                                    {
                                        tmin = tfirst/gwd[0].v.z; ncontact.Set(0,0,-nSignZ); (ptcontact = pos+gwd[0].v*tfirst).z += m_size.z*nSignZ; //?
                                        pentmin=pent; jmin=-1; idmat=m_surface_idx; iPrim=-1;    ipartMin=0;
                                    }
                                }
                            }
                        }
                        if (pNRC->pent) {
                            IF (pNRC>=(pNoResponseContactLE+nNoResponseAllocLE-1), 0) {
                                delete [] pNoResponseContactLE; pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE+16];
                                pNRC=pNoResponseContactLE+nNoResponseAllocLE-1; nNoResponseAllocLE+=16;
                            }
                            ++pNRC; pNRC->pent=NULL; pNRC->tmin=ip.time_interval*2;
                        }
                    }

                    if (tmin<=ip.time_interval) {
                        tmin = max(tlim,tmin-m_pWorld->m_vars.maxContactGapPlayer);
                        pos += gwd[0].v*tmin;
                        static const float g_cosSlide=cos_tpl(0.3f), g_sinSlide=sin_tpl(0.3f);
                        /*if (bFlying) {
                            if ((ncontact*axis)*(1-m_bSwimming)>g_cosSlide)
                                ncontact = axis*g_cosSlide + (pos-ptcontact-axis*(axis*(pos-ptcontact))).normalized()*g_sinSlide;
                        } else */
                        if (!bFlying && inrange(ncontact*axis, 0.85f,-0.1f) && (unsigned int)pentmin->m_iSimClass-1u<2u &&
                            pentmin->GetMassInv()>m_massinv*0.25f)
                            ncontact.z=0, ncontact.normalize();
                        int bPush = pentmin->m_iSimClass>0 || isneg(min(m_slopeClimb-ncontact*axis, ncontact*axis+m_slopeFall)) | bFlying;
                        int bUnmovable = isneg(-pentmin->m_iSimClass>>31 & ~(-((int)m_flags & pef_pushable_by_players)>>31));
                        bPush &= bUnmovable^1;
                        {
                            Matrix33 K;
                            K.SetZero();
                            int bPushOther = (m_flags & (pentmin->m_iSimClass==3 ? lef_push_players : lef_push_objects)) &&
                                (pentmin->m_flags & pef_pushable_by_players) &&
                                (pentmin->m_iSimClass | m_pWorld->m_vars.bPlayersCanBreak | pentmin->m_flags & pef_players_can_break);
                            bPushOther &= iszero((int)(INT_PTR)pentmin-(int)(INT_PTR)m_pLastGroundCollider)^1;
                            bPushOther |= bUnmovable;
                            if (bPushOther)
                                pentmin->GetContactMatrix(ptcontact, jmin, K);
                            if (!bPushOther || /*pentmin->m_iSimClass-3 | */m_flags & pef_pushable_by_players)
                                GetContactMatrix(ptcontact, -1, K);
                            else
                                bPush = 0;
                            vrel = ncontact*(vel+m_velGround); //(ncontact*gwd[0].v)*vel.len();
                            ai.impulse = ncontact;
                            if (pentmin->m_iSimClass==3) {
                                // make the player slide off when standing on other players
                                vrel -= ncontact*((CLivingEntity*)pentmin)->m_vel;
                                if (ncontact*axis > 0.95f) {
                                    ai.impulse += (pos-pentmin->m_pos-axis*(axis*(pos-pentmin->m_pos))).normalized();
                                    if (inrange(vrel,-1.0f,1.0f))
                                        vrel = -1.0f;
                                }
                            } else {
                                RigidBody *pbody = pentmin->GetRigidBody(jmin);
                                vrel -= ncontact*(pbody->v+(pbody->w^ptcontact-pbody->pos));
                            }
                            vrel = min(0.0f, vrel);
                            float imp = -vrel*1.01f/max(1e-6f,ncontact*K*ncontact);
                            jmin -= jmin>>31;
                            if (bPush || m_flags & lef_report_sliding_contacts || pentmin->m_parts[jmin].flags & geom_manually_breakable)
                                RegisterContact(pos,ptcontact,ncontact,pentmin,jmin,idmat,imp*bPush,0,iPrim,ipartMin);
                            ai.impulse *= imp;
                            ai.point = ptcontact;    ai.ipart = 0;
                            if (ai.impulse.len2()*sqr(m_massinv) > max(1.0f,sqr(vrel)))
                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                            if (bPush) {
                                vel += ai.impulse*m_massinv;
                                if (m_kInertia==0 && (pentmin->m_iSimClass-3 | m_flags & pef_pushable_by_players))
                                    m_timeForceInertia = m_timeImpulseRecover;
                            }
                            if (bPushOther) {
                                ai.impulse.Flip(); ai.ipart = jmin;
                                if (fabs_tpl(ncontact*axis)<0.7f)
                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                ai.iApplyTime = isneg(pentmin->m_iSimClass-3)<<1;
                                if (pentmin->GetType()<PE_LIVING)
                                    ai.impulse *= 0.2f;
                                pentmin->Action(&ai);
                                if (pentmin->m_iSimClass<3)
                                    m_timeSinceImpulseContact = 0;
                            }
                        }
                        movelen -= tmin; movesum += tmin;
                        for(i=0;i<iter && ncontactHist[i]*ncontact<0.95f;i++);
                        if (i==iter)
                            ncontactSum += ncontact;
                        ncontactHist[iter] = ncontact;
                        if (iter==1 && movesum==0.0f) {
                            ncontact = (ncontactHist[0]^ncontactHist[1]).normalized();
                            gwd[0].v = ncontact*(gwd[0].v*ncontact);
                        }    else {
                            gwd[0].v -= ncontact*(gwd[0].v*ncontact);
                            gwd[0].v = gwd[0].v*0.9998f+ncontact*(gwd[0].v.len()*0.02f);
                        }
                        tmin = gwd[0].v.len(); movelen*=tmin;
                        if (tmin>0) gwd[0].v/=tmin;
                        movelen = (float)__fsel(gwd[0].v*move, movelen, 0.0f);
                    } else {
                        pos += gwd[0].v*movelen; movesum += movelen; /* exit do-loop */ iter=1000;
                    }
                    for (le_tmp_contact* c=pNoResponseContactLE; c<=pNRC && c->pent; c++)
                        if (c->tmin<tmin)
                            RegisterContact(pos,c->ptcontact,c->ncontact,c->pent,c->ipart,c->idmat,0.f,0,c->iPrim);
                } while(movelen>m_pWorld->m_vars.maxContactGapPlayer*0.1f && ++iter<3);

                const float fContactSumLenSq = ncontactSum.len2();
                if(movesum<move0*0.001f && (sqr_signed(ncontactSum.z)>sqr(0.4f)*fContactSumLenSq || fContactSumLenSq<0.6f))
                    m_bStuck = 1;

                if (m_parts[0].flagsCollider!=0 && (bUnprojected || !(m_flags & lef_loosen_stuck_checks))) {
                    ip.bSweepTest = false;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    gwd[0].v = -axis;
                    ip.bStopAtFirstTri = true; ip.bNoBorder = true; ip.time_interval = m_size.z*10;
                    for(i=0; i<nents; ++i)
                        if (pPrecompEnts[i].iSimClass==0) {
                            CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                                if (pPrecompParts[j1].partflags & collider_flags && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;
                                    if(m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)) {
                                    if (pcontacts->t>m_pWorld->m_vars.maxContactGapPlayer)
                                        vel.zero(),m_bStuck=1;  
                                    pos = pos0; m_timeUseLowCap=1.0f;
                                    goto nomove;
                                }
                            }
                    } nomove:;
                }
            } else
                pos += move;

            if (!m_pLastGroundCollider)// || m_pLastGroundCollider->GetMassInv()>m_massinv)
                velGround.zero();
            else
                velGround = m_velGround;
            m_hLatest = h = ShootRayDown(pPrecompEnts, nents, pPrecompParts, pos,nslope, time_interval,false,true);
            if (nslope*axis<0.087f)
                nslope = m_nslope;
            else {
                WriteLockCond lock(m_lockLiving,m_bStateReading^1);
                m_nslope = nslope;
            }
            if (m_pLastGroundCollider) {
                RegisterContact(newpos,newpos,m_qrot*Vec3(0,0,1),m_pLastGroundCollider,m_iLastGroundColliderPart,m_lastGroundSurfaceIdx,0,1,m_lastGroundPrim);
                if (m_pLastGroundCollider->m_iSimClass==0)
                    ReleaseGroundCollider();
            }

            if (bFlying)
                m_timeFlying += time_interval;
            int bGroundContact = isneg(max(pos*axis-m_hPivot-(h+m_groundContactEps), m_slopeFall-nslope*axis));
            if (!bGroundContact)
                ReleaseGroundCollider();

            bFlying = m_pWorld->m_vars.bFlyMode || m_gravity*axis>0 || m_bSwimming || ((bGroundContact|m_bStuck)^1);
            m_bActiveEnvironment = m_bStuck;

            if (bFlying)
                Step_HandleFlying(vel, velGround, bWasFlying, heightAdj, kInertia, time_interval);
            else {
                if (bWasFlying)
                    Step_HandleWasFlying(vel, bFlying, axis, bGroundContact);
              
                Vec3 velReq = m_velRequested,g;
                if (!m_bSwimming) velReq -= m_nslope*(velReq*m_nslope);
                if (kInertia * time_interval > 1.0f)    kInertia = 1.0f/time_interval;
                Vec3 last_force = (velReq-vel)*kInertia;
                const float axisSlope = m_nslope*axis;
                if (axisSlope<m_slopeSlide && !m_bSwimming)    {
                    g = m_gravity;
                    last_force += g-m_nslope*(g*m_nslope);
                }
              
                const Vec3 velIncLastForce = vel + (last_force*time_interval);
                if (velIncLastForce*vel<0 && velIncLastForce*m_velRequested<=0)
                    vel.zero();
                else
                    vel = velIncLastForce;

                if (axisSlope<m_slopeClimb) {
                    const float axisVel = vel*axis;
                    if (axisVel>0 && last_force*axis>0)
                        vel -= axis*(axisVel);
                    if ((pos-pos0)*axis > m_size.z*0.001f)
                        vel -= axis*(axis*vel);
                }
                if (axisSlope<m_slopeFall && !m_bStuck) {
                    bFlying=1; vel += m_nslope-axis*(axisSlope);
                }
                if (m_velRequested.len2()==0 && vel.len2()<0.001f || vel.len2()<0.0001f)
                    vel.zero();
            }

            if (!bFlying)
                m_timeFlying = 0;

            if (m_flags & lef_snap_velocities)
                vel = DecodeVec6b(EncodeVec6b(vel));

            if (!m_bStateReading) {
                float dh;
                if (!bFlying && (dh=(pos-pos0)*axis)>m_size.z*0.01f) {
                    m_dhSpeed = max(m_dhSpeed, dh/m_stablehTime);
                    m_dh += dh;
                    m_stablehTime = 0;
                }    else
                    dh = 0;
                m_stablehTime = min(m_stablehTime+time_interval,0.5f);

                m_dhSpeed += m_dhAcc*time_interval;
                if (m_dhAcc==0 && m_dh*m_dhSpeed<0 || m_dh*m_dhAcc<0 || m_dh*(m_dh-m_dhSpeed*time_interval)<0)
                    m_dh = m_dhSpeed = m_dhAcc = 0;
                else
                    m_dh -= m_dhSpeed*time_interval;
            }

            if (m_pHeadGeom) {
                ip.bSweepTest = true;
                gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                gwd[0].v = axis;
                tmin = ip.time_interval = m_hHead-m_hCyl-min(m_dh,0.0f);
                for(i=0;i<nents;i++) if (pentlist[i]->m_iSimClass==0) {//pentlist[i]->GetType()!=PE_LIVING && pentlist[i]->GetMassInv()*0.4f<m_massinv) {
                    for(int j1=0;j1<pentlist[i]->GetUsedPartsCount(iCaller);j1++)
                        if (pentlist[i]->m_parts[j=pentlist[i]->GetUsedPart(iCaller,j1)].flags & collider_flags) {
                            Matrix33 rotMat = Matrix33(pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q);
                            gwd[1].R = rotMat;
                            gwd[1].offset = pentlist[i]->m_pos + rotMat*pentlist[i]->m_parts[j].pos;
                            gwd[1].scale = pentlist[i]->m_parts[j].scale;
                            if(m_pHeadGeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts))
                                tmin = min(tmin,(float)pcontacts[0].t);
                        }
                }
                if (m_dh<ip.time_interval+min(m_dh,0.0f)-tmin || fabs_tpl(m_dhSpeed)+fabs_tpl(m_dhAcc)==0)
                    m_dh = ip.time_interval+min(m_dh,0.0f)-tmin;
            }
        }
      
        coord_block_BBox partCoord;
        ComputeBBoxLE(pos,BBoxInner,&partCoord);
        UpdatePosition(pos,BBoxInner, m_pWorld->RepositionEntity(this,1,BBoxInner));
        bMoving = 1;
    } else if (!m_bActive) {
        if (m_velRequested.len2()>0) {
            m_pos += m_velRequested*time_interval;
            m_BBox[0] += m_velRequested*time_interval; m_BBox[1] += m_velRequested*time_interval;
            JobAtomicAdd(&m_pWorld->m_lockGrid,-m_pWorld->RepositionEntity(this,1));
            bMoving = 1;
        }
        if (m_bReleaseGroundColliderWhenNotActive!=0)
            ReleaseGroundCollider();
    }
  
    { WriteLockCond lock(m_lockLiving,m_bStateReading^1);
        //if (m_pWorld->m_vars.bMultiplayer)
        //    m_pos = CompressPos(m_pos);
      
        m_deltaV        = (m_vel - vel0);
        m_vel                = vel+m_vel-vel0;      
        m_bFlying        = bFlying;
        m_deltaQRot = m_qrot * !oldQRot;

        m_timeSmooth = (float)__fsel(-time_interval, m_timeSmooth, time_interval);
        if (m_pWorld->m_bUpdateOnlyFlagged) {
            m_deltaPos = m_posLocal-m_pos;
            if (m_deltaPos.len2()<sqr(0.01f) || m_deltaPos.len2()>sqr(2.0f))
                m_deltaPos.zero();
        }
        if (m_pBody)
            if (!m_nColliders) {
                delete m_pBody; m_pBody=0;
            } else {
                m_pBody->pos=m_pos+m_qrot*Vec3(0,0,m_hCyl); m_pBody->q=m_qrot;
                m_pBody->P=(m_pBody->v=m_vel)*(m_pBody->M=m_mass);
                m_pBody->Minv=m_massinv;
                if (m_pWorld->m_timePhysics > m_timeRotChanged+0.05f)
                    m_pBody->w.zero(), m_pBody->L.zero();
                /*quaternionf dq = m_history[m_iHist].q*!m_history[m_iHist-3&m_szHistory-1].q;
                float dt=0; for(i=0; i<4; i++)
                    dt += m_history[m_iHist-i&m_szHistory-1].dt;
                if (inrange(dt, 0.0f,1.0f)) {
                    if (dq.v.len2()<sqr(0.05f))
                        m_pBody->w = dq.v*(2/dt);
                    else
                        m_pBody->w = dq.v.normalized()*(acos_tpl(dq.w)*2/dt);
                }*/
            }
    }

    if (!m_bStateReading) {
        if( bMoving )    {
            Vec3 gravity; MARK_UNUSED gravity;
            pe_params_buoyancy pb;
            m_pWorld->CheckAreas(this,gravity,&pb,0);
            if (!is_unused(gravity))
                m_gravity = gravity;

            if (m_pWorld->m_pWaterMan)
                m_pWorld->m_pWaterMan->OnWaterInteraction(this);
        }

        if (m_flags & (pef_monitor_poststep | pef_log_poststep)) {
            EventPhysPostStep epps;
            epps.pEntity=this; epps.pForeignData=m_pForeignData; epps.iForeignData=m_iForeignData;
            epps.dt=time_interval; epps.pos=m_pos; epps.q=m_qrot; epps.idStep=m_pWorld->m_idStep;
            epps.pos -= m_qrot*Vec3(0,0,m_dh);
            m_pWorld->OnEvent(m_flags,&epps);
        }
        /*if (m_pWorld->m_iLastLogPump > m_timeLogged)
            m_posLogged = pos0;
        m_timeLogged = m_pWorld->m_iLastLogPump;*/
    }

    return 1;
}

Many italians worked as coders for crytek. The cryengine is bound to be a complete mess.
 

DraQ

Arcane
Joined
Oct 24, 2007
Messages
32,828
Location
Chrząszczyżewoszyce, powiat Łękołody
https://github.com/CRYTEK-CRYENGINE/CRYENGINE
That's right, it get open sourced. The first version.
I'm not a fan of their games but if that mean less usage of Unity the better...
Imagine dungeon crawlers in this engine.

It's called Cry Engine because the code makes you cry.

For example, this is ONE function
https://github.com/CRYTEK-CRYENGINE...e/CryEngine/CryPhysics/livingentity.cpp#L1300

Code:
int CLivingEntity::Step(float time_interval)
{
    if (time_interval<=0)
        return 1;
    float dt = m_timeStepFull-m_timeStepPerformed;
    time_interval = m_pWorld->m_bWorldStep==2 ? min(time_interval, dt) : dt;
    time_interval = max(time_interval, 0.001f);

    const int iCaller = get_iCaller_int();
    int i,j,jmin,ipartMin,nents,ncont,bFlying,bWasFlying,bUnprojected,idmat,iPrim, bHasExtraParts=0,
        bHasFastPhys,icnt,nUnproj,bStaticUnproj,bDynUnproj,bMoving=0,nPrecompEnts=0,nPrecompParts=0, nUsedPartsCount=0,
        &nNoResponseAllocLE=m_pWorld->m_threadData[iCaller].nNoResponseAllocLE,
        &nPrecompEntsAlloc=m_pWorld->m_threadData[iCaller].nPrecompEntsAllocLE,&nPrecompPartsAlloc=m_pWorld->m_threadData[iCaller].nPrecompPartsAllocLE;
    const Quat oldQRot = m_qrot;
    Vec3 pos,vel,pos0,vel0,newpos,move(ZERO),nslope,ncontactHist[4],ncontact,ptcontact,ncontactSum,BBoxInner[2],velGround,axis,sz,heightAdj=Vec3(0.f);
    float movelen,tmin,vrel,movesum,kInertia;
    le_precomp_entity *&pPrecompEnts=m_pWorld->m_threadData[iCaller].pTmpPrecompEntsLE;
    le_precomp_part *&pPrecompParts=m_pWorld->m_threadData[iCaller].pTmpPrecompPartsLE;
    le_tmp_contact *&pNoResponseContactLE=m_pWorld->m_threadData[iCaller].pTmpNoResponseContactLE, *pNRC;
    le_contact unproj[8];
    CCylinderGeom CylinderGeomOuter,*pCyl[2];
    geom_world_data gwd[3];
    intersection_params ip;
    CPhysicalEntity **pentlist, *pentmin=NULL;
    geom_contact *pcontacts;
    pe_action_impulse ai;
    pe_status_dynamics sd;
    WriteLockCond lockMain(m_lockStep,m_bStateReading^1);
    ip.bNoAreaContacts = true;

    IF (nNoResponseAllocLE==0, 0) pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE=16];

    if (m_timeForceInertia>0.0001f)
        kInertia = 6.0f;
    else if (m_kInertiaAccel && m_velRequested.len2()>0.1f)
        kInertia = m_kInertiaAccel;
    else
        kInertia = m_kInertia;

    pos = m_pWorld->m_bWorldStep==2 ? m_pos : SyncWithGroundCollider(time_interval);
    vel0=vel = m_vel;
    bWasFlying = bFlying = m_bFlying;
    if (!m_bStateReading) {
        m_timeUseLowCap -= time_interval;
        m_timeSinceStanceChange += time_interval;
        m_timeSinceImpulseContact += time_interval;
        m_timeForceInertia = max(0.0f,m_timeForceInertia-time_interval);
        m_timeStepPerformed += time_interval;
    }

    if (m_bActive &&
            (!(vel.len2()==0 && m_velRequested.len2()==0 && (!bFlying || m_gravity.len2()==0) && m_dhSpeed==0 && m_dhAcc==0) ||
            m_bActiveEnvironment || m_nslope.z<m_slopeSlide || m_velGround.len2()>0))  
    {
        FUNCTION_PROFILER( GetISystem(),PROFILE_PHYSICS );
        PHYS_ENTITY_PROFILER

        m_bActiveEnvironment = 0;
        //m_nslope.Set(0,0,1);
        if (kInertia==0 && !bFlying && !m_bJumpRequested || m_pWorld->m_vars.bFlyMode) {
            vel = m_velRequested;
            vel -= m_nslope*(m_nslope*vel);
        }
        if (bFlying && !m_pWorld->m_vars.bFlyMode && m_kAirControl>0)    {
            if (kInertia>0) {
                Vec3 velDelta = m_velRequested * (m_kInertia*time_interval*m_kAirControl);
                Vec3 velDiff = m_velRequested - vel;
                  
                const float kAirControlSelect = m_kAirControl-1.0f;

                velDelta.x = (float)__fsel(-(velDiff.x * velDelta.x), 0.0f, velDelta.x);
                velDelta.y = (float)__fsel(-(velDiff.y * velDelta.y), 0.0f, velDelta.y);
                velDelta.z = (float)__fsel(-(velDiff.z * velDelta.z), 0.0f, velDelta.z);

                velDelta.x = (float)__fsel(velDiff.x, min(velDiff.x, velDelta.x), max(velDiff.x, velDelta.x));
                velDelta.y = (float)__fsel(velDiff.y, min(velDiff.y, velDelta.y), max(velDiff.y, velDelta.y));
                velDelta.z = (float)__fsel(velDiff.z, min(velDiff.z, velDelta.z), max(velDiff.z, velDelta.z));
              
                velDelta.y = (float)__fsel(kAirControlSelect, velDiff.y, velDelta.y);
                velDelta.x = (float)__fsel(kAirControlSelect, velDiff.x, velDelta.x);              

                vel += velDelta;
            } else if (m_gravity.len2()>0)
                vel = m_gravity*(vel*m_gravity-m_velRequested*m_gravity)/m_gravity.len2()+m_velRequested;
            else
                vel = m_velRequested;
        }

        //filippo:m_forceFly is to let the game set a velocity no matter what is the status of the entity.
        if (m_forceFly)
            vel = m_velRequested;
         else if (bFlying && !m_bSwimming && !m_pWorld->m_vars.bFlyMode)
             move += m_gravity*sqr(time_interval)*0.5f;

        if (vel.len2() > sqr(m_pWorld->m_vars.maxVelPlayers))
            vel.normalize() *= m_pWorld->m_vars.maxVelPlayers;
      
        move += vel*time_interval;

        m_forceFly = false;
        bUnprojected = 0;
        axis = m_qrot*Vec3(0,0,1);
        if (_isnan(move.len2())) //necessary? Is there any way that this can occur? - Rich S
            return 1;
        --m_bSquashed; m_bSquashed-=m_bSquashed>>31;

        if (m_pWorld->m_vars.iCollisionMode!=0 && m_pWorld->m_vars.bFlyMode) {    //Rich S - is bFlyMode a cheat? Can we disable in release?
            pos+=move; bFlying=1; m_hLatest=0; ReleaseGroundCollider();
        } else {

            const float fSizeX = m_size.x;
            const float fSizeZ = m_size.z;
            movelen = move.len();
            const float fGap = (movelen+m_pWorld->m_vars.maxContactGapPlayer)*1.5f;
            const Vec3 posDiff = pos - m_pos;
            BBoxInner[0] = m_BBox[0]+(posDiff)-Vec3(fGap,fGap,fGap);
            BBoxInner[1] = m_BBox[1]+(posDiff)+Vec3(fGap,fGap,fGap);
            const float fGap2 = max(10.0f*time_interval,fGap); // adds a safety margin of m_size.x width
            const Vec3 BBoxOuter0 = m_BBox[0]+(posDiff)-Vec3(fGap2,fGap2,fGap2);
            const Vec3 BBoxOuter1 = m_BBox[1]+(posDiff)+Vec3(fGap2,fGap2,fGap2);

            nents = m_pWorld->GetEntitiesAround(BBoxOuter0,BBoxOuter1,
                pentlist, m_collTypes|ent_independent|ent_triggers|ent_sort_by_mass, this, 0,iCaller);

            if (m_vel.len2()) for(i=0;i<m_nColliders;i++) if (m_pColliders[i]->HasConstraintContactsWith(this,constraint_inactive))
                m_pColliders[i]->Awake();

            const float fMassInv = m_massinv;
            for(i=j=bHasFastPhys=0,vrel=0; i<nents; i++) if (!m_pForeignData || pentlist[i]->m_pForeignData!=m_pForeignData){
                Vec3 size = pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0];
                int bFastPhys = 0;
                if (IgnoreCollision(m_collisionClass, pentlist[i]->m_collisionClass))
                    continue;
                if (pentlist[i]->m_iSimClass==2) {
                    if (pentlist[i]->m_flags & ref_small_and_fast)
                        continue;
                    else if (pentlist[i]->GetMassInv()*0.4f<fMassInv) {
                        pentlist[i]->GetStatus(&sd);
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(size.x,size.y),size.z));;
                        bHasFastPhys |= (bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval));
                    }
                }
                if (!bFastPhys && !AABB_overlap(pentlist[i]->m_BBox,BBoxInner) && size.len2()>0)
                    continue;
                idmat = pentlist[i]->GetType();
                if (idmat==PE_SOFT || idmat==PE_ROPE)
                    pentlist[i]->Awake();
                else if (pentlist[i]->m_iSimClass<4 &&
                    (idmat!=PE_LIVING && !pentlist[i]->IgnoreCollisionsWith(this,1) ||
                     idmat==PE_LIVING && pentlist[i]->m_parts[0].flags&collider_flags &&
                     pentlist[i]!=this && m_pLivingEntToIgnore!=pentlist[i] && ((CLivingEntity*)pentlist[i])->m_pLivingEntToIgnore!=this))
                {
                    if (pentlist[i]->m_iSimClass==1 && m_timeSinceImpulseContact<0.2f && pentlist[i]->GetMassInv()>0)    {
                        int ipart; unsigned int flags;
                        for(ipart=0,flags=0; ipart<pentlist[i]->m_nParts; ipart++)
                            flags |= pentlist[i]->m_parts[ipart].flags;
                        if (flags & collider_flags)
                            pentlist[i]->Awake();
                    }
                    pentlist[j++] = pentlist[i];
                }
            }
            nents = j;
            pos0 = pos;
            bStaticUnproj = bDynUnproj = 0;
            newpos = pos+move;

            IF (nents>nPrecompEntsAlloc, 0) delete[] pPrecompEnts, pPrecompEnts=new le_precomp_entity[nPrecompEntsAlloc=nents];
            for(i=0; i<nents; i++) {
                le_precomp_entity &ent = pPrecompEnts[nPrecompEnts++];
                ent.BBox[0]=pentlist[i]->m_BBox[0];
                ent.BBox[1]=pentlist[i]->m_BBox[1];
                ent.sz=(sz=pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0]);
                ent.bCheckBBox=sz.len2()>0;
                ent.massinv=pentlist[i]->GetMassInv();
                ent.entType=pentlist[i]->GetType();
                ent.iSimClass=pentlist[i]->m_iSimClass;
                ent.pent=pentlist[i];
                ent.nParts=pentlist[i]->m_nParts;
                ent.ignoreCollisionsWith=pentlist[i]->IgnoreCollisionsWith(this,1);
                ent.iPartsBegin=nPrecompParts;
                ent.iPartsEnd=nPrecompParts+(nUsedPartsCount=pentlist[i]->GetUsedPartsCount(iCaller));
                IF (ent.iPartsEnd>nPrecompPartsAlloc, 0) {
                    ReallocateList(pPrecompParts, nPrecompParts, ent.iPartsEnd+128);
                    nPrecompPartsAlloc=ent.iPartsEnd+128;
                }
                for(int j1=0; j1<nUsedPartsCount; j1++) {
                    le_precomp_part &part = pPrecompParts[nPrecompParts++];
                    part.BBox[0]=pentlist[i]->m_parts[part.ipart=j=pentlist[i]->GetUsedPart(iCaller,j1)].BBox[0];
                    part.BBox[1]=pentlist[i]->m_parts[j].BBox[1];
                    part.partrot=pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q;
                    part.partoff=pentlist[i]->m_pos + pentlist[i]->m_qrot*pentlist[i]->m_parts[j].pos;
                    part.partscale=pentlist[i]->m_parts[j].scale;  
                    part.partflags=pentlist[i]->m_parts[j].flags;
                    part.pgeom=pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom;
                    part.surface_idx=pentlist[i]->m_parts[j].surface_idx;
                    ent.iLastPart=nPrecompParts-1;
                }
            }
      
            // first, check if we need unprojection in the initial position
            if (sqr(m_qrot.v.x)+sqr(m_qrot.v.y)<sqr(0.001f))
                gwd[0].R.SetIdentity();
            else
                gwd[0].R = Matrix33(m_qrot);
            gwd[0].centerOfMass = gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
            gwd[0].v.zero(); gwd[0].w.zero(); // since we check a static character against potentially moving environment here
            ip.vrel_min = fSizeX;
            ip.time_interval = time_interval*2;
            ip.maxUnproj = fSizeX*2.5f;
            ip.ptOutsidePivot[0] = gwd[0].offset;
            pCyl[0] = m_pCylinderGeom;
            if (bHasFastPhys) {
                cylinder cylOuter;
                cylOuter.r = fSizeX+min(fSizeX*1.5f,vrel*time_interval);
                cylOuter.hh = fSizeZ+min(fSizeZ,vrel*time_interval);
                cylOuter.center.zero();
                cylOuter.axis.Set(0,0,1);
                CylinderGeomOuter.CreateCylinder(&cylOuter);
                pCyl[1] = &CylinderGeomOuter;
            }

            retry_without_ground_sync:
            if (m_parts[0].flagsCollider) {
                for(i=nUnproj=0,ncontactSum.zero();i<nents;++i)
                    if (pPrecompEnts[i].entType!=PE_LIVING) {
                    const float minv = pPrecompEnts[i].massinv;
                    const int bHeavy = isneg(minv*0.4f-fMassInv);
                    const int iSimClass = pPrecompEnts[i].iSimClass;
                    CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                    int bFastPhys = 0;
                    if (bHasFastPhys && bHeavy && iSimClass==2 && pent!=m_pLastGroundCollider) {
                        pent->GetStatus(&sd);
                        const Vec3 &sz0 = pPrecompEnts[i].sz;
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(sz0.x,sz0.y),sz0.z));
                        bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval);
                        gwd[1].v = sd.v; gwd[1].w = sd.w;
                        gwd[1].centerOfMass = sd.centerOfMass;
                    }    else {
                        gwd[1].v.zero(); gwd[1].w.zero();
                    }

                    for(int iCyl=0; iCyl<bFastPhys+m_nParts; iCyl++) {
                        int igwd,flagsCollider;    IGeometry *pCurCyl;
                        if (iCyl<=bFastPhys) {
                            pCurCyl=pCyl[iCyl]; igwd=0;    flagsCollider=collider_flags;
                        } else {
                            pCurCyl = m_parts[iCyl-bFastPhys].pPhysGeom->pGeom;
                            gwd[igwd=2].R = Matrix33(m_qrot*m_parts[iCyl-bFastPhys].q);
                            gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[iCyl-bFastPhys].pos;
                            gwd[2].scale = m_parts[iCyl-bFastPhys].scale;
                            if (!((flagsCollider = m_parts[iCyl-bFastPhys].flagsCollider) & geom_colltype_solid))
                                continue;
                            bHasExtraParts = 1;
                        }
                        for(int j1=pPrecompEnts[i].iPartsBegin, bCheckBBox=pPrecompEnts[i].bCheckBBox; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                            if (pPrecompParts[j1].partflags & flagsCollider && (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))    {
                                //(pent->m_qrot*pentlist[i]->m_parts[j].q).getmatrix(gwd[1].R); //Q2M_IVO
                                gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                gwd[1].offset = pPrecompParts[j1].partoff;
                                gwd[1].scale = pPrecompParts[j1].partscale;
                                j = pPrecompParts[j1].ipart;
                                //if (m_pWorld->m_pRenderer) m_pWorld->m_pRenderer->DrawGeometry(pent->m_parts[j].pPhysGeomProxy->pGeom, &gwd[1], 4);

                                if (icnt=pCurCyl->Intersect(pPrecompParts[j1].pgeom, gwd+igwd,gwd+1, &ip, pcontacts)) {
                                    const uint32 uFlags = m_flags;
                                    for(ncont=0; ncont<icnt-1 && pcontacts[ncont].dir*(pcontacts[ncont].pt-gwd[0].offset)>0; ncont++);
                                    if ((pos0-m_pos).len2()>sqr(0.001f)) {//m_pos-posncont==icnt) {
                                        gwd[0].offset+=m_pos-pos; move-=m_pos-pos; pos=m_pos;
                                        pos0=m_pos; goto retry_without_ground_sync;    // if we made SyncWithGroundCollider and it caused intersections, roll it back
                                        //continue;
                                    }
                                    if (iCyl==0 && bHeavy && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                        const int bVeryHeavyFlags = (~(-isneg(minv*2-fMassInv))) | pent->m_flags;
                                        if (m_pWorld->m_bWorldStep==2) { // this means step induced by rigid bodies moving around
                                            // if the entity is rigid, store the contact
                                            int bPushOther;
                                            if (bPushOther = iSimClass>0 && minv>0) {// && pent->m_iGroup==m_pWorld->m_iCurGroup) {
                                                nUnproj = min(nUnproj+1,(int)(CRY_ARRAY_COUNT(unproj)));
                                                unproj[nUnproj-1].pent = pent;
                                                unproj[nUnproj-1].ipart = j;
                                                unproj[nUnproj-1].pt = pcontacts[ncont].pt;
                                                unproj[nUnproj-1].n = pcontacts[ncont].n;
                                                unproj[nUnproj-1].center = gwd[0].offset;
                                                unproj[nUnproj-1].penetration = pcontacts[ncont].t;
                                            }    else if (!(bVeryHeavyFlags & pef_cannot_squash_players))    {
                                                m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                                if (iSimClass>0)
                                                    ncontactSum = pcontacts[ncont].n;
                                            }

                                            // check previous contacts from this frame, register in entity if there are conflicts
                                            for(icnt=0; icnt<nUnproj-bPushOther; icnt++) {
                                                const float fUnprojDotContact = unproj[icnt].n*pcontacts[ncont].n;
                                                if (fUnprojDotContact<0) {
                                                    RegisterUnprojContact(unproj[icnt]);
                                                    if (bPushOther)
                                                        RegisterUnprojContact(unproj[nUnproj-1]);
                                                    if (!((bVeryHeavyFlags|unproj[icnt].pent->m_flags) & pef_cannot_squash_players))
                                                        m_bSquashed = min(5, m_bSquashed+5*isneg(max(5*minv-fMassInv, fUnprojDotContact+0.99f)));
                                                }  
                                            }
                                        } else if (!(bVeryHeavyFlags & pef_cannot_squash_players)) {
                                            m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                            if (iSimClass>0)
                                                ncontactSum = pcontacts[ncont].n;
                                        }

                                        if (uFlags & pef_pushable_by_players) {
                                            (minv==0 ? bStaticUnproj:bDynUnproj)++;
                                            Vec3 offs = pcontacts[ncont].dir*(pcontacts[ncont].t+m_pWorld->m_vars.maxContactGapPlayer);
                                            pos += offs; gwd[0].offset += offs;
                                            bUnprojected = 1;
                                            if (pcontacts[ncont].t>m_size.x)
                                                ip.ptOutsidePivot[0].Set(1E11f,1E11f,1E11f);
                                        }
                                    }

                                    if (iSimClass==2) {
                                        Matrix33 K;
                                        K.SetZero();
                                        if (uFlags & pef_pushable_by_players)
                                            GetContactMatrix(pcontacts[ncont].center, 0, K);
                                        int bPushOther = (uFlags & lef_push_objects) && (pent->m_flags & pef_pushable_by_players);
                                        bPushOther |= iszero(iSimClass-2);
                                        bPushOther &= iszero((int)(INT_PTR)pent-(int)(INT_PTR)m_pLastGroundCollider)^1;
                                        if (bPushOther)
                                            pent->GetContactMatrix(pcontacts[ncont].center, j, K);
                                        else if (!(uFlags & pef_pushable_by_players))
                                            continue;
                                        pcontacts[ncont].center -= pcontacts[ncont].dir*pcontacts[ncont].t;
                                        ncontact = -pcontacts[ncont].n;//(gwd[0].offset-pcontacts[ncont].center).normalized();
                                        if (fabs_tpl(ncontact.z)<0.5f) {
                                            ncontact.z=0; ncontact.normalize();
                                        }
                                        RigidBody *pbody = pent->GetRigidBody(j);
                                        vrel = ncontact*(pbody->v+(pbody->w^pcontacts[ncont].center-pbody->pos)-vel-m_velGround);
                                        if (iCyl==0 || fabs_tpl(vrel)*time_interval>m_size.x*0.2f) {
                                            vrel = max(0.0f,vrel-ncontact*(vel+m_velGround));
                                            float imp=vrel/max(1e-6f,ncontact*K*ncontact);
                                            ai.impulse = ncontact*imp;
                                            ai.point = pcontacts[ncont].center;    ai.ipart = 0;
                                            if (ai.impulse.len2()*sqr(fMassInv) > max(1.0f,sqr(vrel)))
                                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                                            if ((uFlags & (pef_pushable_by_players|geom_no_coll_response)) == pef_pushable_by_players)
                                                vel += ai.impulse*fMassInv;
                                            /*if (vel.z>-5) {
                                            vel.z = max(0.0f, vel.z); vel.z += ai.impulse.len()*fMassInv*0.1f;
                                            }*/
                                            bFlying = 1; m_timeFlying = 0;
                                            if (m_kInertia==0)
                                                m_timeForceInertia = m_timeImpulseRecover;
                                            if (bPushOther) {
                                                if (fabs_tpl(pcontacts[ncont].dir*axis)<0.7f)
                                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                                ai.impulse.Flip(); ai.ipart = j;
                                                //if (pent->GetType()<PE_LIVING)
                                                //    ai.impulse *= 0.2f;
                                                pent->Action(&ai,1);
                                                m_timeSinceImpulseContact = 0;
                                            }
                                            idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont].id[1]>>31 | max(pcontacts[ncont].id[1],0);
                                            RegisterContact(pos,pcontacts[ncont].pt,ncontact,pent,j,idmat,imp,0,pcontacts[ncont].iPrim[1]);
                                        }
                                    }
                                    //break;
                                }
                            }
                    }
                }
            }
            if (bStaticUnproj && bDynUnproj && m_bSquashed) {
                pos = pos0; // disable unprojection if we are being squashed
                bStaticUnproj = bDynUnproj = 0;
            }
            else if (bStaticUnproj+bDynUnproj>0) {
                newpos = pos+move;
            }
          
            float h = ShootRayDown(pPrecompEnts,nents,pPrecompParts,newpos,nslope);
            float hcur = newpos*axis-m_hPivot;
            const float fAxisDotSlope = axis*nslope;
            if (fAxisDotSlope>m_slopeFall &&
                    (hcur<h && hcur>h-(m_hCyl-m_size.z)*1.01f ||
                     hcur>h && sqr_signed(hcur-h)<vel.len2()*sqr(time_interval) && !bFlying && !m_bJumpRequested && !m_bSwimming))
            {
                if (h>hcur && m_nslope*axis<m_slopeSlide && m_nslope*nslope<m_slopeSlide &&
                        fAxisDotSlope<m_slopeSlide && m_velRequested.len2()==0)
                {  
                    newpos = pos; vel.zero();
                }    else
                    newpos += (heightAdj = axis*(h+m_hPivot-newpos*axis));
                move = newpos-pos; movelen = move.len();
            }
            pos0 = pos;
            if (m_bJumpRequested)
                AddLegsImpulse(-vel,m_nslope,true);
            m_bJumpRequested = 0;
            m_bStuck = 0; ncontactSum.zero();

            if (movelen>m_size.x*1E-4f && m_parts[0].flagsCollider!=0) {
                ip.bSweepTest = true;
                gwd[0].v = move/movelen;
                int iter = 0;
                float move0 = movelen; movesum = 0;
                pe_player_dimensions pd;

                do {
                    float tlim = 0.0f;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    ip.time_interval = movelen+m_pWorld->m_vars.maxContactGapPlayer; tmin = ip.time_interval*2;    iPrim = -1;
                    pNRC = pNoResponseContactLE; pNRC->pent = NULL; pNRC->tmin = tmin;
                    for(i=0; i<nents; ++i) {
                        if (pPrecompEnts[i].entType!=PE_LIVING ||
                                pPrecompEnts[i].nParts - iszero((int)(pPrecompParts[pPrecompEnts[i].iLastPart].partflags & collider_flags)) > 1-bHasExtraParts ||
                                max(sqr(m_qrot.v.x)+sqr(m_qrot.v.y),sqr(pPrecompEnts[i].pent->m_qrot.v.x)+sqr(pPrecompEnts[i].pent->m_qrot.v.y))>0.001f)
                        {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            int bCheckBBox=pPrecompEnts[i].bCheckBBox;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1) {
                                const uint32 uPartFlags = pPrecompParts[j1].partflags;
                                if (uPartFlags & (collider_flags|geom_log_interactions) &&
                                    (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))
                                {
                                    if (uPartFlags & geom_log_interactions) {
                                        EventPhysBBoxOverlap event;
                                        event.pEntity[0]=this; event.pForeignData[0]=m_pForeignData; event.iForeignData[0]=m_iForeignData;
                                        event.pEntity[1]=pent; event.pForeignData[1]=pent->m_pForeignData; event.iForeignData[1]=pent->m_iForeignData;
                                        m_pWorld->OnEvent(m_flags, &event);
                                        if (!(uPartFlags & collider_flags))
                                            continue;
                                    }
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;

                                    int ipart = 0;
                                    if((ncont = m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)))
                                        got_contact:
                                        if (pcontacts[ncont-1].t<tmin && pcontacts[ncont-1].n*gwd[0].v>0)    {
                                            if (!((pPrecompParts[j1].partflags | m_parts[ipart].flags)&geom_no_coll_response)) {
                                                // Solid contact
                                                tmin = pcontacts[ncont-1].t; tlim=0.0f; ncontact = -pcontacts[ncont-1].n; ptcontact = pcontacts[ncont-1].pt; iPrim = pcontacts[ncont-1].iPrim[1];
                                                pentmin=pent; jmin=pPrecompParts[j1].ipart; idmat=pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0); ipartMin=ipart;
                                            } else if (pcontacts[ncont-1].t<pNRC->tmin) {
                                                // Non-response contact
                                                pNRC->pent = pent; pNRC->tmin = pcontacts[ncont-1].t;
                                                pNRC->ptcontact = pcontacts[ncont-1].pt; pNRC->ncontact = -pcontacts[ncont-1].n;
                                                pNRC->ipart = pPrecompParts[j1].ipart; pNRC->iPrim = pcontacts[ncont-1].iPrim[1];
                                                pNRC->idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0);
                                            }
                                        }
                                    for(ipart++; ipart<(m_nParts&-bHasExtraParts); ipart++) if (m_parts[ipart].flagsCollider & uPartFlags) {
                                        gwd[2].R = Matrix33(m_qrot*m_parts[ipart].q);
                                        gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[ipart].pos;
                                        gwd[2].scale = m_parts[ipart].scale; gwd[2].v = gwd[0].v;
                                        if((ncont = m_parts[ipart].pPhysGeomProxy->pGeom->Intersect(pPrecompParts[j1].pgeom, gwd+2,gwd+1, &ip, pcontacts)))
                                            goto got_contact;
                                    }
                                }
                            }
                        }    else {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            pent->GetParams(&pd);
                            Vec2 dorigin,ncoll,move2d=(Vec2)gwd[0].v;
                            dorigin = Vec2(pos-pent->m_pos);
                            float kb=dorigin*move2d, kc=len2(dorigin)-sqr(m_size.x+pd.sizeCollider.x), kd=kb*kb-kc, zup0,zdown0,zup1,zdown1;
                            if (kd>=0) {
                                zup0 = (zdown0 = pos.z-m_hPivot)+m_hCyl+m_size.z+m_size.x*m_bUseCapsule;
                                zdown0 = max(zdown0, zup0-(m_size.x*m_bUseCapsule+m_size.z)*2);
                                zup1 = (zdown1 = pent->m_pos.z-pd.heightPivot)+pd.heightCollider+pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule;
                                zdown1 = max(zdown1, zup1-(pd.sizeCollider.x*pd.bUseCapsule+pd.sizeCollider.z)*2);
                                kd=sqrt_tpl(kd);
                                float tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                bool bSideContact = min(zup0+gwd[0].v.z*tfirst,zup1)>max(zdown0+gwd[0].v.z*tfirst,zdown1);
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d>=0 && bSideContact)
                                    continue;    // if entities separate during this timestep, ignore other collisions
                                tfirst=-kb-kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                /*if (tfirst<-m_size.x || min(zup0+gwd[0].v.z*tfirst,zup1)<max(zdown0+gwd[0].v.z*tfirst,zdown1) || ncoll*move2d>=0) {
                                    tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                }*/
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d<0 && bSideContact) {
                                    tlim = (tmin = tfirst)*iszero(iter); ncontact.Set(ncoll.x,ncoll.y,0).normalize(); ptcontact = pos+gwd[0].v*tfirst-ncontact*m_size.x;
                                    pentmin=pent; jmin=0; idmat=m_surface_idx; iPrim=-1; ipartMin=0;
                                }
                                // also check for cap-cap contact
                                if (fabs_tpl(gwd[0].v.z)>m_size.z*1E-5f) {
                                    int nSignZ = sgnnz(gwd[0].v.z);    //Could be float?
                                    zup0 = pos.z-m_hPivot+m_hCyl+(m_size.z+m_size.x*m_bUseCapsule)*nSignZ;
                                    zdown1 = pent->m_pos.z-pd.heightPivot+pd.heightCollider-(pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule)*nSignZ;
                                    tfirst = zdown1-zup0;
                                    if (inrange(tfirst,-m_size.x*gwd[0].v.z,tmin*gwd[0].v.z) &&
                                            len2(dorigin*gwd[0].v.z+move2d*tfirst)<sqr((m_size.x+pd.sizeCollider.x)*gwd[0].v.z))
                                    {
                                        tmin = tfirst/gwd[0].v.z; ncontact.Set(0,0,-nSignZ); (ptcontact = pos+gwd[0].v*tfirst).z += m_size.z*nSignZ; //?
                                        pentmin=pent; jmin=-1; idmat=m_surface_idx; iPrim=-1;    ipartMin=0;
                                    }
                                }
                            }
                        }
                        if (pNRC->pent) {
                            IF (pNRC>=(pNoResponseContactLE+nNoResponseAllocLE-1), 0) {
                                delete [] pNoResponseContactLE; pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE+16];
                                pNRC=pNoResponseContactLE+nNoResponseAllocLE-1; nNoResponseAllocLE+=16;
                            }
                            ++pNRC; pNRC->pent=NULL; pNRC->tmin=ip.time_interval*2;
                        }
                    }

                    if (tmin<=ip.time_interval) {
                        tmin = max(tlim,tmin-m_pWorld->m_vars.maxContactGapPlayer);
                        pos += gwd[0].v*tmin;
                        static const float g_cosSlide=cos_tpl(0.3f), g_sinSlide=sin_tpl(0.3f);
                        /*if (bFlying) {
                            if ((ncontact*axis)*(1-m_bSwimming)>g_cosSlide)
                                ncontact = axis*g_cosSlide + (pos-ptcontact-axis*(axis*(pos-ptcontact))).normalized()*g_sinSlide;
                        } else */
                        if (!bFlying && inrange(ncontact*axis, 0.85f,-0.1f) && (unsigned int)pentmin->m_iSimClass-1u<2u &&
                            pentmin->GetMassInv()>m_massinv*0.25f)
                            ncontact.z=0, ncontact.normalize();
                        int bPush = pentmin->m_iSimClass>0 || isneg(min(m_slopeClimb-ncontact*axis, ncontact*axis+m_slopeFall)) | bFlying;
                        int bUnmovable = isneg(-pentmin->m_iSimClass>>31 & ~(-((int)m_flags & pef_pushable_by_players)>>31));
                        bPush &= bUnmovable^1;
                        {
                            Matrix33 K;
                            K.SetZero();
                            int bPushOther = (m_flags & (pentmin->m_iSimClass==3 ? lef_push_players : lef_push_objects)) &&
                                (pentmin->m_flags & pef_pushable_by_players) &&
                                (pentmin->m_iSimClass | m_pWorld->m_vars.bPlayersCanBreak | pentmin->m_flags & pef_players_can_break);
                            bPushOther &= iszero((int)(INT_PTR)pentmin-(int)(INT_PTR)m_pLastGroundCollider)^1;
                            bPushOther |= bUnmovable;
                            if (bPushOther)
                                pentmin->GetContactMatrix(ptcontact, jmin, K);
                            if (!bPushOther || /*pentmin->m_iSimClass-3 | */m_flags & pef_pushable_by_players)
                                GetContactMatrix(ptcontact, -1, K);
                            else
                                bPush = 0;
                            vrel = ncontact*(vel+m_velGround); //(ncontact*gwd[0].v)*vel.len();
                            ai.impulse = ncontact;
                            if (pentmin->m_iSimClass==3) {
                                // make the player slide off when standing on other players
                                vrel -= ncontact*((CLivingEntity*)pentmin)->m_vel;
                                if (ncontact*axis > 0.95f) {
                                    ai.impulse += (pos-pentmin->m_pos-axis*(axis*(pos-pentmin->m_pos))).normalized();
                                    if (inrange(vrel,-1.0f,1.0f))
                                        vrel = -1.0f;
                                }
                            } else {
                                RigidBody *pbody = pentmin->GetRigidBody(jmin);
                                vrel -= ncontact*(pbody->v+(pbody->w^ptcontact-pbody->pos));
                            }
                            vrel = min(0.0f, vrel);
                            float imp = -vrel*1.01f/max(1e-6f,ncontact*K*ncontact);
                            jmin -= jmin>>31;
                            if (bPush || m_flags & lef_report_sliding_contacts || pentmin->m_parts[jmin].flags & geom_manually_breakable)
                                RegisterContact(pos,ptcontact,ncontact,pentmin,jmin,idmat,imp*bPush,0,iPrim,ipartMin);
                            ai.impulse *= imp;
                            ai.point = ptcontact;    ai.ipart = 0;
                            if (ai.impulse.len2()*sqr(m_massinv) > max(1.0f,sqr(vrel)))
                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                            if (bPush) {
                                vel += ai.impulse*m_massinv;
                                if (m_kInertia==0 && (pentmin->m_iSimClass-3 | m_flags & pef_pushable_by_players))
                                    m_timeForceInertia = m_timeImpulseRecover;
                            }
                            if (bPushOther) {
                                ai.impulse.Flip(); ai.ipart = jmin;
                                if (fabs_tpl(ncontact*axis)<0.7f)
                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                ai.iApplyTime = isneg(pentmin->m_iSimClass-3)<<1;
                                if (pentmin->GetType()<PE_LIVING)
                                    ai.impulse *= 0.2f;
                                pentmin->Action(&ai);
                                if (pentmin->m_iSimClass<3)
                                    m_timeSinceImpulseContact = 0;
                            }
                        }
                        movelen -= tmin; movesum += tmin;
                        for(i=0;i<iter && ncontactHist[i]*ncontact<0.95f;i++);
                        if (i==iter)
                            ncontactSum += ncontact;
                        ncontactHist[iter] = ncontact;
                        if (iter==1 && movesum==0.0f) {
                            ncontact = (ncontactHist[0]^ncontactHist[1]).normalized();
                            gwd[0].v = ncontact*(gwd[0].v*ncontact);
                        }    else {
                            gwd[0].v -= ncontact*(gwd[0].v*ncontact);
                            gwd[0].v = gwd[0].v*0.9998f+ncontact*(gwd[0].v.len()*0.02f);
                        }
                        tmin = gwd[0].v.len(); movelen*=tmin;
                        if (tmin>0) gwd[0].v/=tmin;
                        movelen = (float)__fsel(gwd[0].v*move, movelen, 0.0f);
                    } else {
                        pos += gwd[0].v*movelen; movesum += movelen; /* exit do-loop */ iter=1000;
                    }
                    for (le_tmp_contact* c=pNoResponseContactLE; c<=pNRC && c->pent; c++)
                        if (c->tmin<tmin)
                            RegisterContact(pos,c->ptcontact,c->ncontact,c->pent,c->ipart,c->idmat,0.f,0,c->iPrim);
                } while(movelen>m_pWorld->m_vars.maxContactGapPlayer*0.1f && ++iter<3);

                const float fContactSumLenSq = ncontactSum.len2();
                if(movesum<move0*0.001f && (sqr_signed(ncontactSum.z)>sqr(0.4f)*fContactSumLenSq || fContactSumLenSq<0.6f))
                    m_bStuck = 1;

                if (m_parts[0].flagsCollider!=0 && (bUnprojected || !(m_flags & lef_loosen_stuck_checks))) {
                    ip.bSweepTest = false;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    gwd[0].v = -axis;
                    ip.bStopAtFirstTri = true; ip.bNoBorder = true; ip.time_interval = m_size.z*10;
                    for(i=0; i<nents; ++i)
                        if (pPrecompEnts[i].iSimClass==0) {
                            CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                                if (pPrecompParts[j1].partflags & collider_flags && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;
                                    if(m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)) {
                                    if (pcontacts->t>m_pWorld->m_vars.maxContactGapPlayer)
                                        vel.zero(),m_bStuck=1;  
                                    pos = pos0; m_timeUseLowCap=1.0f;
                                    goto nomove;
                                }
                            }
                    } nomove:;
                }
            } else
                pos += move;

            if (!m_pLastGroundCollider)// || m_pLastGroundCollider->GetMassInv()>m_massinv)
                velGround.zero();
            else
                velGround = m_velGround;
            m_hLatest = h = ShootRayDown(pPrecompEnts, nents, pPrecompParts, pos,nslope, time_interval,false,true);
            if (nslope*axis<0.087f)
                nslope = m_nslope;
            else {
                WriteLockCond lock(m_lockLiving,m_bStateReading^1);
                m_nslope = nslope;
            }
            if (m_pLastGroundCollider) {
                RegisterContact(newpos,newpos,m_qrot*Vec3(0,0,1),m_pLastGroundCollider,m_iLastGroundColliderPart,m_lastGroundSurfaceIdx,0,1,m_lastGroundPrim);
                if (m_pLastGroundCollider->m_iSimClass==0)
                    ReleaseGroundCollider();
            }

            if (bFlying)
                m_timeFlying += time_interval;
            int bGroundContact = isneg(max(pos*axis-m_hPivot-(h+m_groundContactEps), m_slopeFall-nslope*axis));
            if (!bGroundContact)
                ReleaseGroundCollider();

            bFlying = m_pWorld->m_vars.bFlyMode || m_gravity*axis>0 || m_bSwimming || ((bGroundContact|m_bStuck)^1);
            m_bActiveEnvironment = m_bStuck;

            if (bFlying)
                Step_HandleFlying(vel, velGround, bWasFlying, heightAdj, kInertia, time_interval);
            else {
                if (bWasFlying)
                    Step_HandleWasFlying(vel, bFlying, axis, bGroundContact);
              
                Vec3 velReq = m_velRequested,g;
                if (!m_bSwimming) velReq -= m_nslope*(velReq*m_nslope);
                if (kInertia * time_interval > 1.0f)    kInertia = 1.0f/time_interval;
                Vec3 last_force = (velReq-vel)*kInertia;
                const float axisSlope = m_nslope*axis;
                if (axisSlope<m_slopeSlide && !m_bSwimming)    {
                    g = m_gravity;
                    last_force += g-m_nslope*(g*m_nslope);
                }
              
                const Vec3 velIncLastForce = vel + (last_force*time_interval);
                if (velIncLastForce*vel<0 && velIncLastForce*m_velRequested<=0)
                    vel.zero();
                else
                    vel = velIncLastForce;

                if (axisSlope<m_slopeClimb) {
                    const float axisVel = vel*axis;
                    if (axisVel>0 && last_force*axis>0)
                        vel -= axis*(axisVel);
                    if ((pos-pos0)*axis > m_size.z*0.001f)
                        vel -= axis*(axis*vel);
                }
                if (axisSlope<m_slopeFall && !m_bStuck) {
                    bFlying=1; vel += m_nslope-axis*(axisSlope);
                }
                if (m_velRequested.len2()==0 && vel.len2()<0.001f || vel.len2()<0.0001f)
                    vel.zero();
            }

            if (!bFlying)
                m_timeFlying = 0;

            if (m_flags & lef_snap_velocities)
                vel = DecodeVec6b(EncodeVec6b(vel));

            if (!m_bStateReading) {
                float dh;
                if (!bFlying && (dh=(pos-pos0)*axis)>m_size.z*0.01f) {
                    m_dhSpeed = max(m_dhSpeed, dh/m_stablehTime);
                    m_dh += dh;
                    m_stablehTime = 0;
                }    else
                    dh = 0;
                m_stablehTime = min(m_stablehTime+time_interval,0.5f);

                m_dhSpeed += m_dhAcc*time_interval;
                if (m_dhAcc==0 && m_dh*m_dhSpeed<0 || m_dh*m_dhAcc<0 || m_dh*(m_dh-m_dhSpeed*time_interval)<0)
                    m_dh = m_dhSpeed = m_dhAcc = 0;
                else
                    m_dh -= m_dhSpeed*time_interval;
            }

            if (m_pHeadGeom) {
                ip.bSweepTest = true;
                gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                gwd[0].v = axis;
                tmin = ip.time_interval = m_hHead-m_hCyl-min(m_dh,0.0f);
                for(i=0;i<nents;i++) if (pentlist[i]->m_iSimClass==0) {//pentlist[i]->GetType()!=PE_LIVING && pentlist[i]->GetMassInv()*0.4f<m_massinv) {
                    for(int j1=0;j1<pentlist[i]->GetUsedPartsCount(iCaller);j1++)
                        if (pentlist[i]->m_parts[j=pentlist[i]->GetUsedPart(iCaller,j1)].flags & collider_flags) {
                            Matrix33 rotMat = Matrix33(pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q);
                            gwd[1].R = rotMat;
                            gwd[1].offset = pentlist[i]->m_pos + rotMat*pentlist[i]->m_parts[j].pos;
                            gwd[1].scale = pentlist[i]->m_parts[j].scale;
                            if(m_pHeadGeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts))
                                tmin = min(tmin,(float)pcontacts[0].t);
                        }
                }
                if (m_dh<ip.time_interval+min(m_dh,0.0f)-tmin || fabs_tpl(m_dhSpeed)+fabs_tpl(m_dhAcc)==0)
                    m_dh = ip.time_interval+min(m_dh,0.0f)-tmin;
            }
        }
      
        coord_block_BBox partCoord;
        ComputeBBoxLE(pos,BBoxInner,&partCoord);
        UpdatePosition(pos,BBoxInner, m_pWorld->RepositionEntity(this,1,BBoxInner));
        bMoving = 1;
    } else if (!m_bActive) {
        if (m_velRequested.len2()>0) {
            m_pos += m_velRequested*time_interval;
            m_BBox[0] += m_velRequested*time_interval; m_BBox[1] += m_velRequested*time_interval;
            JobAtomicAdd(&m_pWorld->m_lockGrid,-m_pWorld->RepositionEntity(this,1));
            bMoving = 1;
        }
        if (m_bReleaseGroundColliderWhenNotActive!=0)
            ReleaseGroundCollider();
    }
  
    { WriteLockCond lock(m_lockLiving,m_bStateReading^1);
        //if (m_pWorld->m_vars.bMultiplayer)
        //    m_pos = CompressPos(m_pos);
      
        m_deltaV        = (m_vel - vel0);
        m_vel                = vel+m_vel-vel0;      
        m_bFlying        = bFlying;
        m_deltaQRot = m_qrot * !oldQRot;

        m_timeSmooth = (float)__fsel(-time_interval, m_timeSmooth, time_interval);
        if (m_pWorld->m_bUpdateOnlyFlagged) {
            m_deltaPos = m_posLocal-m_pos;
            if (m_deltaPos.len2()<sqr(0.01f) || m_deltaPos.len2()>sqr(2.0f))
                m_deltaPos.zero();
        }
        if (m_pBody)
            if (!m_nColliders) {
                delete m_pBody; m_pBody=0;
            } else {
                m_pBody->pos=m_pos+m_qrot*Vec3(0,0,m_hCyl); m_pBody->q=m_qrot;
                m_pBody->P=(m_pBody->v=m_vel)*(m_pBody->M=m_mass);
                m_pBody->Minv=m_massinv;
                if (m_pWorld->m_timePhysics > m_timeRotChanged+0.05f)
                    m_pBody->w.zero(), m_pBody->L.zero();
                /*quaternionf dq = m_history[m_iHist].q*!m_history[m_iHist-3&m_szHistory-1].q;
                float dt=0; for(i=0; i<4; i++)
                    dt += m_history[m_iHist-i&m_szHistory-1].dt;
                if (inrange(dt, 0.0f,1.0f)) {
                    if (dq.v.len2()<sqr(0.05f))
                        m_pBody->w = dq.v*(2/dt);
                    else
                        m_pBody->w = dq.v.normalized()*(acos_tpl(dq.w)*2/dt);
                }*/
            }
    }

    if (!m_bStateReading) {
        if( bMoving )    {
            Vec3 gravity; MARK_UNUSED gravity;
            pe_params_buoyancy pb;
            m_pWorld->CheckAreas(this,gravity,&pb,0);
            if (!is_unused(gravity))
                m_gravity = gravity;

            if (m_pWorld->m_pWaterMan)
                m_pWorld->m_pWaterMan->OnWaterInteraction(this);
        }

        if (m_flags & (pef_monitor_poststep | pef_log_poststep)) {
            EventPhysPostStep epps;
            epps.pEntity=this; epps.pForeignData=m_pForeignData; epps.iForeignData=m_iForeignData;
            epps.dt=time_interval; epps.pos=m_pos; epps.q=m_qrot; epps.idStep=m_pWorld->m_idStep;
            epps.pos -= m_qrot*Vec3(0,0,m_dh);
            m_pWorld->OnEvent(m_flags,&epps);
        }
        /*if (m_pWorld->m_iLastLogPump > m_timeLogged)
            m_posLogged = pos0;
        m_timeLogged = m_pWorld->m_iLastLogPump;*/
    }

    return 1;
}
My eyes, they bleed.

Seen worse, though. At least by a factor of 2.
 
Joined
Jan 7, 2012
Messages
14,274
https://github.com/CRYTEK-CRYENGINE/CRYENGINE
That's right, it get open sourced. The first version.
I'm not a fan of their games but if that mean less usage of Unity the better...
Imagine dungeon crawlers in this engine.

It's called Cry Engine because the code makes you cry.

Where is the InstakillHeadshotThePlayerFromAcrossTheMapIfSpotted() function? I remember this being a part of Far Cry.

800 line functions with almost no comments though, that's even more hardcore.
 

Echo Mirage

Arcane
Joined
Aug 19, 2013
Messages
1,575
Location
Tirra Lirra by the River
I unironically didn't know MineCon was a thing.
Lucky guy.

The only thing I recall of Minecon was back when the Mincraft hype was at its max. The two insufferable guys from Yogscast were hired to host it. And then proved to the world that they were indeed insufferable dicks. Even Notch told them to fuck off during some nice social media butthurt.
 
Self-Ejected

vivec

Self-Ejected
Joined
Oct 20, 2014
Messages
1,149
https://github.com/CRYTEK-CRYENGINE/CRYENGINE
That's right, it get open sourced. The first version.
I'm not a fan of their games but if that mean less usage of Unity the better...
Imagine dungeon crawlers in this engine.

It's called Cry Engine because the code makes you cry.

For example, this is ONE function
https://github.com/CRYTEK-CRYENGINE...e/CryEngine/CryPhysics/livingentity.cpp#L1300

Code:
int CLivingEntity::Step(float time_interval)
{
    if (time_interval<=0)
        return 1;
    float dt = m_timeStepFull-m_timeStepPerformed;
    time_interval = m_pWorld->m_bWorldStep==2 ? min(time_interval, dt) : dt;
    time_interval = max(time_interval, 0.001f);

    const int iCaller = get_iCaller_int();
    int i,j,jmin,ipartMin,nents,ncont,bFlying,bWasFlying,bUnprojected,idmat,iPrim, bHasExtraParts=0,
        bHasFastPhys,icnt,nUnproj,bStaticUnproj,bDynUnproj,bMoving=0,nPrecompEnts=0,nPrecompParts=0, nUsedPartsCount=0,
        &nNoResponseAllocLE=m_pWorld->m_threadData[iCaller].nNoResponseAllocLE,
        &nPrecompEntsAlloc=m_pWorld->m_threadData[iCaller].nPrecompEntsAllocLE,&nPrecompPartsAlloc=m_pWorld->m_threadData[iCaller].nPrecompPartsAllocLE;
    const Quat oldQRot = m_qrot;
    Vec3 pos,vel,pos0,vel0,newpos,move(ZERO),nslope,ncontactHist[4],ncontact,ptcontact,ncontactSum,BBoxInner[2],velGround,axis,sz,heightAdj=Vec3(0.f);
    float movelen,tmin,vrel,movesum,kInertia;
    le_precomp_entity *&pPrecompEnts=m_pWorld->m_threadData[iCaller].pTmpPrecompEntsLE;
    le_precomp_part *&pPrecompParts=m_pWorld->m_threadData[iCaller].pTmpPrecompPartsLE;
    le_tmp_contact *&pNoResponseContactLE=m_pWorld->m_threadData[iCaller].pTmpNoResponseContactLE, *pNRC;
    le_contact unproj[8];
    CCylinderGeom CylinderGeomOuter,*pCyl[2];
    geom_world_data gwd[3];
    intersection_params ip;
    CPhysicalEntity **pentlist, *pentmin=NULL;
    geom_contact *pcontacts;
    pe_action_impulse ai;
    pe_status_dynamics sd;
    WriteLockCond lockMain(m_lockStep,m_bStateReading^1);
    ip.bNoAreaContacts = true;

    IF (nNoResponseAllocLE==0, 0) pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE=16];

    if (m_timeForceInertia>0.0001f)
        kInertia = 6.0f;
    else if (m_kInertiaAccel && m_velRequested.len2()>0.1f)
        kInertia = m_kInertiaAccel;
    else
        kInertia = m_kInertia;

    pos = m_pWorld->m_bWorldStep==2 ? m_pos : SyncWithGroundCollider(time_interval);
    vel0=vel = m_vel;
    bWasFlying = bFlying = m_bFlying;
    if (!m_bStateReading) {
        m_timeUseLowCap -= time_interval;
        m_timeSinceStanceChange += time_interval;
        m_timeSinceImpulseContact += time_interval;
        m_timeForceInertia = max(0.0f,m_timeForceInertia-time_interval);
        m_timeStepPerformed += time_interval;
    }

    if (m_bActive &&
            (!(vel.len2()==0 && m_velRequested.len2()==0 && (!bFlying || m_gravity.len2()==0) && m_dhSpeed==0 && m_dhAcc==0) ||
            m_bActiveEnvironment || m_nslope.z<m_slopeSlide || m_velGround.len2()>0)) 
    {
        FUNCTION_PROFILER( GetISystem(),PROFILE_PHYSICS );
        PHYS_ENTITY_PROFILER

        m_bActiveEnvironment = 0;
        //m_nslope.Set(0,0,1);
        if (kInertia==0 && !bFlying && !m_bJumpRequested || m_pWorld->m_vars.bFlyMode) {
            vel = m_velRequested;
            vel -= m_nslope*(m_nslope*vel);
        }
        if (bFlying && !m_pWorld->m_vars.bFlyMode && m_kAirControl>0)    {
            if (kInertia>0) {
                Vec3 velDelta = m_velRequested * (m_kInertia*time_interval*m_kAirControl);
                Vec3 velDiff = m_velRequested - vel;
                 
                const float kAirControlSelect = m_kAirControl-1.0f;

                velDelta.x = (float)__fsel(-(velDiff.x * velDelta.x), 0.0f, velDelta.x);
                velDelta.y = (float)__fsel(-(velDiff.y * velDelta.y), 0.0f, velDelta.y);
                velDelta.z = (float)__fsel(-(velDiff.z * velDelta.z), 0.0f, velDelta.z);

                velDelta.x = (float)__fsel(velDiff.x, min(velDiff.x, velDelta.x), max(velDiff.x, velDelta.x));
                velDelta.y = (float)__fsel(velDiff.y, min(velDiff.y, velDelta.y), max(velDiff.y, velDelta.y));
                velDelta.z = (float)__fsel(velDiff.z, min(velDiff.z, velDelta.z), max(velDiff.z, velDelta.z));
             
                velDelta.y = (float)__fsel(kAirControlSelect, velDiff.y, velDelta.y);
                velDelta.x = (float)__fsel(kAirControlSelect, velDiff.x, velDelta.x);             

                vel += velDelta;
            } else if (m_gravity.len2()>0)
                vel = m_gravity*(vel*m_gravity-m_velRequested*m_gravity)/m_gravity.len2()+m_velRequested;
            else
                vel = m_velRequested;
        }

        //filippo:m_forceFly is to let the game set a velocity no matter what is the status of the entity.
        if (m_forceFly)
            vel = m_velRequested;
         else if (bFlying && !m_bSwimming && !m_pWorld->m_vars.bFlyMode)
             move += m_gravity*sqr(time_interval)*0.5f;

        if (vel.len2() > sqr(m_pWorld->m_vars.maxVelPlayers))
            vel.normalize() *= m_pWorld->m_vars.maxVelPlayers;
     
        move += vel*time_interval;

        m_forceFly = false;
        bUnprojected = 0;
        axis = m_qrot*Vec3(0,0,1);
        if (_isnan(move.len2())) //necessary? Is there any way that this can occur? - Rich S
            return 1;
        --m_bSquashed; m_bSquashed-=m_bSquashed>>31;

        if (m_pWorld->m_vars.iCollisionMode!=0 && m_pWorld->m_vars.bFlyMode) {    //Rich S - is bFlyMode a cheat? Can we disable in release?
            pos+=move; bFlying=1; m_hLatest=0; ReleaseGroundCollider();
        } else {

            const float fSizeX = m_size.x;
            const float fSizeZ = m_size.z;
            movelen = move.len();
            const float fGap = (movelen+m_pWorld->m_vars.maxContactGapPlayer)*1.5f;
            const Vec3 posDiff = pos - m_pos;
            BBoxInner[0] = m_BBox[0]+(posDiff)-Vec3(fGap,fGap,fGap);
            BBoxInner[1] = m_BBox[1]+(posDiff)+Vec3(fGap,fGap,fGap);
            const float fGap2 = max(10.0f*time_interval,fGap); // adds a safety margin of m_size.x width
            const Vec3 BBoxOuter0 = m_BBox[0]+(posDiff)-Vec3(fGap2,fGap2,fGap2);
            const Vec3 BBoxOuter1 = m_BBox[1]+(posDiff)+Vec3(fGap2,fGap2,fGap2);

            nents = m_pWorld->GetEntitiesAround(BBoxOuter0,BBoxOuter1,
                pentlist, m_collTypes|ent_independent|ent_triggers|ent_sort_by_mass, this, 0,iCaller);

            if (m_vel.len2()) for(i=0;i<m_nColliders;i++) if (m_pColliders[i]->HasConstraintContactsWith(this,constraint_inactive))
                m_pColliders[i]->Awake();

            const float fMassInv = m_massinv;
            for(i=j=bHasFastPhys=0,vrel=0; i<nents; i++) if (!m_pForeignData || pentlist[i]->m_pForeignData!=m_pForeignData){
                Vec3 size = pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0];
                int bFastPhys = 0;
                if (IgnoreCollision(m_collisionClass, pentlist[i]->m_collisionClass))
                    continue;
                if (pentlist[i]->m_iSimClass==2) {
                    if (pentlist[i]->m_flags & ref_small_and_fast)
                        continue;
                    else if (pentlist[i]->GetMassInv()*0.4f<fMassInv) {
                        pentlist[i]->GetStatus(&sd);
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(size.x,size.y),size.z));;
                        bHasFastPhys |= (bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval));
                    }
                }
                if (!bFastPhys && !AABB_overlap(pentlist[i]->m_BBox,BBoxInner) && size.len2()>0)
                    continue;
                idmat = pentlist[i]->GetType();
                if (idmat==PE_SOFT || idmat==PE_ROPE)
                    pentlist[i]->Awake();
                else if (pentlist[i]->m_iSimClass<4 &&
                    (idmat!=PE_LIVING && !pentlist[i]->IgnoreCollisionsWith(this,1) ||
                     idmat==PE_LIVING && pentlist[i]->m_parts[0].flags&collider_flags &&
                     pentlist[i]!=this && m_pLivingEntToIgnore!=pentlist[i] && ((CLivingEntity*)pentlist[i])->m_pLivingEntToIgnore!=this))
                {
                    if (pentlist[i]->m_iSimClass==1 && m_timeSinceImpulseContact<0.2f && pentlist[i]->GetMassInv()>0)    {
                        int ipart; unsigned int flags;
                        for(ipart=0,flags=0; ipart<pentlist[i]->m_nParts; ipart++)
                            flags |= pentlist[i]->m_parts[ipart].flags;
                        if (flags & collider_flags)
                            pentlist[i]->Awake();
                    }
                    pentlist[j++] = pentlist[i];
                }
            }
            nents = j;
            pos0 = pos;
            bStaticUnproj = bDynUnproj = 0;
            newpos = pos+move;

            IF (nents>nPrecompEntsAlloc, 0) delete[] pPrecompEnts, pPrecompEnts=new le_precomp_entity[nPrecompEntsAlloc=nents];
            for(i=0; i<nents; i++) {
                le_precomp_entity &ent = pPrecompEnts[nPrecompEnts++];
                ent.BBox[0]=pentlist[i]->m_BBox[0];
                ent.BBox[1]=pentlist[i]->m_BBox[1];
                ent.sz=(sz=pentlist[i]->m_BBox[1]-pentlist[i]->m_BBox[0]);
                ent.bCheckBBox=sz.len2()>0;
                ent.massinv=pentlist[i]->GetMassInv();
                ent.entType=pentlist[i]->GetType();
                ent.iSimClass=pentlist[i]->m_iSimClass;
                ent.pent=pentlist[i];
                ent.nParts=pentlist[i]->m_nParts;
                ent.ignoreCollisionsWith=pentlist[i]->IgnoreCollisionsWith(this,1);
                ent.iPartsBegin=nPrecompParts;
                ent.iPartsEnd=nPrecompParts+(nUsedPartsCount=pentlist[i]->GetUsedPartsCount(iCaller));
                IF (ent.iPartsEnd>nPrecompPartsAlloc, 0) {
                    ReallocateList(pPrecompParts, nPrecompParts, ent.iPartsEnd+128);
                    nPrecompPartsAlloc=ent.iPartsEnd+128;
                }
                for(int j1=0; j1<nUsedPartsCount; j1++) {
                    le_precomp_part &part = pPrecompParts[nPrecompParts++];
                    part.BBox[0]=pentlist[i]->m_parts[part.ipart=j=pentlist[i]->GetUsedPart(iCaller,j1)].BBox[0];
                    part.BBox[1]=pentlist[i]->m_parts[j].BBox[1];
                    part.partrot=pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q;
                    part.partoff=pentlist[i]->m_pos + pentlist[i]->m_qrot*pentlist[i]->m_parts[j].pos;
                    part.partscale=pentlist[i]->m_parts[j].scale; 
                    part.partflags=pentlist[i]->m_parts[j].flags;
                    part.pgeom=pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom;
                    part.surface_idx=pentlist[i]->m_parts[j].surface_idx;
                    ent.iLastPart=nPrecompParts-1;
                }
            }
     
            // first, check if we need unprojection in the initial position
            if (sqr(m_qrot.v.x)+sqr(m_qrot.v.y)<sqr(0.001f))
                gwd[0].R.SetIdentity();
            else
                gwd[0].R = Matrix33(m_qrot);
            gwd[0].centerOfMass = gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
            gwd[0].v.zero(); gwd[0].w.zero(); // since we check a static character against potentially moving environment here
            ip.vrel_min = fSizeX;
            ip.time_interval = time_interval*2;
            ip.maxUnproj = fSizeX*2.5f;
            ip.ptOutsidePivot[0] = gwd[0].offset;
            pCyl[0] = m_pCylinderGeom;
            if (bHasFastPhys) {
                cylinder cylOuter;
                cylOuter.r = fSizeX+min(fSizeX*1.5f,vrel*time_interval);
                cylOuter.hh = fSizeZ+min(fSizeZ,vrel*time_interval);
                cylOuter.center.zero();
                cylOuter.axis.Set(0,0,1);
                CylinderGeomOuter.CreateCylinder(&cylOuter);
                pCyl[1] = &CylinderGeomOuter;
            }

            retry_without_ground_sync:
            if (m_parts[0].flagsCollider) {
                for(i=nUnproj=0,ncontactSum.zero();i<nents;++i)
                    if (pPrecompEnts[i].entType!=PE_LIVING) {
                    const float minv = pPrecompEnts[i].massinv;
                    const int bHeavy = isneg(minv*0.4f-fMassInv);
                    const int iSimClass = pPrecompEnts[i].iSimClass;
                    CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                    int bFastPhys = 0;
                    if (bHasFastPhys && bHeavy && iSimClass==2 && pent!=m_pLastGroundCollider) {
                        pent->GetStatus(&sd);
                        const Vec3 &sz0 = pPrecompEnts[i].sz;
                        vrel = max(vrel,sd.v.len()+sd.w.len()*max(max(sz0.x,sz0.y),sz0.z));
                        bFastPhys = isneg(fSizeX*0.2f-vrel*time_interval);
                        gwd[1].v = sd.v; gwd[1].w = sd.w;
                        gwd[1].centerOfMass = sd.centerOfMass;
                    }    else {
                        gwd[1].v.zero(); gwd[1].w.zero();
                    }

                    for(int iCyl=0; iCyl<bFastPhys+m_nParts; iCyl++) {
                        int igwd,flagsCollider;    IGeometry *pCurCyl;
                        if (iCyl<=bFastPhys) {
                            pCurCyl=pCyl[iCyl]; igwd=0;    flagsCollider=collider_flags;
                        } else {
                            pCurCyl = m_parts[iCyl-bFastPhys].pPhysGeom->pGeom;
                            gwd[igwd=2].R = Matrix33(m_qrot*m_parts[iCyl-bFastPhys].q);
                            gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[iCyl-bFastPhys].pos;
                            gwd[2].scale = m_parts[iCyl-bFastPhys].scale;
                            if (!((flagsCollider = m_parts[iCyl-bFastPhys].flagsCollider) & geom_colltype_solid))
                                continue;
                            bHasExtraParts = 1;
                        }
                        for(int j1=pPrecompEnts[i].iPartsBegin, bCheckBBox=pPrecompEnts[i].bCheckBBox; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                            if (pPrecompParts[j1].partflags & flagsCollider && (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))    {
                                //(pent->m_qrot*pentlist[i]->m_parts[j].q).getmatrix(gwd[1].R); //Q2M_IVO
                                gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                gwd[1].offset = pPrecompParts[j1].partoff;
                                gwd[1].scale = pPrecompParts[j1].partscale;
                                j = pPrecompParts[j1].ipart;
                                //if (m_pWorld->m_pRenderer) m_pWorld->m_pRenderer->DrawGeometry(pent->m_parts[j].pPhysGeomProxy->pGeom, &gwd[1], 4);

                                if (icnt=pCurCyl->Intersect(pPrecompParts[j1].pgeom, gwd+igwd,gwd+1, &ip, pcontacts)) {
                                    const uint32 uFlags = m_flags;
                                    for(ncont=0; ncont<icnt-1 && pcontacts[ncont].dir*(pcontacts[ncont].pt-gwd[0].offset)>0; ncont++);
                                    if ((pos0-m_pos).len2()>sqr(0.001f)) {//m_pos-posncont==icnt) {
                                        gwd[0].offset+=m_pos-pos; move-=m_pos-pos; pos=m_pos;
                                        pos0=m_pos; goto retry_without_ground_sync;    // if we made SyncWithGroundCollider and it caused intersections, roll it back
                                        //continue;
                                    }
                                    if (iCyl==0 && bHeavy && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                        const int bVeryHeavyFlags = (~(-isneg(minv*2-fMassInv))) | pent->m_flags;
                                        if (m_pWorld->m_bWorldStep==2) { // this means step induced by rigid bodies moving around
                                            // if the entity is rigid, store the contact
                                            int bPushOther;
                                            if (bPushOther = iSimClass>0 && minv>0) {// && pent->m_iGroup==m_pWorld->m_iCurGroup) {
                                                nUnproj = min(nUnproj+1,(int)(CRY_ARRAY_COUNT(unproj)));
                                                unproj[nUnproj-1].pent = pent;
                                                unproj[nUnproj-1].ipart = j;
                                                unproj[nUnproj-1].pt = pcontacts[ncont].pt;
                                                unproj[nUnproj-1].n = pcontacts[ncont].n;
                                                unproj[nUnproj-1].center = gwd[0].offset;
                                                unproj[nUnproj-1].penetration = pcontacts[ncont].t;
                                            }    else if (!(bVeryHeavyFlags & pef_cannot_squash_players))    {
                                                m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                                if (iSimClass>0)
                                                    ncontactSum = pcontacts[ncont].n;
                                            }

                                            // check previous contacts from this frame, register in entity if there are conflicts
                                            for(icnt=0; icnt<nUnproj-bPushOther; icnt++) {
                                                const float fUnprojDotContact = unproj[icnt].n*pcontacts[ncont].n;
                                                if (fUnprojDotContact<0) {
                                                    RegisterUnprojContact(unproj[icnt]);
                                                    if (bPushOther)
                                                        RegisterUnprojContact(unproj[nUnproj-1]);
                                                    if (!((bVeryHeavyFlags|unproj[icnt].pent->m_flags) & pef_cannot_squash_players))
                                                        m_bSquashed = min(5, m_bSquashed+5*isneg(max(5*minv-fMassInv, fUnprojDotContact+0.99f)));
                                                } 
                                            }
                                        } else if (!(bVeryHeavyFlags & pef_cannot_squash_players)) {
                                            m_bSquashed = min(5, m_bSquashed+5*isneg(ncontactSum*pcontacts[ncont].n+0.99f));
                                            if (iSimClass>0)
                                                ncontactSum = pcontacts[ncont].n;
                                        }

                                        if (uFlags & pef_pushable_by_players) {
                                            (minv==0 ? bStaticUnproj:bDynUnproj)++;
                                            Vec3 offs = pcontacts[ncont].dir*(pcontacts[ncont].t+m_pWorld->m_vars.maxContactGapPlayer);
                                            pos += offs; gwd[0].offset += offs;
                                            bUnprojected = 1;
                                            if (pcontacts[ncont].t>m_size.x)
                                                ip.ptOutsidePivot[0].Set(1E11f,1E11f,1E11f);
                                        }
                                    }

                                    if (iSimClass==2) {
                                        Matrix33 K;
                                        K.SetZero();
                                        if (uFlags & pef_pushable_by_players)
                                            GetContactMatrix(pcontacts[ncont].center, 0, K);
                                        int bPushOther = (uFlags & lef_push_objects) && (pent->m_flags & pef_pushable_by_players);
                                        bPushOther |= iszero(iSimClass-2);
                                        bPushOther &= iszero((int)(INT_PTR)pent-(int)(INT_PTR)m_pLastGroundCollider)^1;
                                        if (bPushOther)
                                            pent->GetContactMatrix(pcontacts[ncont].center, j, K);
                                        else if (!(uFlags & pef_pushable_by_players))
                                            continue;
                                        pcontacts[ncont].center -= pcontacts[ncont].dir*pcontacts[ncont].t;
                                        ncontact = -pcontacts[ncont].n;//(gwd[0].offset-pcontacts[ncont].center).normalized();
                                        if (fabs_tpl(ncontact.z)<0.5f) {
                                            ncontact.z=0; ncontact.normalize();
                                        }
                                        RigidBody *pbody = pent->GetRigidBody(j);
                                        vrel = ncontact*(pbody->v+(pbody->w^pcontacts[ncont].center-pbody->pos)-vel-m_velGround);
                                        if (iCyl==0 || fabs_tpl(vrel)*time_interval>m_size.x*0.2f) {
                                            vrel = max(0.0f,vrel-ncontact*(vel+m_velGround));
                                            float imp=vrel/max(1e-6f,ncontact*K*ncontact);
                                            ai.impulse = ncontact*imp;
                                            ai.point = pcontacts[ncont].center;    ai.ipart = 0;
                                            if (ai.impulse.len2()*sqr(fMassInv) > max(1.0f,sqr(vrel)))
                                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                                            if ((uFlags & (pef_pushable_by_players|geom_no_coll_response)) == pef_pushable_by_players)
                                                vel += ai.impulse*fMassInv;
                                            /*if (vel.z>-5) {
                                            vel.z = max(0.0f, vel.z); vel.z += ai.impulse.len()*fMassInv*0.1f;
                                            }*/
                                            bFlying = 1; m_timeFlying = 0;
                                            if (m_kInertia==0)
                                                m_timeForceInertia = m_timeImpulseRecover;
                                            if (bPushOther) {
                                                if (fabs_tpl(pcontacts[ncont].dir*axis)<0.7f)
                                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                                ai.impulse.Flip(); ai.ipart = j;
                                                //if (pent->GetType()<PE_LIVING)
                                                //    ai.impulse *= 0.2f;
                                                pent->Action(&ai,1);
                                                m_timeSinceImpulseContact = 0;
                                            }
                                            idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont].id[1]>>31 | max(pcontacts[ncont].id[1],0);
                                            RegisterContact(pos,pcontacts[ncont].pt,ncontact,pent,j,idmat,imp,0,pcontacts[ncont].iPrim[1]);
                                        }
                                    }
                                    //break;
                                }
                            }
                    }
                }
            }
            if (bStaticUnproj && bDynUnproj && m_bSquashed) {
                pos = pos0; // disable unprojection if we are being squashed
                bStaticUnproj = bDynUnproj = 0;
            }
            else if (bStaticUnproj+bDynUnproj>0) {
                newpos = pos+move;
            }
         
            float h = ShootRayDown(pPrecompEnts,nents,pPrecompParts,newpos,nslope);
            float hcur = newpos*axis-m_hPivot;
            const float fAxisDotSlope = axis*nslope;
            if (fAxisDotSlope>m_slopeFall &&
                    (hcur<h && hcur>h-(m_hCyl-m_size.z)*1.01f ||
                     hcur>h && sqr_signed(hcur-h)<vel.len2()*sqr(time_interval) && !bFlying && !m_bJumpRequested && !m_bSwimming))
            {
                if (h>hcur && m_nslope*axis<m_slopeSlide && m_nslope*nslope<m_slopeSlide &&
                        fAxisDotSlope<m_slopeSlide && m_velRequested.len2()==0)
                { 
                    newpos = pos; vel.zero();
                }    else
                    newpos += (heightAdj = axis*(h+m_hPivot-newpos*axis));
                move = newpos-pos; movelen = move.len();
            }
            pos0 = pos;
            if (m_bJumpRequested)
                AddLegsImpulse(-vel,m_nslope,true);
            m_bJumpRequested = 0;
            m_bStuck = 0; ncontactSum.zero();

            if (movelen>m_size.x*1E-4f && m_parts[0].flagsCollider!=0) {
                ip.bSweepTest = true;
                gwd[0].v = move/movelen;
                int iter = 0;
                float move0 = movelen; movesum = 0;
                pe_player_dimensions pd;

                do {
                    float tlim = 0.0f;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    ip.time_interval = movelen+m_pWorld->m_vars.maxContactGapPlayer; tmin = ip.time_interval*2;    iPrim = -1;
                    pNRC = pNoResponseContactLE; pNRC->pent = NULL; pNRC->tmin = tmin;
                    for(i=0; i<nents; ++i) {
                        if (pPrecompEnts[i].entType!=PE_LIVING ||
                                pPrecompEnts[i].nParts - iszero((int)(pPrecompParts[pPrecompEnts[i].iLastPart].partflags & collider_flags)) > 1-bHasExtraParts ||
                                max(sqr(m_qrot.v.x)+sqr(m_qrot.v.y),sqr(pPrecompEnts[i].pent->m_qrot.v.x)+sqr(pPrecompEnts[i].pent->m_qrot.v.y))>0.001f)
                        {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            int bCheckBBox=pPrecompEnts[i].bCheckBBox;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1) {
                                const uint32 uPartFlags = pPrecompParts[j1].partflags;
                                if (uPartFlags & (collider_flags|geom_log_interactions) &&
                                    (!bCheckBBox || AABB_overlap(BBoxInner,pPrecompParts[j1].BBox)))
                                {
                                    if (uPartFlags & geom_log_interactions) {
                                        EventPhysBBoxOverlap event;
                                        event.pEntity[0]=this; event.pForeignData[0]=m_pForeignData; event.iForeignData[0]=m_iForeignData;
                                        event.pEntity[1]=pent; event.pForeignData[1]=pent->m_pForeignData; event.iForeignData[1]=pent->m_iForeignData;
                                        m_pWorld->OnEvent(m_flags, &event);
                                        if (!(uPartFlags & collider_flags))
                                            continue;
                                    }
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;

                                    int ipart = 0;
                                    if((ncont = m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)))
                                        got_contact:
                                        if (pcontacts[ncont-1].t<tmin && pcontacts[ncont-1].n*gwd[0].v>0)    {
                                            if (!((pPrecompParts[j1].partflags | m_parts[ipart].flags)&geom_no_coll_response)) {
                                                // Solid contact
                                                tmin = pcontacts[ncont-1].t; tlim=0.0f; ncontact = -pcontacts[ncont-1].n; ptcontact = pcontacts[ncont-1].pt; iPrim = pcontacts[ncont-1].iPrim[1];
                                                pentmin=pent; jmin=pPrecompParts[j1].ipart; idmat=pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0); ipartMin=ipart;
                                            } else if (pcontacts[ncont-1].t<pNRC->tmin) {
                                                // Non-response contact
                                                pNRC->pent = pent; pNRC->tmin = pcontacts[ncont-1].t;
                                                pNRC->ptcontact = pcontacts[ncont-1].pt; pNRC->ncontact = -pcontacts[ncont-1].n;
                                                pNRC->ipart = pPrecompParts[j1].ipart; pNRC->iPrim = pcontacts[ncont-1].iPrim[1];
                                                pNRC->idmat = pPrecompParts[j1].surface_idx&pcontacts[ncont-1].id[1]>>31 | max(pcontacts[ncont-1].id[1],0);
                                            }
                                        }
                                    for(ipart++; ipart<(m_nParts&-bHasExtraParts); ipart++) if (m_parts[ipart].flagsCollider & uPartFlags) {
                                        gwd[2].R = Matrix33(m_qrot*m_parts[ipart].q);
                                        gwd[2].centerOfMass = gwd[2].offset = pos + m_qrot*m_parts[ipart].pos;
                                        gwd[2].scale = m_parts[ipart].scale; gwd[2].v = gwd[0].v;
                                        if((ncont = m_parts[ipart].pPhysGeomProxy->pGeom->Intersect(pPrecompParts[j1].pgeom, gwd+2,gwd+1, &ip, pcontacts)))
                                            goto got_contact;
                                    }
                                }
                            }
                        }    else {
                            CPhysicalEntity *const pent=pPrecompEnts[i].pent;
                            pent->GetParams(&pd);
                            Vec2 dorigin,ncoll,move2d=(Vec2)gwd[0].v;
                            dorigin = Vec2(pos-pent->m_pos);
                            float kb=dorigin*move2d, kc=len2(dorigin)-sqr(m_size.x+pd.sizeCollider.x), kd=kb*kb-kc, zup0,zdown0,zup1,zdown1;
                            if (kd>=0) {
                                zup0 = (zdown0 = pos.z-m_hPivot)+m_hCyl+m_size.z+m_size.x*m_bUseCapsule;
                                zdown0 = max(zdown0, zup0-(m_size.x*m_bUseCapsule+m_size.z)*2);
                                zup1 = (zdown1 = pent->m_pos.z-pd.heightPivot)+pd.heightCollider+pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule;
                                zdown1 = max(zdown1, zup1-(pd.sizeCollider.x*pd.bUseCapsule+pd.sizeCollider.z)*2);
                                kd=sqrt_tpl(kd);
                                float tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                bool bSideContact = min(zup0+gwd[0].v.z*tfirst,zup1)>max(zdown0+gwd[0].v.z*tfirst,zdown1);
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d>=0 && bSideContact)
                                    continue;    // if entities separate during this timestep, ignore other collisions
                                tfirst=-kb-kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                /*if (tfirst<-m_size.x || min(zup0+gwd[0].v.z*tfirst,zup1)<max(zdown0+gwd[0].v.z*tfirst,zdown1) || ncoll*move2d>=0) {
                                    tfirst=-kb+kd; ncoll = Vec2(pos+gwd[0].v*tfirst-pent->m_pos);
                                }*/
                                if (tfirst>-m_size.x && tfirst<tmin && ncoll*move2d<0 && bSideContact) {
                                    tlim = (tmin = tfirst)*iszero(iter); ncontact.Set(ncoll.x,ncoll.y,0).normalize(); ptcontact = pos+gwd[0].v*tfirst-ncontact*m_size.x;
                                    pentmin=pent; jmin=0; idmat=m_surface_idx; iPrim=-1; ipartMin=0;
                                }
                                // also check for cap-cap contact
                                if (fabs_tpl(gwd[0].v.z)>m_size.z*1E-5f) {
                                    int nSignZ = sgnnz(gwd[0].v.z);    //Could be float?
                                    zup0 = pos.z-m_hPivot+m_hCyl+(m_size.z+m_size.x*m_bUseCapsule)*nSignZ;
                                    zdown1 = pent->m_pos.z-pd.heightPivot+pd.heightCollider-(pd.sizeCollider.z+pd.sizeCollider.x*pd.bUseCapsule)*nSignZ;
                                    tfirst = zdown1-zup0;
                                    if (inrange(tfirst,-m_size.x*gwd[0].v.z,tmin*gwd[0].v.z) &&
                                            len2(dorigin*gwd[0].v.z+move2d*tfirst)<sqr((m_size.x+pd.sizeCollider.x)*gwd[0].v.z))
                                    {
                                        tmin = tfirst/gwd[0].v.z; ncontact.Set(0,0,-nSignZ); (ptcontact = pos+gwd[0].v*tfirst).z += m_size.z*nSignZ; //?
                                        pentmin=pent; jmin=-1; idmat=m_surface_idx; iPrim=-1;    ipartMin=0;
                                    }
                                }
                            }
                        }
                        if (pNRC->pent) {
                            IF (pNRC>=(pNoResponseContactLE+nNoResponseAllocLE-1), 0) {
                                delete [] pNoResponseContactLE; pNoResponseContactLE=new le_tmp_contact[nNoResponseAllocLE+16];
                                pNRC=pNoResponseContactLE+nNoResponseAllocLE-1; nNoResponseAllocLE+=16;
                            }
                            ++pNRC; pNRC->pent=NULL; pNRC->tmin=ip.time_interval*2;
                        }
                    }

                    if (tmin<=ip.time_interval) {
                        tmin = max(tlim,tmin-m_pWorld->m_vars.maxContactGapPlayer);
                        pos += gwd[0].v*tmin;
                        static const float g_cosSlide=cos_tpl(0.3f), g_sinSlide=sin_tpl(0.3f);
                        /*if (bFlying) {
                            if ((ncontact*axis)*(1-m_bSwimming)>g_cosSlide)
                                ncontact = axis*g_cosSlide + (pos-ptcontact-axis*(axis*(pos-ptcontact))).normalized()*g_sinSlide;
                        } else */
                        if (!bFlying && inrange(ncontact*axis, 0.85f,-0.1f) && (unsigned int)pentmin->m_iSimClass-1u<2u &&
                            pentmin->GetMassInv()>m_massinv*0.25f)
                            ncontact.z=0, ncontact.normalize();
                        int bPush = pentmin->m_iSimClass>0 || isneg(min(m_slopeClimb-ncontact*axis, ncontact*axis+m_slopeFall)) | bFlying;
                        int bUnmovable = isneg(-pentmin->m_iSimClass>>31 & ~(-((int)m_flags & pef_pushable_by_players)>>31));
                        bPush &= bUnmovable^1;
                        {
                            Matrix33 K;
                            K.SetZero();
                            int bPushOther = (m_flags & (pentmin->m_iSimClass==3 ? lef_push_players : lef_push_objects)) &&
                                (pentmin->m_flags & pef_pushable_by_players) &&
                                (pentmin->m_iSimClass | m_pWorld->m_vars.bPlayersCanBreak | pentmin->m_flags & pef_players_can_break);
                            bPushOther &= iszero((int)(INT_PTR)pentmin-(int)(INT_PTR)m_pLastGroundCollider)^1;
                            bPushOther |= bUnmovable;
                            if (bPushOther)
                                pentmin->GetContactMatrix(ptcontact, jmin, K);
                            if (!bPushOther || /*pentmin->m_iSimClass-3 | */m_flags & pef_pushable_by_players)
                                GetContactMatrix(ptcontact, -1, K);
                            else
                                bPush = 0;
                            vrel = ncontact*(vel+m_velGround); //(ncontact*gwd[0].v)*vel.len();
                            ai.impulse = ncontact;
                            if (pentmin->m_iSimClass==3) {
                                // make the player slide off when standing on other players
                                vrel -= ncontact*((CLivingEntity*)pentmin)->m_vel;
                                if (ncontact*axis > 0.95f) {
                                    ai.impulse += (pos-pentmin->m_pos-axis*(axis*(pos-pentmin->m_pos))).normalized();
                                    if (inrange(vrel,-1.0f,1.0f))
                                        vrel = -1.0f;
                                }
                            } else {
                                RigidBody *pbody = pentmin->GetRigidBody(jmin);
                                vrel -= ncontact*(pbody->v+(pbody->w^ptcontact-pbody->pos));
                            }
                            vrel = min(0.0f, vrel);
                            float imp = -vrel*1.01f/max(1e-6f,ncontact*K*ncontact);
                            jmin -= jmin>>31;
                            if (bPush || m_flags & lef_report_sliding_contacts || pentmin->m_parts[jmin].flags & geom_manually_breakable)
                                RegisterContact(pos,ptcontact,ncontact,pentmin,jmin,idmat,imp*bPush,0,iPrim,ipartMin);
                            ai.impulse *= imp;
                            ai.point = ptcontact;    ai.ipart = 0;
                            if (ai.impulse.len2()*sqr(m_massinv) > max(1.0f,sqr(vrel)))
                                ai.impulse.normalize() *= fabs_tpl(vrel)*m_mass*0.5f;
                            if (bPush) {
                                vel += ai.impulse*m_massinv;
                                if (m_kInertia==0 && (pentmin->m_iSimClass-3 | m_flags & pef_pushable_by_players))
                                    m_timeForceInertia = m_timeImpulseRecover;
                            }
                            if (bPushOther) {
                                ai.impulse.Flip(); ai.ipart = jmin;
                                if (fabs_tpl(ncontact*axis)<0.7f)
                                    ai.impulse -= axis*(axis*ai.impulse); // ignore vertical component - might be semi-random depending on cylinder intersection
                                ai.iApplyTime = isneg(pentmin->m_iSimClass-3)<<1;
                                if (pentmin->GetType()<PE_LIVING)
                                    ai.impulse *= 0.2f;
                                pentmin->Action(&ai);
                                if (pentmin->m_iSimClass<3)
                                    m_timeSinceImpulseContact = 0;
                            }
                        }
                        movelen -= tmin; movesum += tmin;
                        for(i=0;i<iter && ncontactHist[i]*ncontact<0.95f;i++);
                        if (i==iter)
                            ncontactSum += ncontact;
                        ncontactHist[iter] = ncontact;
                        if (iter==1 && movesum==0.0f) {
                            ncontact = (ncontactHist[0]^ncontactHist[1]).normalized();
                            gwd[0].v = ncontact*(gwd[0].v*ncontact);
                        }    else {
                            gwd[0].v -= ncontact*(gwd[0].v*ncontact);
                            gwd[0].v = gwd[0].v*0.9998f+ncontact*(gwd[0].v.len()*0.02f);
                        }
                        tmin = gwd[0].v.len(); movelen*=tmin;
                        if (tmin>0) gwd[0].v/=tmin;
                        movelen = (float)__fsel(gwd[0].v*move, movelen, 0.0f);
                    } else {
                        pos += gwd[0].v*movelen; movesum += movelen; /* exit do-loop */ iter=1000;
                    }
                    for (le_tmp_contact* c=pNoResponseContactLE; c<=pNRC && c->pent; c++)
                        if (c->tmin<tmin)
                            RegisterContact(pos,c->ptcontact,c->ncontact,c->pent,c->ipart,c->idmat,0.f,0,c->iPrim);
                } while(movelen>m_pWorld->m_vars.maxContactGapPlayer*0.1f && ++iter<3);

                const float fContactSumLenSq = ncontactSum.len2();
                if(movesum<move0*0.001f && (sqr_signed(ncontactSum.z)>sqr(0.4f)*fContactSumLenSq || fContactSumLenSq<0.6f))
                    m_bStuck = 1;

                if (m_parts[0].flagsCollider!=0 && (bUnprojected || !(m_flags & lef_loosen_stuck_checks))) {
                    ip.bSweepTest = false;
                    gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                    gwd[0].v = -axis;
                    ip.bStopAtFirstTri = true; ip.bNoBorder = true; ip.time_interval = m_size.z*10;
                    for(i=0; i<nents; ++i)
                        if (pPrecompEnts[i].iSimClass==0) {
                            CPhysicalEntity *const pent = pPrecompEnts[i].pent;
                            for(int j1=pPrecompEnts[i].iPartsBegin; j1<pPrecompEnts[i].iPartsEnd; ++j1)
                                if (pPrecompParts[j1].partflags & collider_flags && !(pPrecompParts[j1].partflags & geom_no_coll_response)) {
                                    gwd[1].R = Matrix33(pPrecompParts[j1].partrot);
                                    gwd[1].offset = pPrecompParts[j1].partoff;
                                    gwd[1].scale = pPrecompParts[j1].partscale;
                                    if(m_pCylinderGeom->Intersect(pPrecompParts[j1].pgeom, gwd,gwd+1, &ip, pcontacts)) {
                                    if (pcontacts->t>m_pWorld->m_vars.maxContactGapPlayer)
                                        vel.zero(),m_bStuck=1; 
                                    pos = pos0; m_timeUseLowCap=1.0f;
                                    goto nomove;
                                }
                            }
                    } nomove:;
                }
            } else
                pos += move;

            if (!m_pLastGroundCollider)// || m_pLastGroundCollider->GetMassInv()>m_massinv)
                velGround.zero();
            else
                velGround = m_velGround;
            m_hLatest = h = ShootRayDown(pPrecompEnts, nents, pPrecompParts, pos,nslope, time_interval,false,true);
            if (nslope*axis<0.087f)
                nslope = m_nslope;
            else {
                WriteLockCond lock(m_lockLiving,m_bStateReading^1);
                m_nslope = nslope;
            }
            if (m_pLastGroundCollider) {
                RegisterContact(newpos,newpos,m_qrot*Vec3(0,0,1),m_pLastGroundCollider,m_iLastGroundColliderPart,m_lastGroundSurfaceIdx,0,1,m_lastGroundPrim);
                if (m_pLastGroundCollider->m_iSimClass==0)
                    ReleaseGroundCollider();
            }

            if (bFlying)
                m_timeFlying += time_interval;
            int bGroundContact = isneg(max(pos*axis-m_hPivot-(h+m_groundContactEps), m_slopeFall-nslope*axis));
            if (!bGroundContact)
                ReleaseGroundCollider();

            bFlying = m_pWorld->m_vars.bFlyMode || m_gravity*axis>0 || m_bSwimming || ((bGroundContact|m_bStuck)^1);
            m_bActiveEnvironment = m_bStuck;

            if (bFlying)
                Step_HandleFlying(vel, velGround, bWasFlying, heightAdj, kInertia, time_interval);
            else {
                if (bWasFlying)
                    Step_HandleWasFlying(vel, bFlying, axis, bGroundContact);
             
                Vec3 velReq = m_velRequested,g;
                if (!m_bSwimming) velReq -= m_nslope*(velReq*m_nslope);
                if (kInertia * time_interval > 1.0f)    kInertia = 1.0f/time_interval;
                Vec3 last_force = (velReq-vel)*kInertia;
                const float axisSlope = m_nslope*axis;
                if (axisSlope<m_slopeSlide && !m_bSwimming)    {
                    g = m_gravity;
                    last_force += g-m_nslope*(g*m_nslope);
                }
             
                const Vec3 velIncLastForce = vel + (last_force*time_interval);
                if (velIncLastForce*vel<0 && velIncLastForce*m_velRequested<=0)
                    vel.zero();
                else
                    vel = velIncLastForce;

                if (axisSlope<m_slopeClimb) {
                    const float axisVel = vel*axis;
                    if (axisVel>0 && last_force*axis>0)
                        vel -= axis*(axisVel);
                    if ((pos-pos0)*axis > m_size.z*0.001f)
                        vel -= axis*(axis*vel);
                }
                if (axisSlope<m_slopeFall && !m_bStuck) {
                    bFlying=1; vel += m_nslope-axis*(axisSlope);
                }
                if (m_velRequested.len2()==0 && vel.len2()<0.001f || vel.len2()<0.0001f)
                    vel.zero();
            }

            if (!bFlying)
                m_timeFlying = 0;

            if (m_flags & lef_snap_velocities)
                vel = DecodeVec6b(EncodeVec6b(vel));

            if (!m_bStateReading) {
                float dh;
                if (!bFlying && (dh=(pos-pos0)*axis)>m_size.z*0.01f) {
                    m_dhSpeed = max(m_dhSpeed, dh/m_stablehTime);
                    m_dh += dh;
                    m_stablehTime = 0;
                }    else
                    dh = 0;
                m_stablehTime = min(m_stablehTime+time_interval,0.5f);

                m_dhSpeed += m_dhAcc*time_interval;
                if (m_dhAcc==0 && m_dh*m_dhSpeed<0 || m_dh*m_dhAcc<0 || m_dh*(m_dh-m_dhSpeed*time_interval)<0)
                    m_dh = m_dhSpeed = m_dhAcc = 0;
                else
                    m_dh -= m_dhSpeed*time_interval;
            }

            if (m_pHeadGeom) {
                ip.bSweepTest = true;
                gwd[0].offset = pos + gwd[0].R*m_parts[0].pos;
                gwd[0].v = axis;
                tmin = ip.time_interval = m_hHead-m_hCyl-min(m_dh,0.0f);
                for(i=0;i<nents;i++) if (pentlist[i]->m_iSimClass==0) {//pentlist[i]->GetType()!=PE_LIVING && pentlist[i]->GetMassInv()*0.4f<m_massinv) {
                    for(int j1=0;j1<pentlist[i]->GetUsedPartsCount(iCaller);j1++)
                        if (pentlist[i]->m_parts[j=pentlist[i]->GetUsedPart(iCaller,j1)].flags & collider_flags) {
                            Matrix33 rotMat = Matrix33(pentlist[i]->m_qrot*pentlist[i]->m_parts[j].q);
                            gwd[1].R = rotMat;
                            gwd[1].offset = pentlist[i]->m_pos + rotMat*pentlist[i]->m_parts[j].pos;
                            gwd[1].scale = pentlist[i]->m_parts[j].scale;
                            if(m_pHeadGeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts))
                                tmin = min(tmin,(float)pcontacts[0].t);
                        }
                }
                if (m_dh<ip.time_interval+min(m_dh,0.0f)-tmin || fabs_tpl(m_dhSpeed)+fabs_tpl(m_dhAcc)==0)
                    m_dh = ip.time_interval+min(m_dh,0.0f)-tmin;
            }
        }
     
        coord_block_BBox partCoord;
        ComputeBBoxLE(pos,BBoxInner,&partCoord);
        UpdatePosition(pos,BBoxInner, m_pWorld->RepositionEntity(this,1,BBoxInner));
        bMoving = 1;
    } else if (!m_bActive) {
        if (m_velRequested.len2()>0) {
            m_pos += m_velRequested*time_interval;
            m_BBox[0] += m_velRequested*time_interval; m_BBox[1] += m_velRequested*time_interval;
            JobAtomicAdd(&m_pWorld->m_lockGrid,-m_pWorld->RepositionEntity(this,1));
            bMoving = 1;
        }
        if (m_bReleaseGroundColliderWhenNotActive!=0)
            ReleaseGroundCollider();
    }
 
    { WriteLockCond lock(m_lockLiving,m_bStateReading^1);
        //if (m_pWorld->m_vars.bMultiplayer)
        //    m_pos = CompressPos(m_pos);
     
        m_deltaV        = (m_vel - vel0);
        m_vel                = vel+m_vel-vel0;     
        m_bFlying        = bFlying;
        m_deltaQRot = m_qrot * !oldQRot;

        m_timeSmooth = (float)__fsel(-time_interval, m_timeSmooth, time_interval);
        if (m_pWorld->m_bUpdateOnlyFlagged) {
            m_deltaPos = m_posLocal-m_pos;
            if (m_deltaPos.len2()<sqr(0.01f) || m_deltaPos.len2()>sqr(2.0f))
                m_deltaPos.zero();
        }
        if (m_pBody)
            if (!m_nColliders) {
                delete m_pBody; m_pBody=0;
            } else {
                m_pBody->pos=m_pos+m_qrot*Vec3(0,0,m_hCyl); m_pBody->q=m_qrot;
                m_pBody->P=(m_pBody->v=m_vel)*(m_pBody->M=m_mass);
                m_pBody->Minv=m_massinv;
                if (m_pWorld->m_timePhysics > m_timeRotChanged+0.05f)
                    m_pBody->w.zero(), m_pBody->L.zero();
                /*quaternionf dq = m_history[m_iHist].q*!m_history[m_iHist-3&m_szHistory-1].q;
                float dt=0; for(i=0; i<4; i++)
                    dt += m_history[m_iHist-i&m_szHistory-1].dt;
                if (inrange(dt, 0.0f,1.0f)) {
                    if (dq.v.len2()<sqr(0.05f))
                        m_pBody->w = dq.v*(2/dt);
                    else
                        m_pBody->w = dq.v.normalized()*(acos_tpl(dq.w)*2/dt);
                }*/
            }
    }

    if (!m_bStateReading) {
        if( bMoving )    {
            Vec3 gravity; MARK_UNUSED gravity;
            pe_params_buoyancy pb;
            m_pWorld->CheckAreas(this,gravity,&pb,0);
            if (!is_unused(gravity))
                m_gravity = gravity;

            if (m_pWorld->m_pWaterMan)
                m_pWorld->m_pWaterMan->OnWaterInteraction(this);
        }

        if (m_flags & (pef_monitor_poststep | pef_log_poststep)) {
            EventPhysPostStep epps;
            epps.pEntity=this; epps.pForeignData=m_pForeignData; epps.iForeignData=m_iForeignData;
            epps.dt=time_interval; epps.pos=m_pos; epps.q=m_qrot; epps.idStep=m_pWorld->m_idStep;
            epps.pos -= m_qrot*Vec3(0,0,m_dh);
            m_pWorld->OnEvent(m_flags,&epps);
        }
        /*if (m_pWorld->m_iLastLogPump > m_timeLogged)
            m_posLogged = pos0;
        m_timeLogged = m_pWorld->m_iLastLogPump;*/
    }

    return 1;
}
My eyes, they bleed.

Seen worse, though. At least by a factor of 2.


There are 9 instances of "goto." Anyone notice that?
 

Perkel

Arcane
Joined
Mar 28, 2014
Messages
15,875
There are 9 instances of "goto." Anyone notice that?

I am basically 0 at coding but at least i fucking know that when you use more than 5-6 deep indentation for whatever reason you need to seriously think about your code architecture. Bless PEP8 of python.


speaking of cringe and e3.

Nothing beats Konami e3 2010 press conference. Still fucking remember how absurd it was when i watched it live.

 
Last edited:

pOcHa

Arcane
Patron
Joined
Jul 12, 2015
Messages
2,893
Make the Codex Great Again! Grab the Codex by the pussy Insert Title Here RPG Wokedex Strap Yourselves In Codex Year of the Donut Steve gets a Kidney but I don't even get a tag.
that silent hill segment - you just can't stage this shit (theme from jaws was priceless)... but he was actually looking at the teleprompter, the camera angle was just awkward

people liked the goofy presentation so much, they petitioned konami to return next year - but the fuckers were so embarrassed that they did a bland prerecorded video instead
 

Baron Dupek

Arcane
Joined
Jul 23, 2013
Messages
1,870,855
https://github.com/CRYTEK-CRYENGINE/CRYENGINE
That's right, it get open sourced. The first version.
I'm not a fan of their games but if that mean less usage of Unity the better...
Imagine dungeon crawlers in this engine.

It's called Cry Engine because the code makes you cry.

Where is the InstakillHeadshotThePlayerFromAcrossTheMapIfSpotted() function? I remember this being a part of Far Cry.

800 line functions with almost no comments though, that's even more hardcore.

You forgot about the part when player is not hidden in the bush.
 

tormund

Arcane
Joined
Aug 15, 2015
Messages
2,282
Location
Penetrating the underrail
that silent hill segment - you just can't stage this shit (theme from jaws was priceless)... but he was actually looking at the teleprompter, the camera angle was just awkward

people liked the goofy presentation so much, they petitioned konami to return next year - but the fuckers were so embarrassed that they did a bland prerecorded video instead
I could never get any entertainment from cringe fuel like that. Seriously, it's almost physically uncomfortable for me. Those faggy Japanese guys embarrassing themselves is as bad as DO U EVEN LIFT BRAH from that MineCon video...
 

HotSnack

Cipher
Joined
Mar 7, 2006
Messages
650
Why Naughty Dog removed 'fun' from its Uncharted 4 focus tests

Rolling Stone publisher Wenner Media is in the process of launching a new games-focused hub, Glixel, and part of its opening salvo is an intriguingly in-depth interview with Naughty Dog's Neil Druckmann about the design and development of Uncharted 4: A Thief's End.

Druckmann's conversation with Glixel covers a lot of ground, but what's especially notable for game developers is his thoughts on "fun" and how the notion of making a game "fun" impacts game development -- and how it can potentially get in the way of making a holistic experience.

"How do you rate the dive sequence at the beginning of Uncharted 4? Is that fun? There's no real challenge," said Druckmann. "But that level is important, to set up how mundane Nate's life is. Just rating it on its own, one through five, that was constantly the lowest-rated level [in focus tests]. But it kind of had to be. We're not going to change that."

This may not be the most tantalizing bit of behind-the-scenes talk Druckmann indulges in during the interview, but it offers a big-budget example of how developers are shifting the way they talk about games and expanding the scope of their ambition beyond making "fun" experiences. Naughty Dog removed the word from its Uncharted 4 focus tests, says Druckmann, and it seems testers immediately had an easier time of things.

"It used to be, 'How fun did you find this level?' Now it says, 'Overall, how would you rate this level?' Druckmann added. "It becomes less about, 'Did I have fun? Did I have an interesting challenge?' and more about, 'Did I like it?' And I hope people interpret that as, 'Was I engaged? Would I recommend it?''"

As a side benefit, Druckmann says removing the word "fun" from Uncharted 4 focus tests actually caused test scores to rise dramatically.

For more of his comments on how Naughty Dog's latest big-budget hit was designed and developed, including how lessons learned from The Last Of Us were applied to Uncharted 4, check out the full interviewover on Rolling Stone.

Ahahahahahahahaha.

"Guys, one of the levels is not considered fun by our focus testers. So lets fix it by removing fun from the focus tests".

You know, I made a joke in another thread that the drama over them kicking out a focus group tester meant they were willing to not bend over to cater to the "wisdom" of focus groups. It turns out it's true, but only when it means making a game less enjoyable to play at the expense of muh narrative.

Coincidently, the diving section they mention was the exact point I stopped playing the game. For the past 2 hours as the game laboriously told me Nate's tragic childhood I kept thinking. "You know, If this was Uncharted 2 I would have had a cool shoot out level by now that would involve me sliding under and punching some dude in the dick. Probably several times." Series was better when it was unapologetically an Indiana Jones homage.

As a side benefit, Druckmann says removing the word "fun" from Uncharted 4 focus tests actually caused test scores to rise dramatically.
Oh yeah I'm sure it did. :smug:
 

Perkel

Arcane
Joined
Mar 28, 2014
Messages
15,875
Personally, I play games to feel miserable.

post-62477-cats-licking-window-gif-imgur-osey.gif
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom