void SE_BipedController::finalTransformMatrix(int frameindex) { for(int i = 0; i < oneBipAnimation.size(); ++i) { //use local coordinate. SE_Matrix4f worldToModel = mOriginalModelToWorld.inverse(); SE_Matrix4f finalMatrix = worldToModel.mul(mAfterTransformMatrixToWorld[i]).mul(mBindposeMatrixInverse[i]).mul(mOriginalModelToWorld); AllFrameFinalTransformMatrix[frameindex].push_back(finalMatrix); } for(int i = 0; i < AllFrameFinalTransformMatrix[frameindex].size(); ++i) { float f[16]; SE_Matrix4f m = AllFrameFinalTransformMatrix[frameindex][i]; m.getColumnSequence(f); for(int j = 0; j < 16; ++j) { AllFrameFinalTransformToShader[frameindex].push_back(f[j]); } } }
SE_Vector3f SE_SimObject::localToWorld(const SE_Vector3f& v) { SE_Spatial* spatial = getSpatial(); SE_Matrix4f worldTransform = spatial->getWorldTransform(); SE_Vector4f v4(v, 1); v4 = worldTransform.mul(getLocalMatrix()).map(v4); return v4.xyz(); }
void SE_BipedController::createBoneBaseMatrixInverse() { mBindposeMatrixInverse.clear(); for(int i = 0; i < oneBipAnimation.size(); ++i) { SE_Matrix4f bp = oneBipAnimation[i]->bind_pose; mBindposeMatrixInverse.push_back(bp.inverse()); } }
void SE_BoneAnimation::onEnd() { if(!mSimObject) return; if(!mMesh) return; SE_Matrix4f m; m.identity(); mSimObject->setWorldMatrix(m); mSimObject->setUseWorldMatrix(false); mSimObject->setPrimitiveType(TRIANGLES); mMesh->clearVertexInfo(); }
SE_Matrix4f SE_BufferInput::readMatrix4f() { SE_Matrix4f m; for(int i = 0 ; i < 4 ; i++) { for(int j = 0 ; j < 4 ; j++) { m.set(i, j, readFloat()); } } return m; }
SE_Vector3f SE_SkinJointController::convert(int vertexIndex, int boneMatrixIndex, const SE_Vector3f& v) { BoneWeightVector bwv = mVertexBoneWeightInfo[vertexIndex]; BoneWeightVector::iterator it; SE_Vector4f result(0, 0, 0, 0); SE_Vector4f inputV(v.x, v.y, v.z, 1.0); for(it = bwv.begin() ; it != bwv.end() ; it++) { int boneIndex = it->boneIndex; float weight = it->weight; SE_Bone* bone = mBoneVector[boneIndex - 1]; /* SE_Matrix4f boneBaseMatrix = bone->getBaseMatrix(); SE_Matrix4f worldToBone; SE_Matrix4f boneToWorld; if(boneMatrixIndex == -1) { boneToWorld = bone->getBaseMatrix(); } else { boneToWorld = bone->getMatrix(boneMatrixIndex); } SE_Bone* parent = bone->getParent(); while(parent != NULL) { SE_Matrix4f parentBoneMatrix; if(boneMatrixIndex == -1) parentBoneMatrix = parent->getBaseMatrix(); else parentBoneMatrix = parent->getMatrix(boneMatrixIndex); boneToWorld = parentBoneMatrix.mul(boneToWorld); SE_Matrix4f parentBaseBoneMatrix = parent->getBaseMatrix(); boneBaseMatrix = parentBaseBoneMatrix.mul(boneBaseMatrix); parent = parent->getParent(); } SE_Matrix4f boneBaseMatrixInverse = boneBaseMatrix.inverse(); SE_Matrix4f m = boneToWorld.mul(boneBaseMatrixInverse); */ SE_Matrix4f boneBaseMatrixInverse = mBoneBaseMatrixInverse[boneIndex - 1]; SE_Matrix4f boneToWorld = mBoneToWorldMatrix[boneIndex - 1]; SE_Matrix4f m = boneToWorld.mul(boneBaseMatrixInverse); result = result + m.map(inputV) * weight; } return result.xyz(); }
void SE_SkinJointController::createBoneBaseMatrixInverse() { mBoneBaseMatrixInverse.resize(mBoneVector.size()); for(int i = 0 ; i < mBoneVector.size() ; i++) { SE_Bone* bone = mBoneVector[i]; SE_Matrix4f boneBaseMatrix = bone->getBaseMatrix(); SE_Bone* parent = bone->getParent(); while(parent) { SE_Matrix4f parentBaseMatrix = parent->getBaseMatrix(); boneBaseMatrix = parentBaseMatrix.mul(boneBaseMatrix); parent = parent->getParent(); } mBoneBaseMatrixInverse[i] = boneBaseMatrix.inverse(); } }
void SE_BoneAnimation::onRun() { if(!mSkinJointController) return; SE_Bone* bone = mSkinJointController->mBoneVector[0]; int num = bone->getMatrixNum(); setFrameNum(num); setTimePerFrame(getDuration() / num); mMesh = mSimObject->getMesh(); SE_Matrix4f m; m.identity(); mSimObject->setWorldMatrix(m); mSimObject->setUseWorldMatrix(true); mSimObject->setPrimitiveType(TRIANGLES_INDEX); mMesh->clearVertexInfo(); mSkinJointController->createBoneBaseMatrixInverse(); }
void SE_BufferOutput::writeMatrix4f(const SE_Matrix4f& m) { for(int i = 0 ; i < 4 ; i++) { for(int j = 0 ; j < 4 ; j++) writeFloat(m.get(i, j)); } }
void View::setPosition(float x, float y) { mX = x; mY = y; SE_Matrix3f identity3; identity3.identity(); SE_Matrix4f transform; transform.identity(); transform.set(identity3,SE_Vector3f(mX,mY,0)); setPrevMatrix(transform); //update updateWorldTransform(); updateBoundingVolume(); }
void SE_SkinJointController::createBoneToWorldMatrix(int boneMatrixIndex) { if(mBoneToWorldMatrix.size() == 0) mBoneToWorldMatrix.resize(mBoneVector.size()); for(int i = 0 ; i < mBoneVector.size() ; i++) { SE_Bone* bone = mBoneVector[i]; SE_Bone* parent = bone->getParent(); SE_Matrix4f boneToWorld = bone->getMatrix(boneMatrixIndex); while(parent) { SE_Matrix4f parentBoneToWorld = parent->getMatrix(boneMatrixIndex); boneToWorld = parentBoneToWorld.mul(boneToWorld); parent = parent->getParent(); } mBoneToWorldMatrix[i] = boneToWorld; } }
void SE_NewGeometry::updateWorldTransform() { SE_Spatial::updateWorldTransform(); SE_Matrix4f localM; localM.set(getLocalRotate().toMatrix3f(), getLocalScale(), getLocalTranslate()); mWorldTransform = getPrevMatrix().mul(localM).mul(getPostMatrix()); SE_NewGeometry::_Impl::SimObjectList::iterator it; for(it = mImpl->attachObject.begin() ; it != mImpl->attachObject.end() ; it++) { (*it)->doTransform(getWorldTransform()); } std::list<SE_Spatial*>::iterator itchild = mImplchild->children.begin(); for(; itchild != mImplchild->children.end() ; itchild++) { SE_Spatial* s = *itchild; s->updateWorldTransform(); } }
void SE_Camera::rotateLocal(const SE_Quat& rotate) { SE_Vector3f localxAxis(1, 0, 0); SE_Vector3f localyAxis(0, 1, 0); SE_Vector3f localzAxis(0, 0, 1); localxAxis = rotate.map(localxAxis); localyAxis = rotate.map(localyAxis); //localzAxis = rotate.map(zAxis); SE_Matrix4f vtom = getViewToWorldMatrix(); SE_Vector4f worldxAxis = vtom.map(SE_Vector4f(localxAxis, 0)); SE_Vector4f worldyAxis = vtom.map(SE_Vector4f(localyAxis, 0)); //SE_Vector4f worldzAxis = vtom.map(SE_Vector4f(localzAxis, 0)); SE_Vector4f worldzAxis(worldxAxis.xyz().cross(worldyAxis.xyz()), 0); mAxisX = worldxAxis.normalize().xyz(); mAxisY = worldyAxis.normalize().xyz(); mAxisZ = worldzAxis.normalize().xyz(); mChanged = true; }
void SE_BipedController::fillBoneToWorldPerFrame() { int maxFrameIndex = findMaxFrameIndex(); for(int i = 0; i < oneBipAnimation.size(); ++i) { //get bip one by one SE_Biped *bip = oneBipAnimation[i]; //fill bonetoworld for every frame for(int j = 0; j < maxFrameIndex + 1; ++j) { if(bip->parent) { SE_Matrix4f * m = new SE_Matrix4f(); SE_Matrix4f myTrans; if(bip->animationInfo.size() > 0) { //FIXME: the parent Allways has keyframe when child has keyframe myTrans.set(bip->animationInfo[j]->rotateQ.toMatrix3f(),SE_Vector3f(1,1,1),bip->animationInfo[j]->translate); *m = bip->parent->boneToWorldPerFrame[j]->mul(myTrans); } else { //this bip on this frame has no key. *m = bip->bind_pose; } bip->boneToWorldPerFrame.push_back(m); } else { //this bip is ROOT SE_Matrix4f * m = new SE_Matrix4f(); *m = bip->bind_pose; bip->boneToWorldPerFrame.push_back(m); } } } }
SE_Spatial* SE_ElementManager::createSpatial() { if(!mRoot) return NULL; SE_Spatial* spatial = mRoot->createSpatial(NULL); spatial->setLocalTranslate(SE_Vector3f(0, 0, 0)); spatial->setLocalScale(SE_Vector3f(1, 1, 1)); SE_Vector4f c1(1, 0, 0, 0); SE_Vector4f c2(0, -1, 0, 0); SE_Vector4f c3(0, 0, 1, 0); SE_Vector4f c4(-mRoot->getWidth() / 2, mRoot->getHeight() / 2, 0, 1); SE_Matrix4f localM; localM.setColumn(0, c1); localM.setColumn(1, c2); localM.setColumn(2, c3); localM.setColumn(3, c4); spatial->setPostMatrix(localM); return spatial; }
void SE_BoneAnimation::onUpdate(SE_TimeMS realDelta, SE_TimeMS simulateDelta, float percent, int frameIndex) { if(getCurrentFrame() == frameIndex) return; if(!mSkinJointController) return; if(!mMesh) return; int surfaceNum = mMesh->getSurfaceNum(); for(int i = 0 ; i < surfaceNum ; i++) { SE_Surface* surface = mMesh->getSurface(i); _Vector3f* vertex = NULL; int vertexNum = 0; int* vertexIndex = NULL; int vertexIndexNum = 0; surface->getVertex(vertex, vertexNum); if(!mVertex) { mVertexNum = vertexNum; mVertex = new _Vector3f[vertexNum]; memcpy(mVertex, vertex, sizeof(_Vector3f) * vertexNum); } surface->getVertexIndexInGeometryData(vertexIndex, vertexIndexNum); if(vertex) { mSkinJointController->createBoneToWorldMatrix(frameIndex); for(int j = 0 ; j < vertexNum ; j++) { SE_Vector3f v(mVertex[j].d[0], mVertex[j].d[1], mVertex[j].d[2]); SE_Spatial* spatial = mSimObject->getSpatial(); SE_Matrix4f worldTM = spatial->getWorldTransform(); SE_Vector4f v4(v.x, v.y, v.z, 1.0); v4 = worldTM.map(v4); v = v4.xyz(); v = mSkinJointController->convert(vertexIndex[j], frameIndex, v4.xyz()); vertex[j].d[0] = v.x; vertex[j].d[1] = v.y; vertex[j].d[2] = v.z; } } } }
void SE_BipedController::createBoneToWorldMatrix(int frameindex) { //per frame refresh; mAfterTransformMatrixToWorld.clear(); for(int i = 0; i < oneBipAnimation.size(); ++i) { SE_Biped * bip = oneBipAnimation[i]; SE_Matrix4f transform; if(bip->animationInfo.size() == 0) { transform.identity(); } else { SE_Quat worldR = bip->animationInfo[frameindex]->rotateQ; SE_Vector3f worldT = bip->animationInfo[frameindex]->translate; SE_Vector3f worldS = bip->animationInfo[frameindex]->scale; //not use scale transform.set(worldR.toMatrix3f(),SE_Vector3f(1,1,1),worldT);//myTransform relate parent } SE_Matrix4f parentBoneToWorld; parentBoneToWorld.identity(); if(bip->parent) { parentBoneToWorld = *(bip->parent->boneToWorldPerFrame[frameindex]); } else { //this bip is ROOT,the transform is world relative; } SE_Matrix4f tranToWorld = parentBoneToWorld.mul(transform); mAfterTransformMatrixToWorld.push_back(tranToWorld); } }
void SE_GeometryData::transform(SE_GeometryData* src, const SE_Matrix4f& m, SE_GeometryData* dst) { SE_Vector3f* vertex = NULL; SE_Vector3i* faces = NULL; SE_Vector3f* facenormal = NULL; SE_Vector3f* facevertexnormal = NULL; int vertexNum = 0; int faceNum = 0; int facenormalNum = 0; int facevertexnormalNum = 0; if(src->vertexArray) { vertex = new SE_Vector3f[src->vertexNum]; for(int i = 0 ; i < src->vertexNum ; i++) { SE_Vector4f v(src->vertexArray[i], 1.0f); v = m.map(v); vertex[i] = v.xyz(); } vertexNum = src->vertexNum; } /* if(src->faceArray) { faces = new SE_Vector3i[src->faceNum]; for(int i = 0 ; i < src->faceNum; i++) { faces[i] = src->faceArray[i]; } faceNum = src->faceNum; } */ if(src->faceNormalArray) { /* //SE_Matrix3f t = m.toMatrix3f(); //if(t.hasInverse()) //{ SE_Matrix4f inverse = m.inverse(); inverse = inverse.transpose(); facenormal = new SE_Vector3f[src->faceNormalNum]; for(int i = 0 ; i < src->faceNormalNum ; i++) { facenormal[i] = (inverse.map(SE_Vector4f(src->faceNormalArray[i],0))).xyz(); LOGI("facevertexnormal[%d].x = %f\n",i,facenormal[i].x); LOGI("facevertexnormal[%d].y = %f\n",i,facenormal[i].y); LOGI("facevertexnormal[%d].z = %f\n",i,facenormal[i].z); } facenormalNum = src->faceNormalNum; //} */ } if(src->faceVertexNormalArray) { /* SE_Matrix3f t = m.toMatrix3f(); if(t.hasInverse()) { SE_Matrix3f inverse = t.inverse(); inverse = inverse.transpose(); facevertexnormal = new SE_Vector3f[src->faceVertexNormalNum]; for(int i = 0 ; i < src->faceVertexNormalNum ; i++) { facevertexnormal[i] = inverse.map(src->faceVertexNormalArray[i]); LOGI("facevertexnormal[%d].x = %f\n",i,facevertexnormal[i].x); LOGI("facevertexnormal[%d].y = %f\n",i,facevertexnormal[i].y); LOGI("facevertexnormal[%d].z = %f\n",i,facevertexnormal[i].z); } facevertexnormalNum = src->faceVertexNormalNum; } */ } dst->setVertexArray(vertex, vertexNum); dst->setFaceArray(src->faceArray, src->faceNum, false); dst->setFaceNormalArray(facenormal, facenormalNum); dst->setFaceVertexNormalArray(facevertexnormal,facevertexnormalNum); }
void SE_BipedController::fillFrame() { int maxFrame = findMaxFrameIndex(); std::vector<SE_BipedKeyFrame*> fullFrame; //fullFrame.resize(maxFrame,NULL); for(int i = 0; i < oneBipAnimation.size(); ++i) { //get bip one by one SE_Biped *bip = oneBipAnimation[i]; if(bip->animationInfo.size() == 0) { continue;//this bip has no keyframe } //generate 0 frame, bind_pos relative parent SE_Matrix4f bindposT; if(bip->parent) { bindposT = (bip->parent->bind_pose.inverse()).mul(bip->bind_pose); } else { //this bip is ROOT bindposT = bip->bind_pose; } SE_Quat rotate = bindposT.toMatrix3f().toQuat();//no rotate rotate = rotate.inverse(); SE_Vector3f translate = bindposT.getTranslate(); SE_Vector3f scale(1,1,1); //scale no use SE_BipedKeyFrame *zeroFrame = new SE_BipedKeyFrame(); zeroFrame->frameIndex = 0; zeroFrame->rotateQ = rotate; zeroFrame->scale = scale; zeroFrame->translate = translate; //push first (0) frame to target fullFrame.push_back(zeroFrame); std::vector<SE_BipedKeyFrame*>::iterator it_s = bip->animationInfo.begin(); std::vector<SE_BipedKeyFrame*>::iterator it_t = fullFrame.end(); -- it_t; SE_BipedKeyFrame* node_s = NULL; SE_BipedKeyFrame* node_t = NULL; while(it_s != bip->animationInfo.end()) { node_s = *it_s; node_t = *it_t; if(needInterpolation(node_t->frameIndex,node_s->frameIndex)) { //interpolation interpolation(it_s,it_t,fullFrame); } else if(node_s->frameIndex == node_t->frameIndex)//current source frame index == target frame index { //goto next frame ++it_s; } else //source frame index - target frame index == 1 { //push source frame to target frame vector SE_BipedKeyFrame *nextFrame = new SE_BipedKeyFrame(); //current source node is just next frame nextFrame->frameIndex = node_s->frameIndex; nextFrame->rotateQ = node_s->rotateQ; nextFrame->translate = node_s->translate; nextFrame->scale = node_s->scale; fullFrame.push_back(nextFrame); it_t = fullFrame.end(); --it_t; } } //total frame little than maxFrame? //1.yes fill last frame to vector int lastframe = bip->animationInfo.size() - 1; int lastframeIndex = bip->animationInfo[lastframe]->frameIndex; if(lastframeIndex < maxFrame) { SE_BipedKeyFrame * lastframenode = bip->animationInfo[lastframe]; for(int needfill = 0; needfill < maxFrame - lastframeIndex; ++needfill) { SE_BipedKeyFrame *fillFrame = new SE_BipedKeyFrame(); //next (maxFrame - lastframeIndex) frames are same fillFrame->frameIndex = lastframenode->frameIndex + needfill + 1; fillFrame->rotateQ = lastframenode->rotateQ; fillFrame->translate = lastframenode->translate; fillFrame->scale = lastframenode->scale; fullFrame.push_back(fillFrame); } } //2.no,finish this biped,copy target to source,clear target for(it_s = bip->animationInfo.begin(); it_s != bip->animationInfo.end(); ++it_s) { if(*it_s != NULL) { delete *it_s; } } bip->animationInfo.clear(); bip->animationInfo.resize(fullFrame.size()); //copy target to source std::copy(fullFrame.begin(),fullFrame.end(),bip->animationInfo.begin()); //clear fullFrame vector fullFrame.clear(); } }
SE_Vector3f SE_BipedController::convert(int vertexIndex,int frameindex,const char * objname, const SE_Vector3f& v) { SE_Vector4f input; input.set(v,1); SE_Vector4f result(0,0,0,0); SE_SkeletonUnit *su = findSU(objname); //bipedIndex.size is number that how many bips effact this vertext. int bipNumPerVertex = su->objVertexBlendInfo[vertexIndex]->bipedIndex.size(); //how many bips will take effact to one vertex for(int i = 0; i < bipNumPerVertex; ++i) { int bipIndex = su->objVertexBlendInfo[vertexIndex]->bipedIndex[i];//bipIndex is start from 1, not 0. int bipindexfromcache = su->bipCache[bipIndex-1]->bipIndexOnBipAnimation; SE_Biped *bip = oneBipAnimation[bipindexfromcache];// find bip from all bips if(bip->animationInfo.size() == 0) { continue; } #ifdef _FORDEBUG SE_Matrix4f bindpos = bip->bind_pose; SE_Matrix4f inversOfbp = bindpos.inverse(); SE_Quat worldR = bip->animationInfo[frameindex]->rotateQ; SE_Vector3f worldT = bip->animationInfo[frameindex]->translate; SE_Vector3f worldS = bip->animationInfo[frameindex]->scale; SE_Matrix4f transform; transform.identity(); //not use scale transform.set(worldR.toMatrix3f(),SE_Vector3f(1,1,1),worldT);//myTransform relate parent SE_Matrix4f parentBoneToWorld; parentBoneToWorld.identity(); if(bip->parent) { parentBoneToWorld = *(bip->parent->boneToWorldPerFrame[frameindex]); } else { //this bip is ROOT,the transform is world relative; } SE_Matrix4f m = parentBoneToWorld.mul(transform).mul(inversOfbp); SE_Matrix4f m = mAfterTransformMatrixToWorld[bipindexfromcache].mul(mBindposeMatrixInverse[bipindexfromcache]); #else SE_Matrix4f m = AllFrameFinalTransformMatrix[frameindex][bipindexfromcache]; #endif result = result + m.map(input) * su->objVertexBlendInfo[vertexIndex]->weight[i]; } return result.xyz(); }
SE_Matrix4f SE_Camera::getWorldToViewMatrix() const { SE_Matrix4f vtow = getViewToWorldMatrix(); return vtow.inverse(); }
void SE_Camera::getFrustumPlanes(SE_Plane planes[6]) const { if(!mChanged) { for(int i = 0 ; i < 6 ; i++) { planes[i] = mPlanes[i]; } return; } SE_Plane lplanes[6]; lplanes[0] = mFrustum.getLeftPlane(); lplanes[1] = mFrustum.getRightPlane(); lplanes[2] = mFrustum.getTopPlane(); lplanes[3] = mFrustum.getBottomPlane(); lplanes[4] = mFrustum.getNearPlane(); lplanes[5] = mFrustum.getFarPlane(); SE_Matrix4f vtom = getViewToWorldMatrix(); vtom = vtom.inverse(); vtom = vtom.transpose(); for(int i = 0 ; i < 6 ; i++) { SE_Plane p = lplanes[i].transform(vtom); planes[i].set(p.getNormal().neg(), p.getDistance()); mPlanes[i] = planes[i]; } #ifdef DEBUG /* SE_Plane nplanes[6]; SE_Vector3f NearLeftBottom, NearLeftTop, NearRightBottom, NearRightTop, FarLeftBottom, FarLeftTop, FarRightBottom, FarRightTop; SE_Vector3f tmp1; SE_Vector3f tmp[4]; SE_Rect<float> nearplane = mFrustum.getNearPlaneRect(); tmp[0] = mAxisZ.mul(-mFrustum.getNear()); tmp[1] = mAxisX.mul(nearplane.left); tmp[2] = mAxisY.mul(nearplane.bottom); tmp[3] = mLocation; NearLeftBottom = tmp[0] + tmp[1] + tmp[2] + tmp[3]; tmp1 = tmp[0] + tmp[1] + tmp[2]; tmp1 = tmp1.mul(mFrustum.getFar() / mFrustum.getNear()); FarLeftBottom = mLocation + tmp1; tmp[1] = mAxisX.mul(nearplane.left); tmp[2] = mAxisY.mul(nearplane.top); NearLeftTop = tmp[0] + tmp[1] + tmp[2] + tmp[3]; tmp1 = tmp[0] + tmp[1] + tmp[2]; tmp1 = tmp1.mul(mFrustum.getFar() / mFrustum.getNear()); FarLeftTop = mLocation + tmp1; tmp[1] = mAxisX.mul(nearplane.right); tmp[2] = mAxisY.mul(nearplane.bottom); NearRightBottom = tmp[0] + tmp[1] + tmp[2] + tmp[3]; tmp1 = tmp[0] + tmp[1] + tmp[2]; tmp1 = tmp1.mul(mFrustum.getFar() / mFrustum.getNear()); FarRightBottom = mLocation + tmp1; tmp[1] = mAxisX.mul(nearplane.right); tmp[2] = mAxisY.mul(nearplane.top); NearRightTop = tmp[0] + tmp[1] + tmp[2] + tmp[3]; tmp1 = tmp[0] + tmp[1] + tmp[2]; tmp1 = tmp1.mul(mFrustum.getFar() / mFrustum.getNear()); FarRightTop = mLocation + tmp1; nplanes[0].set(NearLeftBottom, mLocation, NearLeftTop); nplanes[1].set(NearRightTop, mLocation, NearRightBottom); nplanes[2].set(mLocation, NearLeftBottom, NearRightBottom); nplanes[3].set(mLocation, NearRightTop, NearLeftTop); nplanes[4].set(NearLeftBottom, NearRightBottom, NearRightTop); nplanes[5].set(FarLeftBottom, FarLeftTop, FarRightTop); for(int i = 0 ; i < 6 ; i++) { planes[i] = nplanes[i]; } */ #endif }