Vector3 PhysicsConstraint::getWorldCenterOfMass(const Model* model) { Vector3 center; const BoundingBox& box = model->getMesh()->getBoundingBox(); if (!(box.min.isZero() && box.max.isZero())) { Vector3 bMin, bMax; model->getNode()->getWorldMatrix().transformPoint(box.min, &bMin); model->getNode()->getWorldMatrix().transformPoint(box.max, &bMax); center.set(bMin, bMax); center.scale(0.5f); center.add(bMin); } else { const BoundingSphere& sphere = model->getMesh()->getBoundingSphere(); if (!(sphere.center.isZero() && sphere.radius == 0)) { model->getNode()->getWorldMatrix().transformPoint(sphere.center, ¢er); } else { // Warn the user that the model has no bounding volume. WARN_VARG("Model \'%s\' has no bounding volume - center of mass is defaulting to local coordinate origin.", model->getNode()->getId()); model->getNode()->getWorldMatrix().transformPoint(¢er); } } return center; }
AudioSource* AudioSource::create(Properties* properties) { // Check if the properties is valid and has a valid namespace. assert(properties); if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0)) { WARN("Failed to load audio source from properties object: must be non-null object and have namespace equal to \'audio\'."); return NULL; } const char* path = properties->getString("path"); if (path == NULL) { WARN("Audio file failed to load; the file path was not specified."); return NULL; } // Create the audio source. AudioSource* audio = AudioSource::create(path); if (audio == NULL) { WARN_VARG("Audio file '%s' failed to load properly.", path); return NULL; } // Set any properties that the user specified in the .audio file. if (properties->getString("looped") != NULL) { audio->setLooped(properties->getBool("looped")); } if (properties->getString("gain") != NULL) { audio->setGain(properties->getFloat("gain")); } if (properties->getString("pitch") != NULL) { audio->setPitch(properties->getFloat("pitch")); } Vector3 v; if (properties->getVector3("velocity", &v)) { audio->setVelocity(v); } return audio; }
PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Node* node, Properties* properties) { // Check if the properties is valid and has a valid namespace. assert(properties); if (!properties || !(strcmp(properties->getNamespace(), "character") == 0 || strcmp(properties->getNamespace(), "ghost") == 0 || strcmp(properties->getNamespace(), "rigidbody") == 0)) { WARN("Failed to load physics collision shape from properties object: must be non-null object and have namespace equal to \'character\', \'ghost\', or \'rigidbody\'."); return NULL; } // Set values to their defaults. PhysicsCollisionShape::Type type = PhysicsCollisionShape::SHAPE_BOX; Vector3* extents = NULL; Vector3* center = NULL; float radius = -1.0f; float height = -1.0f; bool centerIsAbsolute = false; const char* imagePath = NULL; bool typeSpecified = false; // Load the defined properties. properties->rewind(); const char* name; while (name = properties->getNextProperty()) { if (strcmp(name, "type") == 0) { std::string typeStr = properties->getString(); if (typeStr == "BOX") type = SHAPE_BOX; else if (typeStr == "SPHERE") type = SHAPE_SPHERE; else if (typeStr == "MESH") type = SHAPE_MESH; else if (typeStr == "HEIGHTFIELD") type = SHAPE_HEIGHTFIELD; else if (typeStr == "CAPSULE") type = SHAPE_CAPSULE; else { WARN_VARG("Could not create physics collision shape; unsupported value for collision shape type: '%s'.", typeStr.c_str()); return NULL; } typeSpecified = true; } else if (strcmp(name, "image") == 0) { imagePath = properties->getString(); } else if (strcmp(name, "radius") == 0) { radius = properties->getFloat(); } else if (strcmp(name, "height") == 0) { height = properties->getFloat(); } else if (strcmp(name, "extents") == 0) { extents = new Vector3(); properties->getVector3("extents", extents); } else if (strcmp(name, "center") == 0) { center = new Vector3(); properties->getVector3("center", center); } else if (strcmp(name, "center-absolute") == 0) { centerIsAbsolute = properties->getBool(); } } if (!typeSpecified) { WARN("Missing 'type' specifier for collision shape definition."); return NULL; } // Create the collision shape. PhysicsCollisionShape::Definition* shape = new PhysicsCollisionShape::Definition(); switch (type) { case SHAPE_BOX: if (extents) { if (center) { *shape = box(*extents, *center, centerIsAbsolute); } else { *shape = box(*extents); } } else { *shape = box(); } break; case SHAPE_SPHERE: if (radius != -1.0f) { if (center) { *shape = sphere(radius, *center, centerIsAbsolute); } else { *shape = sphere(radius); } } else { *shape = sphere(); } break; case SHAPE_CAPSULE: if (radius != -1.0f && height != -1.0f) { if (center) { *shape = capsule(radius, height, *center, centerIsAbsolute); } else { *shape = capsule(radius, height); } } else { *shape = capsule(); } break; case SHAPE_MESH: { // Mesh is required on node Mesh* nodeMesh = node->getModel() ? node->getModel()->getMesh() : NULL; if (nodeMesh == NULL) { WARN("Cannot create mesh rigid body for node without mode/mesh."); return NULL; } // Check that the node's mesh's primitive type is supported. switch (nodeMesh->getPrimitiveType()) { case Mesh::TRIANGLES: { *shape = mesh(nodeMesh); break; } case Mesh::LINES: case Mesh::LINE_STRIP: case Mesh::POINTS: case Mesh::TRIANGLE_STRIP: WARN("Mesh rigid bodies are currently only supported on meshes with primitive type equal to TRIANGLES."); SAFE_DELETE(shape); break; } break; } case SHAPE_HEIGHTFIELD: if (imagePath == NULL) { WARN("Heightfield rigid body requires an image path."); } else { // Load the image data from the given file path. Image* image = Image::create(imagePath); if (!image) return NULL; // Ensure that the image's pixel format is supported. switch (image->getFormat()) { case Image::RGB: case Image::RGBA: break; default: WARN_VARG("Heightmap: pixel format is not supported: %d", image->getFormat()); return NULL; } *shape = PhysicsCollisionShape::heightfield(image); SAFE_RELEASE(image); } break; default: WARN("Unsupported value for physics collision shape type."); break; } SAFE_DELETE(extents); SAFE_DELETE(center); return shape; }
void AudioController::update(long elapsedTime) { AudioListener* listener = AudioListener::getInstance(); if (listener) { #ifndef __ANDROID__ alListenerf(AL_GAIN, listener->getGain()); alListenerfv(AL_ORIENTATION, (ALfloat*)listener->getOrientation()); alListenerfv(AL_VELOCITY, (ALfloat*)&listener->getVelocity()); alListenerfv(AL_POSITION, (ALfloat*)&listener->getPosition()); #else if (!_listenerObject) { const SLInterfaceID interfaces[3] = {SL_IID_3DDOPPLER, SL_IID_3DLOCATION}; const SLboolean required[3] = {SL_BOOLEAN_FALSE, SL_BOOLEAN_FALSE}; SLresult result = (*_engineEngine)->CreateListener(_engineEngine, &_listenerObject, 2, interfaces, required); if (result != SL_RESULT_SUCCESS) { WARN_VARG("AudioController: failed to create listener (%u).", result); return; } result = (*_listenerObject)->Realize(_listenerObject, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: failed to realize listener."); return; } // Get the doppler interface in order to set the listener's velocity. result = (*_listenerObject)->GetInterface(_listenerObject, SL_IID_3DDOPPLER, &_listenerDoppler); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: Unable to retrieve listener doppler interface."); return; } // Get the location interface in order to set the listener's position and orientation. result = (*_listenerObject)->GetInterface(_listenerObject, SL_IID_3DLOCATION, &_listenerLocation); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: Unable to retrieve listener location interface."); return; } } SLVec3D f; f.x = listener->getOrientationForward().x; f.y = listener->getOrientationForward().y; f.z = listener->getOrientationForward().z; SLVec3D a; a.x = listener->getOrientationUp().x; a.y = listener->getOrientationUp().y; a.z = listener->getOrientationUp().z; SLresult result = (*_listenerLocation)->SetOrientationVectors(_listenerLocation, &f, &a); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: Unable to set listener orientation."); } SLVec3D p; p.x = listener->getPosition().x; p.y = listener->getPosition().y; p.z = listener->getPosition().z; result = (*_listenerLocation)->SetLocationCartesian(_listenerLocation, &p); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: Unable to set listener location."); } SLVec3D v; v.x = listener->getVelocity().x; v.y = listener->getVelocity().y; v.z = listener->getVelocity().z; result = (*_listenerDoppler)->SetVelocityCartesian(_listenerDoppler, &v); if (result != SL_RESULT_SUCCESS) { WARN("AudioController: Unable to set listener velocity."); } #endif } }
void MaterialParameter::bind(Effect* effect) { // If we had a Uniform cached that is not from the passed in effect, // we need to update our uniform to point to the new effect's uniform. if (!_uniform || _uniform->getEffect() != effect) { _uniform = effect->getUniform(_name.c_str()); if (!_uniform) { // This parameter was not found in the specified effect, so do nothing. WARN_VARG("Warning: Material parameter '%s' not found in effect '%s'.", _name.c_str(), effect->getId()); return; } } switch (_type) { case MaterialParameter::FLOAT: if (_count == 1) { effect->setValue(_uniform, _value.floatValue); } else { assert(_value.floatPtrValue); effect->setValue(_uniform, _value.floatPtrValue, _count); } break; case MaterialParameter::INT: if (_count == 1) { effect->setValue(_uniform, _value.intValue); } else { assert(_value.intPtrValue); effect->setValue(_uniform, _value.intPtrValue, _count); } break; case MaterialParameter::VECTOR2: assert(_value.floatPtrValue); effect->setValue(_uniform, reinterpret_cast<Vector2*>(_value.floatPtrValue), _count); break; case MaterialParameter::VECTOR3: assert(_value.floatPtrValue); effect->setValue(_uniform, reinterpret_cast<Vector3*>(_value.floatPtrValue), _count); break; case MaterialParameter::VECTOR4: assert(_value.floatPtrValue); effect->setValue(_uniform, reinterpret_cast<Vector4*>(_value.floatPtrValue), _count); break; case MaterialParameter::MATRIX: assert(_value.floatPtrValue); effect->setValue(_uniform, reinterpret_cast<Matrix*>(_value.floatPtrValue), _count); break; case MaterialParameter::SAMPLER: assert(_value.samplerValue); effect->setValue(_uniform, _value.samplerValue); break; case MaterialParameter::METHOD: assert(_value.method); _value.method->setValue(effect); break; } }