mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-06 13:47:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "V8World/EdgeBuffer.h"
|
||||
#include "V8World/MovingAssemblyStage.h"
|
||||
#include "V8World/Edge.h"
|
||||
#include "V8World/Joint.h"
|
||||
#include "V8World/Contact.h"
|
||||
#include "V8World/Primitive.h"
|
||||
#include "V8world/World.h"
|
||||
#include "V8world/ContactManager.h"
|
||||
#include "V8world/ContactManagerSpatialHash.h"
|
||||
#include "V8Kernel/Debug.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
EdgeBuffer::~EdgeBuffer()
|
||||
{
|
||||
RBXASSERT(assemblyEdges.empty());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EdgeBuffer::afterAssemblyAdded(Assembly* a)
|
||||
{
|
||||
RBXASSERT_SLOW(debugAddAssembly(a));
|
||||
|
||||
a->visitPrimitives(boost::bind(&EdgeBuffer::assemblyPrimitiveAdded, this, _1));
|
||||
}
|
||||
|
||||
void EdgeBuffer::beforeAssemblyRemoving(Assembly* a)
|
||||
{
|
||||
a->visitPrimitives(boost::bind(&EdgeBuffer::assemblyPrimitiveRemoved, this, _1));
|
||||
|
||||
RBXASSERT_SLOW(debugRemoveAssembly(a));
|
||||
}
|
||||
|
||||
|
||||
void EdgeBuffer::assemblyPrimitiveAdded(Primitive* p)
|
||||
{
|
||||
if (p->getWorld() && p != p->getWorld()->getGroundPrimitive()) {
|
||||
p->getWorld()->getContactManager()->onPrimitiveAssembled(p);
|
||||
}
|
||||
for (int i = 0; i < p->getNumContacts(); ++i) { // this is faster than p->forEachEdge
|
||||
pushEdgeIfOk(p->getContact(i));
|
||||
}
|
||||
for (int i = 0; i < p->getNumJoints(); ++i) {
|
||||
pushEdgeIfOk(p->getJoint(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EdgeBuffer::assemblyPrimitiveRemoved(Primitive* p)
|
||||
{
|
||||
for (int i = 0; i < p->getNumContacts(); ++i) { // this is faster than p->forEachEdge
|
||||
removeEdgeIfDownstream(p->getContact(i));
|
||||
}
|
||||
for (int i = 0; i < p->getNumJoints(); ++i) {
|
||||
removeEdgeIfDownstream(p->getJoint(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EdgeBuffer::assemblyIsHere(Assembly* a)
|
||||
{
|
||||
return ( a
|
||||
&& a->inPipeline()
|
||||
&& a->inOrDownstreamOfStage(this) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Note - for now, everyone does kinematic joints, both clients and server
|
||||
|
||||
void EdgeBuffer::pushEdgeIfOk(Edge* e)
|
||||
{
|
||||
if (e->inStage(this)) {
|
||||
RBXASSERT(Joint::isKinematicJoint(e) == Joint::isMotorJoint(e));
|
||||
|
||||
bool ok = Joint::isKinematicJoint(e) ? pushKinematicOk(e) : pushSpringOk(e); // this is asserting in some places, but needed to allow animation of leg joints after sitting
|
||||
|
||||
if (ok) {
|
||||
e->generateDataForMovingAssemblyStage();
|
||||
getDownstreamWS()->onEdgeAdded(e);
|
||||
RBXASSERT_SLOW(debugPushEdgeToDownstream(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EdgeBuffer::pushSpringOk(Edge* e)
|
||||
{
|
||||
RBXASSERT(e->inStage(this));
|
||||
|
||||
Assembly* a0 = e->getPrimitive(0)->getAssembly();
|
||||
Assembly* a1 = e->getPrimitive(1)->getAssembly();
|
||||
|
||||
bool ok = ( (assemblyIsHere(a0) && assemblyIsHere(a1)) // 1. Both here
|
||||
&& (a0->downstreamOfStage(this) || a1->downstreamOfStage(this)) // 2. One assembly is downstream
|
||||
&& (a0 != a1) ); // 3. Either a kinematic joint (motor), or different assemblies
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Kinematic joints should go for two reasons:
|
||||
|
||||
Both Assemblies Grounded?
|
||||
* this implies no simulation - everyone does it
|
||||
* otherwise, use
|
||||
1. pushSpringOK - i.e. - both assemblies here, at least one downstream (simulating). Will only happen on the dPhysics owner.
|
||||
2.
|
||||
*/
|
||||
|
||||
bool EdgeBuffer::pushKinematicOk(Edge* e)
|
||||
{
|
||||
RBXASSERT(e->inStage(this));
|
||||
RBXASSERT(Joint::isMotorJoint(e));
|
||||
|
||||
Assembly* a0 = e->getPrimitive(0)->getAssembly();
|
||||
|
||||
RBX_ENGINE_ASSERT(a0 == e->getPrimitive(1)->getAssembly());
|
||||
|
||||
bool allClientsStepUi = a0->computeIsGrounded();
|
||||
bool thisClientDoDPhysics = (assemblyIsHere(a0) && a0->downstreamOfStage(this));
|
||||
|
||||
return (allClientsStepUi || thisClientDoDPhysics);
|
||||
}
|
||||
|
||||
|
||||
void EdgeBuffer::removeEdgeIfDownstream(Edge* e)
|
||||
{
|
||||
if (e->downstreamOfStage(this)) {
|
||||
getDownstreamWS()->onEdgeRemoving(e);
|
||||
RBXASSERT_SLOW(debugRemoveEdgeFromDownstream(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void EdgeBuffer::onEdgeAdded(Edge* e)
|
||||
{
|
||||
RBXASSERT(!Joint::isGroundJoint(e));
|
||||
RBXASSERT(!Joint::isRigidJoint(e));
|
||||
e->putInStage(this);
|
||||
pushEdgeIfOk(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EdgeBuffer::onEdgeRemoving(Edge* e)
|
||||
{
|
||||
removeEdgeIfDownstream(e);
|
||||
e->removeFromStage(this);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool EdgeBuffer::debugPushEdgeToDownstream(Edge* e)
|
||||
{
|
||||
RBXASSERT_NOT_RELEASE();
|
||||
|
||||
RBXASSERT(e->downstreamOfStage(this));
|
||||
|
||||
Assembly* a0 = e->getPrimitive(0)->getAssembly();
|
||||
Assembly* a1 = e->getPrimitive(1)->getAssembly();
|
||||
RBXASSERT(a0 && a1);
|
||||
|
||||
if (a0 != a1) {
|
||||
assemblyEdges.insertPair(a0, e);
|
||||
assemblyEdges.insertPair(a1, e);
|
||||
}
|
||||
else {
|
||||
RBXASSERT(Joint::isMotorJoint(e));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EdgeBuffer::debugRemoveEdgeFromDownstream(Edge* e)
|
||||
{
|
||||
RBXASSERT_NOT_RELEASE();
|
||||
|
||||
Assembly* a0 = e->getPrimitive(0)->getAssembly();
|
||||
Assembly* a1 = e->getPrimitive(1)->getAssembly();
|
||||
RBXASSERT(a0 && a1);
|
||||
|
||||
if (a0 != a1) {
|
||||
assemblyEdges.removePair(a0, e);
|
||||
assemblyEdges.removePair(a1, e);
|
||||
}
|
||||
else {
|
||||
RBXASSERT(Joint::isMotorJoint(e));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EdgeBuffer::debugAddAssembly(Assembly* a)
|
||||
{
|
||||
RBXASSERT_NOT_RELEASE();
|
||||
|
||||
//RBXASSERT(assemblyEdges.emptyLeft(a));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool EdgeBuffer::debugRemoveAssembly(Assembly* a)
|
||||
{
|
||||
RBXASSERT_NOT_RELEASE();
|
||||
|
||||
RBXASSERT(assemblyEdges.emptyLeft(a));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user