bool GenmeshAsset::SetSocketTransform(const char* socketName, const SocketDescriptor& desc) { iSkeletonSocket* sock = skeleton->FindSocket (socketName); if (!sock) return false; sock->GetFactory()->SetName(desc.find("Name")->second.second.c_str()); iSkeletonBone* bone = skeleton->FindBone(desc.find("Bone")->second.second.c_str()); if (bone) sock->SetBone(bone); csVector3 offset; if (sscanf(desc.find("Offset")->second.second.c_str(), "%f, %f, %f", &offset[0], &offset[1], &offset[2]) != 3) return false; csReversibleTransform trans = sock->GetTransform(); trans.SetOrigin(offset); sock->SetTransform(trans); csVector3 rot; if (sscanf(desc.find("Rotation")->second.second.c_str(), "%f, %f, %f", &rot[0], &rot[1], &rot[2]) != 3) return false; csReversibleTransform transr = sock->GetTransform(); csMatrix3 m; m *= csXRotMatrix3 (rot.x); m *= csYRotMatrix3 (rot.y); m *= csZRotMatrix3 (rot.z); transr.SetO2T(m); sock->SetTransform(transr); return true; }
void psCharAppearance::ProcessAttach(csRef<iMeshWrapper> meshWrap, csRef<iSpriteCal3DSocket> socket) { if(!socket.IsValid()) return; CS_ASSERT(socket.IsValid()); meshWrap->GetFlags().Set(CS_ENTITY_NODECAL); const char* socketName = socket->GetName(); // Given a socket name of "righthand", we're looking for a key in the form of "socket_righthand" csString keyName = "socket_"; keyName += socketName; // Variables for transform to be specified float trans_x = 0, trans_y = 0.0, trans_z = 0, rot_x = -PI/2, rot_y = 0, rot_z = 0; csRef<iObjectIterator> it = meshWrap->GetFactory()->QueryObject()->GetIterator(); while ( it->HasNext() ) { csRef<iKeyValuePair> key ( scfQueryInterface<iKeyValuePair> (it->Next())); if (key && keyName == key->GetKey()) { sscanf(key->GetValue(),"%f,%f,%f,%f,%f,%f",&trans_x,&trans_y,&trans_z,&rot_x,&rot_y,&rot_z); } } meshWrap->QuerySceneNode()->SetParent( baseMesh->QuerySceneNode ()); socket->SetMeshWrapper( meshWrap ); socket->SetTransform( csTransform(csZRotMatrix3(rot_z)*csYRotMatrix3(rot_y)*csXRotMatrix3(rot_x), csVector3(trans_x,trans_y,trans_z)) ); usedSlots.PushSmart(socketName); }
csReversibleTransform WalkTestLights::FlashlightShift (const csReversibleTransform& tf) { csReversibleTransform newTF (tf); // Tilt flashlight a bit down csMatrix3 newmat (tf.GetT2O()); newmat *= csXRotMatrix3 (float ((10.0/180.0)*PI)); newTF.SetT2O (newmat); return newTF; }
void Simple::Frame () { // First get elapsed time from the virtual clock. csTicks elapsed_time = vc->GetElapsedTicks (); // Now rotate the camera according to keyboard state float speed = (elapsed_time / 1000.0) * (0.06 * 20); iCamera* c = view->GetCamera(); if (kbd->GetKeyState (CSKEY_SHIFT)) { // If the user is holding down shift, the arrow keys will cause // the camera to strafe up, down, left or right from it's // current position. if (kbd->GetKeyState (CSKEY_RIGHT)) c->Move (CS_VEC_RIGHT * 4 * speed); if (kbd->GetKeyState (CSKEY_LEFT)) c->Move (CS_VEC_LEFT * 4 * speed); if (kbd->GetKeyState (CSKEY_UP)) c->Move (CS_VEC_UP * 4 * speed); if (kbd->GetKeyState (CSKEY_DOWN)) c->Move (CS_VEC_DOWN * 4 * speed); } else { // left and right cause the camera to rotate on the global Y // axis; page up and page down cause the camera to rotate on the // _camera's_ X axis (more on this in a second) and up and down // arrows cause the camera to go forwards and backwards. if (kbd->GetKeyState (CSKEY_RIGHT)) rotY += speed; if (kbd->GetKeyState (CSKEY_LEFT)) rotY -= speed; if (kbd->GetKeyState (CSKEY_PGUP)) rotX += speed; if (kbd->GetKeyState (CSKEY_PGDN)) rotX -= speed; if (kbd->GetKeyState (CSKEY_UP)) c->Move (CS_VEC_FORWARD * 4 * speed); if (kbd->GetKeyState (CSKEY_DOWN)) c->Move (CS_VEC_BACKWARD * 4 * speed); } // We now assign a new rotation transformation to the camera. You // can think of the rotation this way: starting from the zero // position, you first rotate "rotY" radians on your Y axis to get // the first rotation. From there you rotate "rotX" radians on the // your X axis to get the final rotation. We multiply the // individual rotations on each axis together to get a single // rotation matrix. The rotations are applied in right to left // order . csMatrix3 rot = csXRotMatrix3 (rotX) * csYRotMatrix3 (rotY); csOrthoTransform ot (rot, c->GetTransform().GetOrigin ()); c->SetTransform (ot); rm->RenderView (view); }
bool AnimeshAsset::SetSocketTransform(const char* socketName, const SocketDescriptor& desc) { uint sockf = animeshsprite->FindSocket(socketName); if (sockf == (uint)~0) return false; CS::Mesh::iAnimatedMeshSocket* sock = animeshstate->GetSocket(sockf); if (!sock) return false; sock->GetFactory()->SetName(desc.find("Name")->second.second.c_str()); int bone; sscanf(desc.find("Bone")->second.second.c_str(), "%d", &bone); sock->GetFactory()->SetBone(bone); csVector3 offset; if (sscanf(desc.find("Offset")->second.second.c_str(), "%f, %f, %f", &offset[0], &offset[1], &offset[2]) != 3) return false; //csReversibleTransform trans = sock->GetFactory()->GetTransform(); csReversibleTransform trans = sock->GetTransform(); trans.SetOrigin(offset); //sock->GetFactory()->SetTransform(trans); sock->SetTransform(trans); csVector3 rot; if (sscanf(desc.find("Rotation")->second.second.c_str(), "%f, %f, %f", &rot[0], &rot[1], &rot[2]) != 3) return false; //csReversibleTransform transr = sock->GetFactory()->GetTransform(); csReversibleTransform transr = sock->GetTransform(); csMatrix3 m; m *= csXRotMatrix3 (rot.x); m *= csYRotMatrix3 (rot.y); m *= csZRotMatrix3 (rot.z); transr.SetO2T(m); //sock->GetFactory()->SetTransform(transr); sock->SetTransform(transr); return true; }
void psCharAppearance::ApplyRider(csRef<iMeshWrapper> mesh) { csRef<iSpriteCal3DState> mountstate = scfQueryInterface<iSpriteCal3DState> (mesh->GetMeshObject()); csRef<iSpriteCal3DSocket> socket = mountstate->FindSocket( "back" ); if ( !socket ) { Error1("Socket back not found."); return; } baseMesh->GetFlags().Set(CS_ENTITY_NODECAL); const char* socketName = socket->GetName(); // Given a socket name of "righthand", we're looking for a key in the form of "socket_righthand" csString keyName = "socket_"; keyName += socketName; // Variables for transform to be specified float trans_x = 0, trans_y = 0.0, trans_z = 0, rot_x = -PI/2, rot_y = 0, rot_z = 0; csRef<iObjectIterator> it = baseMesh->GetFactory()->QueryObject()->GetIterator(); while ( it->HasNext() ) { csRef<iKeyValuePair> key ( scfQueryInterface<iKeyValuePair> (it->Next())); if (key && keyName == key->GetKey()) { sscanf(key->GetValue(),"%f,%f,%f,%f,%f,%f",&trans_x,&trans_y,&trans_z,&rot_x,&rot_y,&rot_z); } } baseMesh->QuerySceneNode()->SetParent( mesh->QuerySceneNode ()); socket->SetMeshWrapper( baseMesh ); socket->SetTransform( csTransform(csZRotMatrix3(rot_z)*csYRotMatrix3(rot_y)*csXRotMatrix3(rot_x), csVector3(trans_x,trans_y,trans_z)) ); }
void psLinearMovement::HugGround (const csVector3& pos, iSector* sector) { csVector3 start, end; csIntersectingTriangle closest_tri; csVector3 isect[4]; csPlane3 plane; bool hit[4]; // Set minimum base dimensions of 0.5x0.5 for good aesthetics float legsXlimit = csMax(bottomSize.x / 2, 0.5f); float legsZlimit = csMax(bottomSize.z / 2, 0.5f); start.y = pos.y + shift.y + 0.01; // Assuming the bounding box is axis-aligned: (Lower-left point) start.x = pos.x - legsXlimit; start.z = pos.z - legsZlimit; end = start; end.y -= 5; hit[0] = csColliderHelper::TraceBeam (cdsys, sector, start, end, false, closest_tri, isect[0]) != -1; // Assuming the bounding box is axis-aligned: (Upper-left point) start.x = pos.x - legsXlimit; start.z = pos.z + legsZlimit; end = start; end.y -= 5; hit[1] = csColliderHelper::TraceBeam (cdsys, sector, start, end, false, closest_tri, isect[1]) != -1; // Assuming the bounding box is axis-aligned: (Upper-right point) start.x = pos.x + legsXlimit; start.z = pos.z + legsZlimit; end = start; end.y -= 5; hit[2] = csColliderHelper::TraceBeam (cdsys, sector, start, end, false, closest_tri, isect[2]) != -1; // Assuming the bounding box is axis-aligned: (Lower-right point) start.x = pos.x + legsXlimit; start.z = pos.z - legsZlimit; end = start; end.y -= 5; hit[3] = csColliderHelper::TraceBeam (cdsys, sector, start, end, false, closest_tri, isect[3]) != -1; //printf("Isect (%f %f %f %f)\n",hit[0] ? isect[0].y : -999, hit[1] ? isect[1].y : -999, hit[2] ? isect[2].y: -999, hit[3] ? isect[3].y: -999); int notHit = 0; int lowest = -1; for (int i = 0; i < 4 && notHit <= 1; i++) { if (!hit[i]) { notHit++; lowest = i; continue; } if(notHit == 0) { if(lowest == -1) lowest = i; else if (isect[lowest].y > isect[i].y) lowest = i; } } if (notHit <= 1) { switch (lowest) { case 0: plane.Set (isect[1], isect[2], isect[3]); break; case 1: plane.Set (isect[0], isect[2], isect[3]); break; case 2: plane.Set (isect[0], isect[1], isect[3]); break; case 3: plane.Set (isect[0], isect[1], isect[2]); break; } csVector3 normal = plane.GetNormal ().Unit (); float newxRot = atan2 (normal.z, normal.y ); float newzRot = -atan2 (normal.x, normal.y ); csMatrix3 rotMat = csZRotMatrix3 (newzRot) * csXRotMatrix3 (newxRot - xRot) * csZRotMatrix3 (-zRot); mesh->GetMovable ()->Transform (rotMat); xRot = newxRot; zRot = newzRot; } }
bool psEffectObj::Update(csTicks elapsed) { if (!anchor || !anchor->IsReady() || !anchorMesh->GetMovable()->GetSectors()->GetCount()) // wait for anchor to be ready return true; const static csMatrix3 UP_FIX(1,0,0, 0,0,1, 0,1,0); const static csMatrix3 billboardFix = csXRotMatrix3(-3.14f/2.0f); iMovable* anchorMovable = anchorMesh->GetMovable(); iMovable* meshMovable = mesh->GetMovable(); csVector3 anchorPosition = anchorMovable->GetFullPosition(); life += elapsed; if (life > animLength && killTime <= 0) { life %= animLength; if (!life) { life += animLength; } } isAlive |= (life >= birth); if (isAlive) { meshMovable->SetSector(anchorMovable->GetSectors()->Get(0)); meshMovable->SetPosition(anchorPosition); if (dir == DT_NONE) { matBase = anchorMovable->GetFullTransform().GetT2O(); } } csMatrix3 matTransform; if (keyFrames->GetSize() == 0) { if (dir == DT_CAMERA) { // note that this is *very* expensive csVector3 camDir = -view->GetCamera()->GetTransform().GetO2TTranslation() + anchorPosition; csReversibleTransform rt; rt.LookAt(camDir, csVector3(0.f,1.f,0.f)); matBase = rt.GetT2O() * UP_FIX; } else if (dir == DT_BILLBOARD) { matBase = view->GetCamera()->GetTransform().GetT2O() * billboardFix; } baseScale = scale; matTransform = matBase / baseScale; } else { currKeyFrame = FindKeyFrameByTime(life); nextKeyFrame = (currKeyFrame + 1) % keyFrames->GetSize(); // grab and lerp values - expensive float lerpfactor = LERP_FACTOR; csVector3 lerpRot = LERP_VEC_KEY(KA_ROT,lerpfactor); csVector3 lerpSpin = LERP_VEC_KEY(KA_SPIN,lerpfactor); csVector3 objOffset = LERP_VEC_KEY(KA_POS,lerpfactor); // calculate rotation from lerped values - expensive csMatrix3 matRot = csZRotMatrix3(lerpRot.z) * csYRotMatrix3(lerpRot.y) * csXRotMatrix3(lerpRot.x); if (dir != DT_CAMERA && dir != DT_BILLBOARD) { matRot *= matBase; } // calculate new position csVector3 newPos = matRot * csVector3(-objOffset.x, objOffset.y, -objOffset.z); if (dir == DT_CAMERA) { // note that this is *very* expensive - again csVector3 camDir = -view->GetCamera()->GetTransform().GetO2TTranslation() + anchorPosition + newPos; csReversibleTransform rt; rt.LookAt(camDir, csVector3(sinf(lerpSpin.y),cosf(lerpSpin.y),0.f)); matBase = rt.GetT2O() * UP_FIX; newPos = rt.GetT2O() * newPos; // rotate and spin should have no effect on the transform when we want it to face the camera matTransform = matBase; } else if (dir == DT_BILLBOARD) { matBase = view->GetCamera()->GetTransform().GetT2O() * billboardFix; matTransform = matBase; } else { matTransform = matRot; matTransform *= csZRotMatrix3(lerpSpin.z) * csYRotMatrix3(lerpSpin.y) * csXRotMatrix3(lerpSpin.x); } // SCALE baseScale = LERP_KEY(KA_SCALE,lerpfactor) * scale; matTransform /= baseScale; // adjust position meshMovable->SetPosition(anchorPosition+newPos); } // set new transform meshMovable->SetTransform(matTransform); meshMovable->UpdateMove(); if (killTime > 0) { killTime -= elapsed; if (killTime <= 0) return false; } return true; }