mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 05:07:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Humanoid/Jumping.h"
|
||||
#include "Humanoid/Humanoid.h"
|
||||
|
||||
#include "V8DataModel/PartInstance.h"
|
||||
#include "V8DataModel/Accoutrement.h"
|
||||
#include "V8World/Primitive.h"
|
||||
#include "V8World/World.h"
|
||||
#include "V8World/ContactManager.h"
|
||||
#include "V8Kernel/Body.h"
|
||||
#include "V8Kernel/Kernel.h"
|
||||
|
||||
DYNAMIC_FASTINTVARIABLE(PGSJumpForceAdjustment, 520)
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
const char* const sJumping = "Jumping";
|
||||
|
||||
|
||||
Jumping::Jumping(Humanoid* humanoid, StateType priorState)
|
||||
:Named<Flying, sJumping>(humanoid, priorState)
|
||||
,jumpDir(0.0f, 1.0f, 0.0f)
|
||||
{
|
||||
if (priorState == SWIMMING)
|
||||
{
|
||||
setOutOfWater();
|
||||
}
|
||||
else if (priorState == CLIMBING)
|
||||
{
|
||||
Vector3 lookDir = humanoid->getTorsoSlow()->getCoordinateFrame().lookVector();
|
||||
lookDir.y = 0.0f;
|
||||
lookDir = lookDir.unit();
|
||||
jumpDir = jumpDir - (lookDir);
|
||||
jumpDir = jumpDir.unit();
|
||||
}
|
||||
setTimer(0.5);
|
||||
}
|
||||
|
||||
|
||||
void Jumping::onComputeForceImpl()
|
||||
{
|
||||
Super::onComputeForceImpl();
|
||||
|
||||
if (!getFinished())
|
||||
{
|
||||
Humanoid* humanoid = getHumanoid();
|
||||
Body* root = humanoid->getRootBodyFast();
|
||||
|
||||
float jumpVelocity = root->getVelocity().linear.dot(jumpDir);
|
||||
|
||||
float targetVelocity = humanoid->getJumpPower();
|
||||
|
||||
const float yAccelDesired = root ? kJumpP() * (targetVelocity - jumpVelocity) : 0.0f;
|
||||
//StandardOut::singleton()->printf(RBX::MESSAGE_INFO, "%f", root->getVelocity().linear.y);
|
||||
|
||||
if (yAccelDesired<=0.0) { // We've acheived the desired velocity
|
||||
setFinished(true);
|
||||
}
|
||||
else if (findCeiling()) {
|
||||
setFinished(true);
|
||||
}
|
||||
else if (root ) {
|
||||
Primitive* floor = getFloorPrimitive();
|
||||
if (floor) {
|
||||
Body* floorRoot = floor->getBody()->getRoot();
|
||||
float mass;
|
||||
if (getHumanoid()->getWorld()->getUsingPGSSolver())
|
||||
{
|
||||
mass = root->getBranchMass();
|
||||
} else {
|
||||
mass = std::min(root->getBranchMass(), floorRoot->getBranchMass());
|
||||
}
|
||||
const float newForceY = mass * yAccelDesired;
|
||||
const float& currentForceYRef = root->getBranchForce().y;
|
||||
|
||||
if (newForceY > currentForceYRef) {
|
||||
const float diff = newForceY - currentForceYRef;
|
||||
|
||||
if (getHumanoid()->getWorld()->getUsingPGSSolver()) // For PGS kernel bodies we apply a fraction of the force
|
||||
{
|
||||
float factor = (float) DFInt::PGSJumpForceAdjustment / 1000.0f;
|
||||
root->accumulateForceAtBranchCofm(jumpDir * newForceY * factor);
|
||||
floorRoot->accumulateForce(Vector3(0.0, -diff * factor, 0.0), getFloorTouchInWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Clamp this?
|
||||
root->accumulateForceAtBranchCofm(jumpDir * newForceY);
|
||||
floorRoot->accumulateForce(Vector3(0.0, -diff, 0.0), getFloorTouchInWorld());
|
||||
}
|
||||
}
|
||||
} else
|
||||
{ // always apply - if we are not near the floor, the jumping state will end
|
||||
const float newForceY = root->getBranchMass() * yAccelDesired;
|
||||
if (getHumanoid()->getWorld()->getUsingPGSSolver())
|
||||
root->accumulateForceAtBranchCofm(jumpDir * newForceY * 0.1);
|
||||
else
|
||||
root->accumulateForceAtBranchCofm(jumpDir * newForceY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Jumping::findCeiling()
|
||||
{
|
||||
Humanoid* humanoid = getHumanoid();
|
||||
|
||||
if (Primitive* torsoPrim = humanoid->getTorsoPrimitiveSlow())
|
||||
{
|
||||
const CoordinateFrame& torsoC = torsoPrim->getCoordinateFrame();
|
||||
|
||||
Vector3 halfSize = 0.4f * torsoPrim->getSize();
|
||||
|
||||
Vector3 pointOnTorso = torsoC.pointToWorldSpace(Vector3(0, -halfSize.y, 0));
|
||||
|
||||
RbxRay tryRay = RbxRay::fromOriginAndDirection(pointOnTorso, Vector3::unitY());
|
||||
|
||||
float maxDistance;
|
||||
Primitive* headPrim = humanoid->getHeadPrimitiveSlow();
|
||||
|
||||
if (headPrim)
|
||||
maxDistance = headPrim->getSize().y + torsoPrim->getSize().y * 1.5f;
|
||||
else
|
||||
maxDistance = torsoPrim->getSize().y * 1.5f;
|
||||
|
||||
shared_ptr<PartInstance> ceilingPart = tryCeiling(tryRay, maxDistance, torsoPrim->getAssembly());
|
||||
|
||||
if (ceilingPart)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
for (int x = -1; x <= 1; x+=2) {
|
||||
for (int z = -1; z <= 1; z+=2)
|
||||
{
|
||||
Vector3 offset (x * halfSize.x, -halfSize.y, z * halfSize.z);
|
||||
|
||||
pointOnTorso = torsoC.pointToWorldSpace(offset);
|
||||
|
||||
tryRay = RbxRay::fromOriginAndDirection(pointOnTorso, Vector3::unitY());
|
||||
|
||||
if ((ceilingPart = tryCeiling(tryRay, maxDistance, torsoPrim->getAssembly())))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
shared_ptr<PartInstance> Jumping::tryCeiling(const RbxRay& ray, float maxDistance, Assembly* humanoidAssembly)
|
||||
{
|
||||
Humanoid* humanoid = getHumanoid();
|
||||
float distance;
|
||||
RBXASSERT(humanoidAssembly);
|
||||
|
||||
filteringAssembly = humanoidAssembly;
|
||||
Vector3 hitPoint;
|
||||
|
||||
Primitive* floorPrim = humanoid->getWorld()->getContactManager()->getHitLegacy( ray,
|
||||
NULL,
|
||||
this,
|
||||
hitPoint,
|
||||
distance,
|
||||
maxDistance,
|
||||
true);
|
||||
shared_ptr<PartInstance> answer;
|
||||
if (floorPrim && (floorPrim->getAssembly() != humanoidAssembly))
|
||||
{
|
||||
answer = shared_from<PartInstance>(PartInstance::fromPrimitive(floorPrim));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
HitTestFilter::Result Jumping::filterResult(const Primitive* testMe) const
|
||||
{
|
||||
RBXASSERT(testMe);
|
||||
|
||||
HitTestFilter::Result newResult = HitTestFilter::INCLUDE_PRIM;
|
||||
|
||||
if ( (!testMe->getCanCollide())
|
||||
|| (filteringAssembly && (filteringAssembly == testMe->getConstAssembly()))
|
||||
|| (Instance::fastDynamicCast<Accoutrement>(PartInstance::fromConstPrimitive(testMe))))
|
||||
{
|
||||
newResult = HitTestFilter::IGNORE_PRIM;
|
||||
}
|
||||
|
||||
return newResult;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user