void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const { (void)aabbMin; (void)aabbMax; int numtotalphysicsverts = 0; int part,graphicssubparts = getNumSubParts(); const unsigned char * vertexbase; const unsigned char * indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; int stride,numverts,numtriangles; int gfxindex; btVector3 triangle[3]; btVector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype for (part=0;part<graphicssubparts ;part++) { getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part); numtotalphysicsverts+=numtriangles*3; //upper bound ///unlike that developers want to pass in double-precision meshes in single-precision Bullet build ///so disable this feature by default ///see patch http://code.google.com/p/bullet/issues/detail?id=213 switch (type) { case PHY_FLOAT: { float* graphicsbase; switch (gfxindextype) { case PHY_INTEGER: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride); graphicsbase = (float*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } case PHY_SHORT: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride); graphicsbase = (float*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } case PHY_UCHAR: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride); graphicsbase = (float*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); graphicsbase = (float*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } default: btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); } break; } case PHY_DOUBLE: { double* graphicsbase; switch (gfxindextype) { case PHY_INTEGER: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride); graphicsbase = (double*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } case PHY_SHORT: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride); graphicsbase = (double*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } case PHY_UCHAR: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride); graphicsbase = (double*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); graphicsbase = (double*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } default: btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); } break; } default: btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); } unLockReadOnlyVertexBase(part); } }
void scale (const T x, const T y) { this->operator *=(getScaling(x, y)); }
void AbsoluteLayout::updateLayout(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent) const { Pnt2f ParentInsetsTopLeft, ParentInsetBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(ParentInsetsTopLeft, ParentInsetBottomRight); Vec2f borderSize(ParentInsetBottomRight-ParentInsetsTopLeft); Vec2f ComponentSize; Pnt2f ComponentPosition; for(UInt32 i = 0 ; i<Components->size(); ++i) { //Calculate the Components Size if((*Components)[i]->getConstraints() != NULL) { ComponentPosition = dynamic_cast<AbsoluteLayoutConstraints*>((*Components)[i]->getConstraints())->getPosition(); } else { ComponentPosition.setValues(0.0f,0.0f); } ComponentSize = (*Components)[i]->getPreferredSize(); if(getScaling()) { Vec2f DifferenceRatio(borderSize.x() / getOriginalDimensions().x(), borderSize.y() / getOriginalDimensions().y()); ComponentPosition.setValues(ComponentPosition.x() * DifferenceRatio.x(), ComponentPosition.y() * DifferenceRatio.y()); ComponentSize.setValues(ComponentSize.x() * DifferenceRatio.x(), ComponentSize.y() * DifferenceRatio.y()); } else { if(ComponentPosition.x() <= 1.0f) { ComponentPosition[0] = ComponentPosition.x() * borderSize.x(); } if(ComponentPosition.y() <= 1.0f) { ComponentPosition[1] = ComponentPosition.y() * borderSize.y(); } if(ComponentSize.x() <= 1.0f) { ComponentSize[0] = ComponentSize.x() * borderSize.x(); } if(ComponentSize.y() <= 1.0f) { ComponentSize[1] = ComponentSize.y() * borderSize.y(); } } ComponentPosition = ParentInsetsTopLeft + ComponentPosition.subZero(); if((*Components)[i]->getPosition() != ComponentPosition) { (*Components)[i]->setPosition(ComponentPosition); } if((*Components)[i]->getSize() != ComponentSize) { (*Components)[i]->setSize(ComponentSize); } } }
///fills the dataBuffer and returns the struct name (and 0 on failure) const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const { btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer; trimeshData->m_numMeshParts = getNumSubParts(); //void* uniquePtr = 0; trimeshData->m_meshPartsPtr = 0; if (trimeshData->m_numMeshParts) { btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts); btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr; trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr); // int numtotalphysicsverts = 0; int part,graphicssubparts = getNumSubParts(); const unsigned char * vertexbase; const unsigned char * indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; int stride,numverts,numtriangles; int gfxindex; // btVector3 triangle[3]; btVector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype for (part=0;part<graphicssubparts ;part++,memPtr++) { getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part); memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles memPtr->m_numVertices = numverts; memPtr->m_indices16 = 0; memPtr->m_indices32 = 0; memPtr->m_3indices16 = 0; memPtr->m_3indices8 = 0; memPtr->m_vertices3f = 0; memPtr->m_vertices3d = 0; switch (gfxindextype) { case PHY_INTEGER: { int numindices = numtriangles*3; if (numindices) { btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices); btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr; memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices); for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride); tmpIndices[gfxindex*3].m_value = tri_indices[0]; tmpIndices[gfxindex*3+1].m_value = tri_indices[1]; tmpIndices[gfxindex*3+2].m_value = tri_indices[2]; } serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); } break; } case PHY_SHORT: { if (numtriangles) { btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles); btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr; memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices); for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride); tmpIndices[gfxindex].m_values[0] = tri_indices[0]; tmpIndices[gfxindex].m_values[1] = tri_indices[1]; tmpIndices[gfxindex].m_values[2] = tri_indices[2]; } serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); } break; } case PHY_UCHAR: { if (numtriangles) { btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles); btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr; memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices); for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride); tmpIndices[gfxindex].m_values[0] = tri_indices[0]; tmpIndices[gfxindex].m_values[1] = tri_indices[1]; tmpIndices[gfxindex].m_values[2] = tri_indices[2]; } serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); } break; } default: { btAssert(0); //unknown index type } } switch (type) { case PHY_FLOAT: { float* graphicsbase; if (numverts) { btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts); btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr; memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices); for (int i=0;i<numverts;i++) { graphicsbase = (float*)(vertexbase+i*stride); tmpVertices[i].m_floats[0] = graphicsbase[0]; tmpVertices[i].m_floats[1] = graphicsbase[1]; tmpVertices[i].m_floats[2] = graphicsbase[2]; } serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); } break; } case PHY_DOUBLE: { if (numverts) { btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts); btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr; memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices); for (int i=0;i<numverts;i++) { double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double tmpVertices[i].m_floats[0] = graphicsbase[0]; tmpVertices[i].m_floats[1] = graphicsbase[1]; tmpVertices[i].m_floats[2] = graphicsbase[2]; } serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); } break; } default: btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); } unLockReadOnlyVertexBase(part); } serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr); } m_scaling.serializeFloat(trimeshData->m_scaling); return "btStridingMeshInterfaceData"; }
/*! SLAssimpImporter::loadAnimation loads the scene graph node tree recursively. */ SLAnimation* SLAssimpImporter::loadAnimation(aiAnimation* anim) { int animCount = 0; if (_skeleton) animCount = _skeleton->numAnimations(); ostringstream oss; oss << "unnamed_anim_" << animCount; SLstring animName = oss.str(); SLfloat animTicksPerSec = (anim->mTicksPerSecond == 0) ? 30.0f : (SLfloat)anim->mTicksPerSecond; SLfloat animDuration = (SLfloat)anim->mDuration / animTicksPerSec; if (anim->mName.length > 0) animName = anim->mName.C_Str(); // log logMessage(LV_minimal, "\nLoading animation %s\n", animName.c_str()); logMessage(LV_normal, " Duration(seconds): %f \n", animDuration); logMessage(LV_normal, " Duration(ticks): %f \n", anim->mDuration); logMessage(LV_normal, " Ticks per second: %f \n", animTicksPerSec); logMessage(LV_normal, " Num channels: %d\n", anim->mNumChannels); // exit if we didn't load a skeleton but have animations for one if (_skinnedMeshes.size() > 0) assert(_skeleton != nullptr && "The skeleton wasn't impoted correctly."); // create the animation SLAnimation* result; if (_skeleton) result = _skeleton->createAnimation(animName, animDuration); else { result = SLScene::current->animManager().createNodeAnimation(animName, animDuration); _nodeAnimations.push_back(result); } SLbool isSkeletonAnim = false; for (SLuint i = 0; i < anim->mNumChannels; i++) { aiNodeAnim* channel = anim->mChannels[i]; // find the node that is animated by this channel SLstring nodeName = channel->mNodeName.C_Str(); SLNode* affectedNode = _sceneRoot->find<SLNode>(nodeName); SLuint id = 0; SLbool isJointNode = (affectedNode == nullptr); // @todo: this is currently a work around but it can happen that we receive normal node animationtracks and joint animationtracks // we don't allow node animation tracks in a skeleton animation, so we should split an animation in two seperate // animations if this happens. for now we just ignore node animation tracks if we already have joint tracks // ofc this will crash if the first track is a node anim but its just temporary if (!isJointNode && isSkeletonAnim) continue; // is there a skeleton and is this animation channel not affecting a normal node? if (_skeletonRoot && !affectedNode) { isSkeletonAnim = true; SLJoint* affectedJoint = _skeleton->getJoint(nodeName); if (affectedJoint == nullptr) break; id = affectedJoint->id(); // @todo warn if we find an animation with some node channels and some joint channels // this shouldn't happen! /// @todo [high priority!] Address the problem of some bones not containing an animation channel /// when importing. Current workaround is to set their reset position to their bind pose. /// This will however fail if we have multiple animations affecting a single model and fading /// some of them out or in. This will require us to provide animations that have a channel /// for all bones even if they're just positional. // What does this next line do? // // The testimportfile we used (Astroboy.dae) has the following properties: // > It has joints in the skeleton that aren't animated by any channel. // > The joints need a reset position of (0, 0, 0) to work properly // because the joint position is contained in a single keyframe for every joint // // Since some of the joints don't have a channel that animates them, they also lack // the joint position that the other joints get from their animation channel. // So we need to set the initial state for all joints that have a channel // to identity. // All joints that arent in a channel will receive their local joint bind pose as // reset position. // // The problem stems from the design desicion to reset a whole skeleton before applying // animations to it. If we were to reset each joint just before applying a channel to it // we wouldn't have this problem. But we coulnd't blend animations as easily. // SLMat4f prevOM = affectedJoint->om(); affectedJoint->om(SLMat4f()); affectedJoint->setInitialState(); affectedJoint->om(prevOM); } // log logMessage(LV_normal, "\n Channel %d %s", i, (isJointNode) ? "(joint animation)\n" : "\n"); logMessage(LV_normal, " Affected node: %s\n", channel->mNodeName.C_Str()); logMessage(LV_detailed, " Num position keys: %d\n", channel->mNumPositionKeys); logMessage(LV_detailed, " Num rotation keys: %d\n", channel->mNumRotationKeys); logMessage(LV_detailed, " Num scaling keys: %d\n", channel->mNumScalingKeys); // joint animation channels should receive the correct node id, normal node animations just get 0 SLNodeAnimTrack* track = result->createNodeAnimationTrack(id); // this is a node animation only, so we add a reference to the affected node to the track if (affectedNode && !isSkeletonAnim) { track->animatedNode(affectedNode); } KeyframeMap keyframes; // add position keys for (SLuint i = 0; i < channel->mNumPositionKeys; i++) { SLfloat time = (SLfloat)channel->mPositionKeys[i].mTime; keyframes[time] = SLImportKeyframe(&channel->mPositionKeys[i], nullptr, nullptr); } // add rotation keys for (SLuint i = 0; i < channel->mNumRotationKeys; i++) { SLfloat time = (SLfloat)channel->mRotationKeys[i].mTime; if (keyframes.find(time) == keyframes.end()) keyframes[time] = SLImportKeyframe(nullptr, &channel->mRotationKeys[i], nullptr); else { // @todo this shouldn't abort but just throw an exception assert(keyframes[time].rotation == nullptr && "There were two rotation keys assigned to the same timestamp."); keyframes[time].rotation = &channel->mRotationKeys[i]; } } // add scaleing keys for (SLuint i = 0; i < channel->mNumScalingKeys; i++) { SLfloat time = (SLfloat)channel->mScalingKeys[i].mTime; if (keyframes.find(time) == keyframes.end()) keyframes[time] = SLImportKeyframe(nullptr, nullptr, &channel->mScalingKeys[i]); else { // @todo this shouldn't abort but just throw an exception assert(keyframes[time].scaling == nullptr && "There were two scaling keys assigned to the same timestamp."); keyframes[time].scaling = &channel->mScalingKeys[i]; } } logMessage(LV_normal, " Found %d distinct keyframe timestamp(s).\n", keyframes.size()); for (auto it : keyframes) { SLTransformKeyframe* kf = track->createNodeKeyframe(it.first); kf->translation(getTranslation(it.first, keyframes)); kf->rotation(getRotation(it.first, keyframes)); kf->scale(getScaling(it.first, keyframes)); // log logMessage(LV_detailed, "\n Generating keyframe at time '%.2f'\n", it.first); logMessage(LV_detailed, " Translation: (%.2f, %.2f, %.2f) %s\n", kf->translation().x, kf->translation().y, kf->translation().z, (it.second.translation != nullptr) ? "imported" : "generated"); logMessage(LV_detailed, " Rotation: (%.2f, %.2f, %.2f, %.2f) %s\n", kf->rotation().x(), kf->rotation().y(), kf->rotation().z(), kf->rotation().w(), (it.second.rotation != nullptr) ? "imported" : "generated"); logMessage(LV_detailed, " Scale: (%.2f, %.2f, %.2f) %s\n", kf->scale().x, kf->scale().y, kf->scale().z, (it.second.scaling != nullptr) ? "imported" : "generated"); } } return result; }
void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const { (void)aabbMin; (void)aabbMax; int numtotalphysicsverts = 0; int part,graphicssubparts = getNumSubParts(); const unsigned char * vertexbase; const unsigned char * indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; int stride,numverts,numtriangles; int gfxindex; btVector3 triangle[3]; btScalar* graphicsbase; btVector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype for (part=0;part<graphicssubparts ;part++) { getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part); numtotalphysicsverts+=numtriangles*3; //upper bound switch (gfxindextype) { case PHY_INTEGER: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { int* tri_indices= (int*)(indexbase+gfxindex*indexstride); graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } case PHY_SHORT: { for (gfxindex=0;gfxindex<numtriangles;gfxindex++) { short int* tri_indices= (short int*)(indexbase+gfxindex*indexstride); graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride); triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride); triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride); triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ()); callback->internalProcessTriangleIndex(triangle,part,gfxindex); } break; } default: btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); } unLockReadOnlyVertexBase(part); } }