void RigidBody::UpdateMass() { if (!body_) 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 = 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(); } }
Vector3 RigidBody::GetLinearFactor() const { return body_ ? ToVector3(body_->getLinearFactor()) : Vector3::ZERO; }
Vector3 RigidBody::GetAngularVelocity() const { return body_ ? ToVector3(body_->getAngularVelocity()) : Vector3::ZERO; }
Vector3 RigidBody::GetAnisotropicFriction() const { return body_ ? ToVector3(body_->getAnisotropicFriction()) : Vector3::ZERO; }
void WriteVertex(float*& dest, aiMesh* mesh, unsigned index, unsigned elementMask, BoundingBox& box, const Matrix3x4& vertexTransform, const Matrix3& normalTransform, Vector<PODVector<unsigned char> >& blendIndices, Vector<PODVector<float> >& blendWeights) { Vector3 vertex = vertexTransform * ToVector3(mesh->mVertices[index]); box.Merge(vertex); *dest++ = vertex.x_; *dest++ = vertex.y_; *dest++ = vertex.z_; if (elementMask & MASK_NORMAL) { Vector3 normal = normalTransform * ToVector3(mesh->mNormals[index]); *dest++ = normal.x_; *dest++ = normal.y_; *dest++ = normal.z_; } if (elementMask & MASK_COLOR) { *((unsigned*)dest) = Color(mesh->mColors[0][index].r, mesh->mColors[0][index].g, mesh->mColors[0][index].b, mesh->mColors[0][index].a).ToUInt(); ++dest; } if (elementMask & MASK_TEXCOORD1) { Vector3 texCoord = ToVector3(mesh->mTextureCoords[0][index]); *dest++ = texCoord.x_; *dest++ = texCoord.y_; } if (elementMask & MASK_TEXCOORD2) { Vector3 texCoord = ToVector3(mesh->mTextureCoords[1][index]); *dest++ = texCoord.x_; *dest++ = texCoord.y_; } if (elementMask & MASK_TANGENT) { Vector3 tangent = normalTransform * ToVector3(mesh->mTangents[index]); Vector3 normal = normalTransform * ToVector3(mesh->mNormals[index]); Vector3 bitangent = normalTransform * ToVector3(mesh->mBitangents[index]); // Check handedness float w = 1.0f; if ((tangent.CrossProduct(normal)).DotProduct(bitangent) < 0.5f) w = -1.0f; *dest++ = tangent.x_; *dest++ = tangent.y_; *dest++ = tangent.z_; *dest++ = w; } if (elementMask & MASK_BLENDWEIGHTS) { for (unsigned i = 0; i < 4; ++i) { if (i < blendWeights[index].Size()) *dest++ = blendWeights[index][i]; else *dest++ = 0.0f; } } if (elementMask & MASK_BLENDINDICES) { unsigned char* destBytes = (unsigned char*)dest; ++dest; for (unsigned i = 0; i < 4; ++i) { if (i < blendIndices[index].Size()) *destBytes++ = blendIndices[index][i]; else *destBytes++ = 0; } } }
Vector3 RigidBody::GetVelocityAtPoint(const Vector3& position) const { return body_ ? ToVector3(body_->getVelocityInLocalPoint(ToBtVector3(position - centerOfMass_))) : Vector3::ZERO; }
Vector3 JSONValue::GetVector3(unsigned index) const { return ToVector3(GetCString(index)); }
Vector3 XMLElement::GetVector3(const String& name) const { return ToVector3(GetAttribute(name)); }
Vector3 JSONValue::GetVector3(const String& name) const { return ToVector3(GetCString(name)); }
inline void TransformComponent::SetPosition(const Vector2& position) { m_position = ToVector3(position); DoLockXYZ(m_position); }
virtual void SetScale(const Vector2& scaleNonUniform) { m_scale = ToVector3(scaleNonUniform); }
Vector3 ToVector3(const String& source) { return ToVector3(source.CString()); }
void QtPropertyDataDavaVariant::SetValueInternal(const QVariant &value) { switch(curVariantValue.type) { case DAVA::VariantType::TYPE_BOOLEAN: curVariantValue.SetBool(value.toBool()); break; case DAVA::VariantType::TYPE_FLOAT: curVariantValue.SetFloat(value.toFloat()); break; case DAVA::VariantType::TYPE_INT32: curVariantValue.SetInt32(value.toInt()); break; case DAVA::VariantType::TYPE_INT64: curVariantValue.SetInt64(value.toLongLong()); break; case DAVA::VariantType::TYPE_UINT32: curVariantValue.SetUInt32(value.toUInt()); break; case DAVA::VariantType::TYPE_UINT64: curVariantValue.SetUInt64(value.toULongLong()); break; case DAVA::VariantType::TYPE_KEYED_ARCHIVE: ToKeyedArchive(value); break; case DAVA::VariantType::TYPE_STRING: curVariantValue.SetString(value.toString().toStdString()); break; case DAVA::VariantType::TYPE_MATRIX2: ToMatrix2(value); break; case DAVA::VariantType::TYPE_MATRIX3: ToMatrix3(value); break; case DAVA::VariantType::TYPE_MATRIX4: ToMatrix4(value); break; case DAVA::VariantType::TYPE_VECTOR2: ToVector2(value); break; case DAVA::VariantType::TYPE_VECTOR3: ToVector3(value); break; case DAVA::VariantType::TYPE_VECTOR4: ToVector4(value); break; case DAVA::VariantType::TYPE_COLOR: ToColor(value); break; case DAVA::VariantType::TYPE_FASTNAME: curVariantValue.SetFastName(DAVA::FastName(value.toString().toStdString().c_str())); break; case DAVA::VariantType::TYPE_AABBOX3: ToAABBox3(value); break; case DAVA::VariantType::TYPE_BYTE_ARRAY: default: break; } }