void RigidBody::SetPosition(Vector3 position) { if (body_) { btTransform& worldTrans = body_->getWorldTransform(); worldTrans.setOrigin(ToBtVector3(position + ToQuaternion(worldTrans.getRotation()) * centerOfMass_)); // When forcing the physics position, set also interpolated position so that there is no jitter btTransform interpTrans = body_->getInterpolationWorldTransform(); interpTrans.setOrigin(worldTrans.getOrigin()); body_->setInterpolationWorldTransform(interpTrans); Activate(); MarkNetworkUpdate(); } }
void Node::Load(const pugi::xml_node& node) { CHECK_ASSERT(name_ == node.attribute("name").as_string()); Vertex3 position(VECTOR3_ZERO); auto posAtt = node.attribute("position"); if (posAtt) position = ToVertex3(posAtt.as_string()); SetPosition(position); Quaternion orientation(QUATERNION_IDENTITY); auto rotAtt = node.attribute("orientation"); if (rotAtt) orientation = ToQuaternion(rotAtt.as_string()); SetOrientation(orientation); Vertex3 scale(VECTOR3_ONE); auto scaAtt = node.attribute("scale"); if (scaAtt) scale = ToVertex3(scaAtt.as_string()); SetScale(scale); }
Animations AssimpModelImporter::ImportAnimations() const { Animations animations; if (scene->HasAnimations()) { for(U32 i = 0; i < scene->mNumAnimations; ++i) { aiAnimation* animation = scene->mAnimations[i]; string animationName = animation->mName.C_Str(); vector<AnimationChannel>& channels = animations[animationName]; if (animationName.empty()) { throw Exception("AssimpImporter: Undefined animation name."); } for(U32 j = 0; j < animation->mNumChannels; ++j) { aiNodeAnim* nodeAnim = animation->mChannels[j]; string channelName = nodeAnim->mNodeName.C_Str(); AnimationChannel channel(channelName); for(U32 p = 0; p < nodeAnim->mNumPositionKeys; ++p) { aiVectorKey key = nodeAnim->mPositionKeys[p]; channel.keys[(U32) key.mTime].position = ToVector3f(key.mValue); } for(U32 s = 0; s < nodeAnim->mNumScalingKeys; ++s) { aiVectorKey key = nodeAnim->mScalingKeys[s]; channel.keys[(U32) key.mTime].scale = ToVector3f(key.mValue); } for(U32 r = 0; r < nodeAnim->mNumRotationKeys; ++r) { aiQuatKey key = nodeAnim->mRotationKeys[r]; channel.keys[(U32) key.mTime].rotation = ToQuaternion(key.mValue); } channels.push_back(channel); } } } return animations; }
void RigidBody::SetPosition(const Vector3& position) { if (body_) { btTransform& worldTrans = body_->getWorldTransform(); worldTrans.setOrigin(ToBtVector3(position + ToQuaternion(worldTrans.getRotation()) * centerOfMass_)); // When forcing the physics position, set also interpolated position so that there is no jitter // When not inside the simulation loop, this may lead to erratic movement of parented rigidbodies // so skip in that case if (physicsWorld_->IsSimulating()) { btTransform interpTrans = body_->getInterpolationWorldTransform(); interpTrans.setOrigin(worldTrans.getOrigin()); body_->setInterpolationWorldTransform(interpTrans); } Activate(); MarkNetworkUpdate(); } }
void Camera::Load(const pugi::xml_node& node) { name_ = node.attribute("name").as_string(); Vertex3 position = ToVertex3(node.attribute("position").as_string()); SetPosition(position); fovy_ = node.attribute("fovy").as_float(); zNear_ = node.attribute("zNear").as_float(); zFar_ = node.attribute("zFar").as_float(); isOrtho_ = node.attribute("isOrtho").as_bool(); orthoScale_ = node.attribute("orthoScale").as_float(); sensorFit_ = (CameraSensorFit)node.attribute("sensorFit").as_int(); Quaternion orientation = ToQuaternion(node.attribute("orientation").as_string()); SetOrientation(orientation); LoadChildren(node); isDirty_ = true; SetUniformsNeedUpdate(); }
void RigidBody::SetPosition(const Vector3& position) { if (body_) { btTransform& worldTrans = body_->getWorldTransform(); worldTrans.setOrigin(ToBtVector3(position + ToQuaternion(worldTrans.getRotation()) * centerOfMass_)); // When forcing the physics position, set also interpolated position so that there is no jitter // When not inside the simulation loop, this may lead to erratic movement of parented rigidbodies // so skip in that case. Exception made before first simulation tick so that interpolation position // of e.g. instantiated prefabs will be correct from the start if (!hasSimulated_ || physicsWorld_->IsSimulating()) { btTransform interpTrans = body_->getInterpolationWorldTransform(); interpTrans.setOrigin(worldTrans.getOrigin()); body_->setInterpolationWorldTransform(interpTrans); } Activate(); MarkNetworkUpdate(); } }
Quaternion XMLElement::GetQuaternion(const ea::string& name) const { return ToQuaternion(GetAttribute(name)); }
Quaternion ToQuaternion(const String& source) { return ToQuaternion(source.CString()); }
void Variant::FromString(VariantType type, const char* value) { switch (type) { case VAR_INT: *this = ToInt(value); break; case VAR_INT64: *this = ToInt64(value); break; case VAR_BOOL: *this = ToBool(value); break; case VAR_FLOAT: *this = ToFloat(value); break; case VAR_VECTOR2: *this = ToVector2(value); break; case VAR_VECTOR3: *this = ToVector3(value); break; case VAR_VECTOR4: *this = ToVector4(value); break; case VAR_QUATERNION: *this = ToQuaternion(value); break; case VAR_COLOR: *this = ToColor(value); break; case VAR_STRING: *this = value; break; case VAR_BUFFER: { SetType(VAR_BUFFER); PODVector<unsigned char>& buffer = *(reinterpret_cast<PODVector<unsigned char>*>(&value_)); StringToBuffer(buffer, value); } break; case VAR_VOIDPTR: // From string to void pointer not supported, set to null *this = (void*)0; break; case VAR_RESOURCEREF: { StringVector values = String::Split(value, ';'); if (values.Size() == 2) { SetType(VAR_RESOURCEREF); ResourceRef& ref = *(reinterpret_cast<ResourceRef*>(&value_)); ref.type_ = values[0]; ref.name_ = values[1]; } } break; case VAR_RESOURCEREFLIST: { StringVector values = String::Split(value, ';', true); if (values.Size() >= 1) { SetType(VAR_RESOURCEREFLIST); ResourceRefList& refList = *(reinterpret_cast<ResourceRefList*>(&value_)); refList.type_ = values[0]; refList.names_.Resize(values.Size() - 1); for (unsigned i = 1; i < values.Size(); ++i) refList.names_[i - 1] = values[i]; } } break; case VAR_INTRECT: *this = ToIntRect(value); break; case VAR_INTVECTOR2: *this = ToIntVector2(value); break; case VAR_INTVECTOR3: *this = ToIntVector3(value); break; case VAR_PTR: // From string to RefCounted pointer not supported, set to null *this = (RefCounted*)0; break; case VAR_MATRIX3: *this = ToMatrix3(value); break; case VAR_MATRIX3X4: *this = ToMatrix3x4(value); break; case VAR_MATRIX4: *this = ToMatrix4(value); break; case VAR_DOUBLE: *this = ToDouble(value); break; case VAR_RECT: *this = ToRect(value); break; default: SetType(VAR_NONE); } }
void RigidBody::UpdateMass() { if (!body_ || !enableMassUpdate_) return; btTransform principal; principal.setRotation(btQuaternion::getIdentity()); principal.setOrigin(btVector3(0.0f, 0.0f, 0.0f)); // Calculate center of mass shift from all the collision shapes unsigned numShapes = (unsigned)compoundShape_->getNumChildShapes(); if (numShapes) { PODVector<float> masses(numShapes); for (unsigned i = 0; i < numShapes; ++i) { // The actual mass does not matter, divide evenly between child shapes masses[i] = 1.0f; } btVector3 inertia(0.0f, 0.0f, 0.0f); compoundShape_->calculatePrincipalAxisTransform(&masses[0], principal, inertia); } // Add child shapes to shifted compound shape with adjusted offset while (shiftedCompoundShape_->getNumChildShapes()) shiftedCompoundShape_->removeChildShapeByIndex(shiftedCompoundShape_->getNumChildShapes() - 1); for (unsigned i = 0; i < numShapes; ++i) { btTransform adjusted = compoundShape_->getChildTransform(i); adjusted.setOrigin(adjusted.getOrigin() - principal.getOrigin()); shiftedCompoundShape_->addChildShape(adjusted, compoundShape_->getChildShape(i)); } // If shifted compound shape has only one child with no offset/rotation, use the child shape // directly as the rigid body collision shape for better collision detection performance bool useCompound = !numShapes || numShapes > 1; if (!useCompound) { const btTransform& childTransform = shiftedCompoundShape_->getChildTransform(0); if (!ToVector3(childTransform.getOrigin()).Equals(Vector3::ZERO) || !ToQuaternion(childTransform.getRotation()).Equals(Quaternion::IDENTITY)) useCompound = true; } body_->setCollisionShape(useCompound ? shiftedCompoundShape_ : shiftedCompoundShape_->getChildShape(0)); // If we have one shape and this is a triangle mesh, we use a custom material callback in order to adjust internal edges if (!useCompound && body_->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE && physicsWorld_->GetInternalEdge()) body_->setCollisionFlags(body_->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); else body_->setCollisionFlags(body_->getCollisionFlags() & ~btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); // Reapply rigid body position with new center of mass shift Vector3 oldPosition = GetPosition(); centerOfMass_ = ToVector3(principal.getOrigin()); SetPosition(oldPosition); // Calculate final inertia btVector3 localInertia(0.0f, 0.0f, 0.0f); if (mass_ > 0.0f) shiftedCompoundShape_->calculateLocalInertia(mass_, localInertia); body_->setMassProps(mass_, localInertia); body_->updateInertiaTensor(); // Reapply constraint positions for new center of mass shift if (node_) { for (PODVector<Constraint*>::Iterator i = constraints_.Begin(); i != constraints_.End(); ++i) (*i)->ApplyFrames(); } }
Quaternion RigidBody::GetRotation() const { return body_ ? ToQuaternion(body_->getWorldTransform().getRotation()) : Quaternion::IDENTITY; }
void Variant::FromString(VariantType type, const char* value) { switch (type) { case VAR_INT: *this = ToInt(value); break; case VAR_BOOL: *this = ToBool(value); break; case VAR_FLOAT: *this = ToFloat(value); break; case VAR_VECTOR2: *this = ToVector2(value); break; case VAR_VECTOR3: *this = ToVector3(value); break; case VAR_VECTOR4: *this = ToVector4(value); break; case VAR_QUATERNION: *this = ToQuaternion(value); break; case VAR_COLOR: *this = ToColor(value); break; case VAR_STRING: *this = value; break; case VAR_BUFFER: { SetType(VAR_BUFFER); PODVector<unsigned char>& buffer = *(reinterpret_cast<PODVector<unsigned char>*>(&value_)); Vector<String> values = String::Split(value, ' '); buffer.Resize(values.Size()); for (unsigned i = 0; i < values.Size(); ++i) buffer[i] = ToInt(values[i]); } break; case VAR_PTR: *this = (void*)0; break; case VAR_RESOURCEREF: { Vector<String> values = String::Split(value, ';'); if (values.Size() == 2) { SetType(VAR_RESOURCEREF); ResourceRef& ref = *(reinterpret_cast<ResourceRef*>(&value_)); ref.type_ = ShortStringHash(values[0]); ref.id_ = StringHash(values[1]); } } break; case VAR_RESOURCEREFLIST: { Vector<String> values = String::Split(value, ';'); if (values.Size() >= 1) { SetType(VAR_RESOURCEREFLIST); ResourceRefList& refList = *(reinterpret_cast<ResourceRefList*>(&value_)); refList.type_ = ShortStringHash(values[0]); refList.ids_.Resize(values.Size() - 1); for (unsigned i = 1; i < values.Size(); ++i) refList.ids_[i - 1] = StringHash(values[i]); } } break; case VAR_INTRECT: *this = ToIntRect(value); break; case VAR_INTVECTOR2: *this = ToIntVector2(value); break; default: SetType(VAR_NONE); } }
Mat3Ref Matrix3::Orthonormalize(void) { //return Quat().SetFromMatrix(*this).Normalize().ToMatrix(*this); return ToMatrix3(ToQuaternion(*this).Normalized()); }
Quaternion JSONValue::GetQuaternion(unsigned index) const { return ToQuaternion(GetCString(index)); }
Quaternion JSONValue::GetQuaternion(const String& name) const { return ToQuaternion(GetCString(name)); }