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,233 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "V8World/PrismPoly.h"
|
||||
#include "V8World/Mesh.h"
|
||||
|
||||
#include "V8World/GeometryPool.h"
|
||||
#include "V8World/PrismMesh.h"
|
||||
#include "Util/Math.h"
|
||||
|
||||
|
||||
namespace RBX {
|
||||
|
||||
void PrismPoly::buildMesh()
|
||||
{
|
||||
Vector3_2Ints key;
|
||||
key.vectPart = getSize();
|
||||
key.int1 = numSides;
|
||||
key.int2 = numSlices;
|
||||
|
||||
prismMesh = PrismMeshPool::getToken(key);
|
||||
|
||||
mesh = prismMesh->getMesh();
|
||||
}
|
||||
|
||||
// Redundant code here - both Prism and Pyramid should descend from common "sided poly"??
|
||||
void PrismPoly::setGeometryParameter(const std::string& parameter, int value)
|
||||
{
|
||||
if (parameter == "NumSides") {
|
||||
setNumSides(value);
|
||||
}
|
||||
else if (parameter == "NumSlices") {
|
||||
setNumSlices(value);
|
||||
}
|
||||
else {
|
||||
RBXASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
int PrismPoly::getGeometryParameter(const std::string& parameter) const
|
||||
{
|
||||
if (parameter == "NumSides") {
|
||||
return numSides;
|
||||
}
|
||||
else if (parameter == "NumSlices") {
|
||||
return numSlices;
|
||||
}
|
||||
else {
|
||||
RBXASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrismPoly::setNumSides( int num )
|
||||
{
|
||||
if (numSides != num) {
|
||||
numSides = num;
|
||||
buildMesh();
|
||||
}
|
||||
}
|
||||
|
||||
void PrismPoly::setNumSlices( int num )
|
||||
{
|
||||
if (numSlices != num) {
|
||||
numSlices = num;
|
||||
buildMesh();
|
||||
}
|
||||
}
|
||||
|
||||
Matrix3 PrismPoly::getMoment(float mass) const
|
||||
{
|
||||
Vector3 size = getSize();
|
||||
|
||||
float area = 2 * (size.x * size.y + size.y * size.z + size.z * size.x);
|
||||
Vector3 I;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int j = (i + 1) % 3;
|
||||
int k = (i + 2) % 3;
|
||||
float x = size[i]; // main axis;
|
||||
float y = size[j];
|
||||
float z = size[k];
|
||||
|
||||
float Ix = (mass / (2.0f * area)) * ( (y*y*y*z/3.0f)
|
||||
+ (y*z*z*z/3.0f)
|
||||
+ (x*y*z*z)
|
||||
+ (x*y*y*y/3.0f)
|
||||
+ (x*y*y*z)
|
||||
+ (x*z*z*z/3.0f) );
|
||||
I[i] = Ix;
|
||||
}
|
||||
return Math::fromDiagonal(I);
|
||||
}
|
||||
|
||||
Vector3 PrismPoly::getCofmOffset( void ) const
|
||||
{
|
||||
return prismMesh->GetLocalCofMFromMesh();
|
||||
}
|
||||
|
||||
|
||||
CoordinateFrame PrismPoly::getSurfaceCoordInBody( const size_t surfaceId ) const
|
||||
{
|
||||
CoordinateFrame aCS;
|
||||
|
||||
// Set rotation
|
||||
aCS.rotation = Math::getWellFormedRotForZVector(mesh->getFace(surfaceId)->normal());
|
||||
|
||||
// Set origin
|
||||
Vector3 bMin, bMax, bCenter;
|
||||
Vector3 xF = aCS.rotation * Vector3::unitX();
|
||||
Vector3 yF = aCS.rotation * Vector3::unitY();
|
||||
|
||||
// For top and bottom surface use the center of the oriented bounding box.
|
||||
// For side surfaces use centroid, but still use the top/bottom bounding box for snapping offset.
|
||||
// This gives prisms a continuous snapping experience as you drag from top to side.
|
||||
float originAdjustX = 0.0f;
|
||||
float originAdjustY = 0.0f;
|
||||
if( surfaceId == mesh->numFaces() - 1 || surfaceId == mesh->numFaces() - 2 )
|
||||
{
|
||||
mesh->getFace(surfaceId)->getOrientedBoundingBox(xF, yF, bMin, bMax, bCenter);
|
||||
aCS.translation = bCenter;
|
||||
// Adjust origin to account for even or odd stud pattern
|
||||
originAdjustX = Math::evenWholeNumberFuzzy((bMin - bMax).dot(xF)) ? 0.0f : 0.5f;
|
||||
originAdjustY = Math::evenWholeNumberFuzzy((bMin - bMax).dot(yF)) ? 0.0f : 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh->getFace(mesh->numFaces() - 1)->getOrientedBoundingBox(xF, yF, bMin, bMax, bCenter);
|
||||
aCS.translation = (mesh->getFace(surfaceId)->getVertex(0)->getOffset() + mesh->getFace(surfaceId)->getVertex(1)->getOffset()) * 0.5;
|
||||
originAdjustX = Math::evenWholeNumberFuzzy((bMin - bMax).dot(xF)) ? 0.0f : 0.5f;
|
||||
}
|
||||
|
||||
aCS.translation += originAdjustX * xF + originAdjustY * yF;
|
||||
|
||||
return aCS;
|
||||
}
|
||||
|
||||
size_t PrismPoly::getFaceFromLegacyNormalId( const NormalId nId ) const
|
||||
{
|
||||
// return -1 if does not exist
|
||||
// return -1 if does not exist
|
||||
// *** NOTE: Prisms with more than 8 sides don't have their sides mapped to legacy normals.
|
||||
RBXASSERT( mesh->numFaces() > 3 );
|
||||
size_t faceId = -1;
|
||||
switch(nId)
|
||||
{
|
||||
case NORM_X:
|
||||
switch(numSides)
|
||||
{
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
faceId = 1;
|
||||
break;
|
||||
case 8:
|
||||
faceId = 2;
|
||||
break;
|
||||
default:
|
||||
faceId = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NORM_X_NEG:
|
||||
switch(numSides)
|
||||
{
|
||||
case 3:
|
||||
faceId = 2;
|
||||
break;
|
||||
case 4:
|
||||
faceId = 3;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
faceId = 4;
|
||||
break;
|
||||
case 8:
|
||||
faceId = 6;
|
||||
break;
|
||||
default:
|
||||
faceId = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NORM_Y:
|
||||
faceId = mesh->numFaces() - 2;
|
||||
break;
|
||||
case NORM_Y_NEG:
|
||||
faceId = mesh->numFaces() - 1;
|
||||
break;
|
||||
case NORM_Z:
|
||||
switch(numSides)
|
||||
{
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 8:
|
||||
faceId = 0;
|
||||
break;
|
||||
default:
|
||||
faceId = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NORM_Z_NEG:
|
||||
switch(numSides)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
faceId = 2;
|
||||
break;
|
||||
case 6:
|
||||
faceId = 3;
|
||||
break;
|
||||
case 8:
|
||||
faceId = 4;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
faceId = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return faceId;
|
||||
}
|
||||
|
||||
|
||||
} // namespace RBX
|
||||
Reference in New Issue
Block a user