Exemple #1
0
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, &center);
        }
        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(&center);
        }
    }

    return center;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
    }
}