void PxCloth::onRemove() { SAFE_DELETE( mMatInst ); if ( isClientObject() ) { _releaseCloth(); _releaseMesh(); PhysicsPlugin::getPhysicsResetSignal().remove( this, &PxCloth::onPhysicsReset ); } removeFromScene(); Parent::onRemove(); }
void PxCloth::_initClothMesh() { // Make sure we can change the world. mWorld->releaseWriteLock(); _releaseMesh(); // Must have at least 2 verts. mPatchVerts.x = getMax( 2, mPatchVerts.x ); mPatchVerts.y = getMax( 2, mPatchVerts.y ); // Generate a uniform cloth patch, // w and h are the width and height, // d is the distance between vertices. mNumVertices = mPatchVerts.x * mPatchVerts.y; mNumIndices = (mPatchVerts.x-1) * (mPatchVerts.y-1) * 2; NxClothMeshDesc desc; desc.numVertices = mNumVertices; desc.numTriangles = mNumIndices; desc.pointStrideBytes = sizeof(NxVec3); desc.triangleStrideBytes = 3*sizeof(NxU32); desc.points = (NxVec3*)dMalloc(sizeof(NxVec3)*desc.numVertices); desc.triangles = (NxU32*)dMalloc(sizeof(NxU32)*desc.numTriangles*3); desc.flags = 0; U32 i,j; NxVec3 *p = (NxVec3*)desc.points; F32 patchWidth = mPatchSize.x / (F32)( mPatchVerts.x - 1 ); F32 patchHeight = mPatchSize.y / (F32)( mPatchVerts.y - 1 ); for (i = 0; i < mPatchVerts.y; i++) { for (j = 0; j < mPatchVerts.x; j++) { p->set( patchWidth * j, 0.0f, patchHeight * i ); p++; } } NxU32 *id = (NxU32*)desc.triangles; for (i = 0; i < mPatchVerts.y-1; i++) { for (j = 0; j < mPatchVerts.x-1; j++) { NxU32 i0 = i * mPatchVerts.x + j; NxU32 i1 = i0 + 1; NxU32 i2 = i0 + mPatchVerts.x; NxU32 i3 = i2 + 1; if ( (j+i) % 2 ) { *id++ = i0; *id++ = i2; *id++ = i1; *id++ = i1; *id++ = i2; *id++ = i3; } else { *id++ = i0; *id++ = i2; *id++ = i3; *id++ = i0; *id++ = i3; *id++ = i1; } } } NxCookingInterface *cooker = PxWorld::getCooking(); cooker->NxInitCooking(); // Ok... cook the mesh! NxCookingParams params; params.targetPlatform = PLATFORM_PC; params.skinWidth = 0.01f; params.hintCollisionSpeed = false; cooker->NxSetCookingParams( params ); PxMemStream cooked; if ( cooker->NxCookClothMesh( desc, cooked ) ) { cooked.resetPosition(); mClothMesh = gPhysicsSDK->createClothMesh( cooked ); } cooker->NxCloseCooking(); NxVec3 *ppoints = (NxVec3*)desc.points; NxU32 *triangs = (NxU32*)desc.triangles; dFree( ppoints ); dFree( triangs ); if ( mClothMesh ) _initReceiveBuffers(); }
void PxCloth::unpackUpdate( NetConnection *conn, BitStream *stream ) { Parent::unpackUpdate( conn, stream ); // TransformMask if ( stream->readFlag() ) { MatrixF mat; mathRead( *stream, &mat ); setTransform( mat ); } // MaterialMask if ( stream->readFlag() ) { stream->read( &mMaterialName ); SAFE_DELETE( mMatInst ); } // ClothMask if ( stream->readFlag() ) { Point2I patchVerts; Point2F patchSize; mathRead( *stream, &patchVerts ); mathRead( *stream, &patchSize ); if ( patchVerts != mPatchVerts || !patchSize.equal( mPatchSize ) ) { mPatchVerts = patchVerts; mPatchSize = patchSize; _releaseMesh(); } U32 attachMask; stream->read( &attachMask ); if ( attachMask != mAttachmentMask ) { mAttachmentMask = attachMask; _releaseCloth(); } mBendingEnabled = stream->readFlag(); mDampingEnabled = stream->readFlag(); mTriangleCollisionEnabled = stream->readFlag(); mSelfCollisionEnabled = stream->readFlag(); stream->read( &mThickness ); stream->read( &mFriction ); stream->read( &mBendingStiffness ); stream->read( &mDampingCoefficient ); F32 density; stream->read( &density ); if ( density != mDensity ) { mDensity = density; _releaseCloth(); } if ( isClientObject() && isProperlyAdded() && mWorld && !mCloth ) { _createClothPatch(); } _updateClothProperties(); } }
void PxCloth::unpackUpdate( NetConnection *conn, BitStream *stream ) { Parent::unpackUpdate( conn, stream ); // TransformMask if ( stream->readFlag() ) { MatrixF mat; mathRead( *stream, &mat ); // start jc if(mCloth) { NxVec3 delta(mat.getPosition() - getTransform().getPosition()); if(mCloth->isSleeping()) mCloth->wakeUp(); if ( mAttachmentMask & BIT( 0 ) ) mCloth->attachVertexToGlobalPosition( 0, mCloth->getPosition( 0 ) + delta ); if ( mAttachmentMask & BIT( 1 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x-1, mCloth->getPosition( mPatchVerts.x-1 ) + delta ); if ( mAttachmentMask & BIT( 2 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x ) + delta ); if ( mAttachmentMask & BIT( 3 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - 1, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - 1 ) + delta ); if ( mAttachmentMask & BIT( 4 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2), mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2) ) + delta ); if ( mAttachmentMask & BIT( 5 ) ) mCloth->attachVertexToGlobalPosition( (mPatchVerts.x/2), mCloth->getPosition( (mPatchVerts.x/2) ) + delta ); if ( mAttachmentMask & BIT( 6 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) ) + delta ); if ( mAttachmentMask & BIT( 7 ) ) mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1) ) + delta ); if ( mAttachmentMask & BIT( 8 ) ) for ( U32 i = mPatchVerts.x * mPatchVerts.y - mPatchVerts.x; i < mPatchVerts.x * mPatchVerts.y; i++ ) mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta ); if ( mAttachmentMask & BIT( 9 ) ) for ( U32 i = 0; i < mPatchVerts.x; i++ ) mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta ); if ( mAttachmentMask & BIT( 10 ) ) for ( U32 i = 0; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta ); if ( mAttachmentMask & BIT( 11 ) ) for ( U32 i = mPatchVerts.x-1; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta ); } // end jc setTransform( mat ); } // start jc // ScaleAttachmentPointsMask if ( stream->readFlag() ) { Point3F attachmentPointScale; mathRead( *stream, &attachmentPointScale ); if(mCloth) { Point3F scale(Point3F::One); scale.convolveInverse(mAttachmentPointScale); scale.convolve(attachmentPointScale); NxVec3 delta(scale); if(mCloth->isSleeping()) mCloth->wakeUp(); static NxVec3 delta2; if ( mAttachmentMask & BIT( 0 ) ) { delta2.arrayMultiply(mCloth->getPosition( 0 ),delta); mCloth->attachVertexToGlobalPosition( 0, delta2); } if ( mAttachmentMask & BIT( 1 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x-1 ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x-1, delta2); } if ( mAttachmentMask & BIT( 2 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x, delta2); } if ( mAttachmentMask & BIT( 3 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - 1 ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - 1, delta2); } if ( mAttachmentMask & BIT( 4 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2) ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2), delta2); } if ( mAttachmentMask & BIT( 5 ) ) { delta2.arrayMultiply(mCloth->getPosition( (mPatchVerts.x/2) ), delta); mCloth->attachVertexToGlobalPosition( (mPatchVerts.x/2), delta2); } if ( mAttachmentMask & BIT( 6 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2), delta2); } if ( mAttachmentMask & BIT( 7 ) ) { delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1) ), delta); mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1), delta2); } if ( mAttachmentMask & BIT( 8 ) ) for ( U32 i = mPatchVerts.x * mPatchVerts.y - mPatchVerts.x; i < mPatchVerts.x * mPatchVerts.y; i++ ) { delta2.arrayMultiply(mCloth->getPosition( i ), delta); mCloth->attachVertexToGlobalPosition( i, delta2); } if ( mAttachmentMask & BIT( 9 ) ) for ( U32 i = 0; i < mPatchVerts.x; i++ ) { delta2.arrayMultiply(mCloth->getPosition( i ), delta); mCloth->attachVertexToGlobalPosition( i, delta2); } if ( mAttachmentMask & BIT( 10 ) ) for ( U32 i = 0; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) { delta2.arrayMultiply(mCloth->getPosition( i ), delta); mCloth->attachVertexToGlobalPosition( i, delta2); } if ( mAttachmentMask & BIT( 11 ) ) for ( U32 i = mPatchVerts.x-1; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) { delta2.arrayMultiply(mCloth->getPosition( i ), delta); mCloth->attachVertexToGlobalPosition( i, delta2); } } mAttachmentPointScale = attachmentPointScale; } // end jc // MaterialMask if ( stream->readFlag() ) { stream->read( &mMaterialName ); SAFE_DELETE( mMatInst ); } // ClothMask if ( stream->readFlag() ) { Point2I patchVerts; Point2F patchSize; mathRead( *stream, &patchVerts ); mathRead( *stream, &patchSize ); if ( patchVerts != mPatchVerts || !patchSize.equal( mPatchSize ) ) { mPatchVerts = patchVerts; mPatchSize = patchSize; _releaseMesh(); } U32 attachMask; stream->read( &attachMask ); if ( attachMask != mAttachmentMask ) { mAttachmentMask = attachMask; _releaseCloth(); } mBendingEnabled = stream->readFlag(); mDampingEnabled = stream->readFlag(); mTriangleCollisionEnabled = stream->readFlag(); mSelfCollisionEnabled = stream->readFlag(); stream->read( &mThickness ); stream->read( &mFriction ); stream->read( &mBendingStiffness ); stream->read( &mDampingCoefficient ); F32 density; stream->read( &density ); if ( density != mDensity ) { mDensity = density; _releaseCloth(); } if ( isClientObject() && isProperlyAdded() && mWorld && !mCloth ) { _createClothPatch(); } _updateClothProperties(); } }