Example #1
0
// ----------------------------------------------------------------------------
void IKSolver::Solve()
{
    URHO3D_PROFILE(IKSolve);

    if (treeNeedsRebuild)
        RebuildTree();

    if (chainTreesNeedUpdating_)
        RebuildChainTrees();

    if (IsSolverTreeValid() == false)
        return;

    if (features_ & UPDATE_ORIGINAL_POSE)
        ApplySceneToOriginalPose();

    if (features_ & UPDATE_ACTIVE_POSE)
        ApplySceneToActivePose();

    if (features_ & USE_ORIGINAL_POSE)
        ApplyOriginalPoseToActivePose();

    for (auto & it : effectorList_)
    {
        it->UpdateTargetNodePosition();
    }

    ik_solver_solve(solver_);

    if (features_ & JOINT_ROTATIONS)
        ik_solver_calculate_joint_rotations(solver_);

    ApplyActivePoseToScene();
}
Example #2
0
void RigidBody::UpdateScale()
{
    URHO3D_PROFILE(RigidBody_UpdateScale);

    // If placeable exists, set local scaling from its scale
    Placeable* placeable = impl->placeable;
    if (placeable && impl->shape)
    {
        const ShapeType shape = static_cast<ShapeType>(shapeType.Get());
        const float3 &sizeVec = size.Get();
        const float3 scale = placeable->WorldScale();

        // Trianglemesh or convexhull does not have scaling of its own in the shape, so multiply with the size
        btVector3 finalScale = (shape != TriMesh && shape != ConvexHull ?
            btVector3(scale.x, scale.y, scale.z) : btVector3(sizeVec.x * scale.x, sizeVec.y * scale.y, sizeVec.z * scale.z));

        /* Bullet has asserts for zero scale in debug mode. These wont trigger in Release
           builds but they sure do indicate we should not be passing zero scale into it.
           @note This is the same logic Placeable enforces before passing scale to ogre,
           but Transform attributes scale can still be zero or negative. */
        if (finalScale.x() < 0)
            finalScale.setX(0);
        if (finalScale.y() < 0)
            finalScale.setY(0);
        if (finalScale.z() < 0)
            finalScale.setZ(0);

        impl->shape->setLocalScaling(finalScale);
    }
}
Example #3
0
void InputAPI::Update(float /*frametime*/)
{
    URHO3D_PROFILE(InputAPI_Update);

    // Move all the double-buffered input events to current events.
    pressedKeys = newKeysPressedQueue;
    newKeysPressedQueue.Clear();

    releasedKeys = newKeysReleasedQueue;
    newKeysReleasedQueue.Clear();

    pressedMouseButtons = newMouseButtonsPressedQueue;
    newMouseButtonsPressedQueue = 0;

    releasedMouseButtons = newMouseButtonsReleasedQueue;
    newMouseButtonsReleasedQueue = 0;

    // Update the new frame start to all input contexts.
    topLevelInputContext.UpdateFrame();

    for(InputContextList::Iterator iter = registeredInputContexts.Begin();
        iter != registeredInputContexts.End(); ++iter)
    {
        InputContextPtr inputContext = (*iter).Lock();
        if (inputContext)
            inputContext->UpdateFrame();
    }

    PruneDeadInputContexts();
}
Example #4
0
void GraphicsWorld::RaycastInternal(const Ray& ray, unsigned layerMask, float maxDistance, bool getAllResults)
{
    URHO3D_PROFILE(GraphicsWorld_Raycast);
    
    rayHits_.Clear();

    Urho3D::PODVector<Urho3D::RayQueryResult> result;
    Urho3D::Octree* octree = urhoScene_->GetComponent<Urho3D::Octree>();
    Urho3D::RayOctreeQuery query(result, ray, Urho3D::RAY_TRIANGLE, maxDistance, Urho3D::DRAWABLE_GEOMETRY);
    octree->Raycast(query);

    for (Urho3D::PODVector<Urho3D::RayQueryResult>::ConstIterator i = result.Begin(); i != result.End(); ++i)
    {
        if (!i->node_)
            continue;
        Entity* entity = static_cast<Entity*>(i->node_->GetVar(entityLink).GetPtr());
        if (!entity)
            continue; // Not a drawable associated with Tundra entity
        Placeable* placeable = entity->Component<Placeable>();
        if (placeable && (placeable->selectionLayer.Get() & layerMask) == 0)
            continue;
        IComponent* component = static_cast<IComponent*>(i->node_->GetVar(componentLink).GetPtr());
        
        RayQueryResult res;
        res.component = component;
        res.entity = entity;
        res.pos = i->position_;
        res.normal = i->normal_;
        /// \todo Fill the rest, like submesh information

        rayHits_.Push(res);
        if (!getAllResults)
            break;
    }
}
Example #5
0
unsigned File::GetChecksum()
{
    if (offset_ || checksum_)
        return checksum_;
#ifdef __ANDROID__
    if ((!handle_ && !assetHandle_) || mode_ == FILE_WRITE)
#else
    if (!handle_ || mode_ == FILE_WRITE)
#endif
        return 0;

    URHO3D_PROFILE(CalculateFileChecksum);

    unsigned oldPos = position_;
    checksum_ = 0;

    Seek(0);
    while (!IsEof())
    {
        unsigned char block[1024];
        unsigned readBytes = Read(block, 1024);
        for (unsigned i = 0; i < readBytes; ++i)
            checksum_ = SDBMHash(checksum_, block[i]);
    }

    Seek(oldPos);
    return checksum_;
}
void SceneInteract::OnScriptInstanceCreated(JavaScriptInstance* instance)
{
    URHO3D_PROFILE(ExposeSceneInteract);

    duk_context* ctx = instance->Context();
    Expose_SceneInteract(ctx);

    instance->RegisterService("sceneinteract", this);
}
void SceneInteract::Update(float /*frameTime*/)
{
    if (!framework->IsHeadless())
    {
        URHO3D_PROFILE(SceneInteract_Update);

        ExecuteRaycast();
        if (lastHitEntity)
            lastHitEntity->Exec(EntityAction::Local, "MouseHover");
        
        frameRaycasted = false;
    }
}
Example #8
0
bool Font::SaveXML(Serializer& dest, int pointSize, bool usedGlyphs, const String& indentation)
{
    FontFace* fontFace = GetFace(pointSize);
    if (!fontFace)
        return false;

    URHO3D_PROFILE(FontSaveXML);

    SharedPtr<FontFaceBitmap> packedFontFace(new FontFaceBitmap(this));
    if (!packedFontFace->Load(fontFace, usedGlyphs))
        return false;

    return packedFontFace->Save(dest, pointSize, indentation);
}
Example #9
0
EntityVector GraphicsWorld::FrustumQuery(const Urho3D::IntRect &viewrect) const
{
    URHO3D_PROFILE(GraphicsWorld_FrustumQuery);
    
    EntityVector ret;
    Camera* cameraComp = renderer_->MainCameraComponent();
    if (!cameraComp || cameraComp->ParentScene() != scene_)
        return ret;
     Urho3D::Camera* cam = cameraComp->UrhoCamera();
     if (!cam)
        return ret;

    int width = renderer_->WindowWidth();
    int height = renderer_->WindowHeight();
    float w = (float)width;
    float h = (float)height;
    float left = (float)(viewrect.left_) / w, right = (float)(viewrect.right_) / w;
    float top = (float)(viewrect.top_) / h, bottom = (float)(viewrect.bottom_) / h;
    if (left > right) std::swap(left, right);
    if (top > bottom) std::swap(top, bottom);
    // don't do selection if box is too small
    if ((right - left) * (bottom - top) < 0.0001)
        return ret;

    Urho3D::Frustum fr;
    fr.vertices_[0] = cam->ScreenToWorldPoint(Urho3D::Vector3(right, top, cam->GetNearClip()));
    fr.vertices_[1] = cam->ScreenToWorldPoint(Urho3D::Vector3(right, bottom, cam->GetNearClip()));
    fr.vertices_[2] = cam->ScreenToWorldPoint(Urho3D::Vector3(left, bottom, cam->GetNearClip()));
    fr.vertices_[3] = cam->ScreenToWorldPoint(Urho3D::Vector3(left, top, cam->GetNearClip()));
    fr.vertices_[4] = cam->ScreenToWorldPoint(Urho3D::Vector3(right, top, cam->GetFarClip()));
    fr.vertices_[5] = cam->ScreenToWorldPoint(Urho3D::Vector3(right, bottom, cam->GetFarClip()));
    fr.vertices_[6] = cam->ScreenToWorldPoint(Urho3D::Vector3(left, bottom, cam->GetFarClip()));
    fr.vertices_[7] = cam->ScreenToWorldPoint(Urho3D::Vector3(left, top, cam->GetFarClip()));
    fr.UpdatePlanes();

    Urho3D::PODVector<Urho3D::Drawable*> result;
    Urho3D::FrustumOctreeQuery query(result, fr, Urho3D::DRAWABLE_GEOMETRY);
    urhoScene_->GetComponent<Urho3D::Octree>()->GetDrawables(query);

    for (Urho3D::PODVector<Urho3D::Drawable*>::ConstIterator i = result.Begin(); i != result.End(); ++i)
    {
        Entity* entity = static_cast<Entity*>((*i)->GetNode()->GetVar(entityLink).GetPtr());
        if (entity)
            ret.Push(EntityPtr(entity));
    }

    return ret;
}
Example #10
0
bool Sound::BeginLoad(Deserializer& source)
{
    URHO3D_PROFILE(LoadSound);

    bool success;
    if (GetExtension(source.GetName()) == ".ogg")
        success = LoadOggVorbis(source);
    else if (GetExtension(source.GetName()) == ".wav")
        success = LoadWav(source);
    else
        success = LoadRaw(source);

    // Load optional parameters
    if (success)
        LoadParameters();

    return success;
}
Example #11
0
void NamedPipe::Close()
{
    if (handle_ != INVALID_HANDLE_VALUE)
    {
        URHO3D_PROFILE(CloseNamedPipe);

        if (isServer_)
        {
            DisconnectNamedPipe(handle_);
            isServer_ = false;
        }

        CloseHandle(handle_);
        handle_ = INVALID_HANDLE_VALUE;
        pipeName_.Clear();

        URHO3D_LOGDEBUG("Closed named pipe " + pipeName_);
    }
}
Example #12
0
void NamedPipe::Close()
{
    if (readHandle_ != -1 || writeHandle_ != -1)
    {
        URHO3D_PROFILE(CloseNamedPipe);
        SAFE_CLOSE(readHandle_);
        SAFE_CLOSE(writeHandle_);

        if (isServer_)
        {
            String serverReadName = pipePath + pipeName_ + "SR";
            String clientReadName = pipePath + pipeName_ + "CR";
            unlink(serverReadName.CString());
            unlink(clientReadName.CString());
            isServer_ = false;
        }

        pipeName_.Clear();
    }
}
Example #13
0
FontFace* Font::GetFace(float pointSize)
{
    // In headless mode, always return null
    auto* graphics = GetSubsystem<Graphics>();
    if (!graphics)
        return nullptr;

    // For bitmap font type, always return the same font face provided by the font's bitmap file regardless of the actual requested point size
    if (fontType_ == FONT_BITMAP)
        pointSize = 0;
    else
        pointSize = Clamp(pointSize, MIN_POINT_SIZE, MAX_POINT_SIZE);

    // For outline fonts, we return the nearest size in 1/64th increments, as that's what FreeType supports.
    int key = FloatToFixed(pointSize);
    HashMap<int, SharedPtr<FontFace> >::Iterator i = faces_.Find(key);
    if (i != faces_.End())
    {
        if (!i->second_->IsDataLost())
            return i->second_;
        else
        {
            // Erase and reload face if texture data lost (OpenGL mode only)
            faces_.Erase(i);
        }
    }

    URHO3D_PROFILE(GetFontFace);

    switch (fontType_)
    {
    case FONT_FREETYPE:
        return GetFaceFreeType(pointSize);

    case FONT_BITMAP:
        return GetFaceBitmap(pointSize);

    default:
        return nullptr;
    }
}
Example #14
0
bool UrhoMeshAsset::DeserializeFromData(const u8 *data_, uint numBytes, bool /*allowAsynchronous*/)
{
    URHO3D_PROFILE(UrhoMeshAsset_LoadFromFileInMemory);

    /// Force an unload of previous data first.
    Unload();

    Urho3D::MemoryBuffer buffer(data_, numBytes);
    model = new Urho3D::Model(GetContext());
    if (model->Load(buffer))
    {
        assetAPI->AssetLoadCompleted(Name());
        return true;
    }
    else
    {
        LogError("MeshAsset::DeserializeFromData: Failed to load Urho format asset " + Name());
        model.Reset();
        return false;
    }
}
Example #15
0
/// Actually update sound sources with the specific timestep. Called internally.
void Audio::UpdateInternal(float timeStep)
{
    URHO3D_PROFILE(UpdateAudio);
    if(listener_) {
        d->updateListenerPostion(listener_->GetNode());
    }
    // Update in reverse order, because sound sources might remove themselves
    for (unsigned i = soundSources_.size() - 1; i < soundSources_.size(); --i)
    {
        SoundSource* source = soundSources_[i];

        // Check for pause if necessary; do not update paused sound sources
        if (!pausedSoundTypes_.empty())
        {
            if (pausedSoundTypes_.contains(source->GetSoundType()))
                continue;
        }

        source->Update(timeStep);
    }
}
Example #16
0
void RigidBody::UpdatePosRotFromPlaceable()
{
    URHO3D_PROFILE(RigidBody_UpdatePosRotFromPlaceable);
    
    Placeable* placeable = impl->placeable;
    if (!placeable || !impl->body)
        return;
    
    float3 position = placeable->WorldPosition();
    Quat orientation = placeable->WorldOrientation();

    btTransform& worldTrans = impl->body->getWorldTransform();
    worldTrans.setOrigin(position);
    worldTrans.setRotation(orientation);
    
    // When we forcibly set the physics transform, also set the interpolation transform to prevent jerky motion
    btTransform interpTrans = impl->body->getInterpolationWorldTransform();
    interpTrans.setOrigin(worldTrans.getOrigin());
    interpTrans.setRotation(worldTrans.getRotation());
    impl->body->setInterpolationWorldTransform(interpTrans);
    
    KeepActive();
}
Example #17
0
void RigidBody::AddBodyToWorld()
{
    if (!physicsWorld_)
        return;

    URHO3D_PROFILE(AddBodyToWorld);

    if (mass_ < 0.0f)
        mass_ = 0.0f;

    if (body_)
        RemoveBodyFromWorld();
    else
    {
        // Correct inertia will be calculated below
        btVector3 localInertia(0.0f, 0.0f, 0.0f);
        body_ = new btRigidBody(mass_, this, shiftedCompoundShape_, localInertia);
        body_->setUserPointer(this);

        // Check for existence of the SmoothedTransform component, which should be created by now in network client mode.
        // If it exists, subscribe to its change events
        smoothedTransform_ = GetComponent<SmoothedTransform>();
        if (smoothedTransform_)
        {
            SubscribeToEvent(smoothedTransform_, E_TARGETPOSITION, URHO3D_HANDLER(RigidBody, HandleTargetPosition));
            SubscribeToEvent(smoothedTransform_, E_TARGETROTATION, URHO3D_HANDLER(RigidBody, HandleTargetRotation));
        }

        // Check if CollisionShapes already exist in the node and add them to the compound shape.
        // Do not update mass yet, but do it once all shapes have been added
        PODVector<CollisionShape*> shapes;
        node_->GetComponents<CollisionShape>(shapes);
        for (PODVector<CollisionShape*>::Iterator i = shapes.Begin(); i != shapes.End(); ++i)
            (*i)->NotifyRigidBody(false);

        // Check if this node contains Constraint components that were waiting for the rigid body to be created, and signal them
        // to create themselves now
        PODVector<Constraint*> constraints;
        node_->GetComponents<Constraint>(constraints);
        for (PODVector<Constraint*>::Iterator i = constraints.Begin(); i != constraints.End(); ++i)
            (*i)->CreateConstraint();
    }

    UpdateMass();
    UpdateGravity();

    int flags = body_->getCollisionFlags();
    if (trigger_)
        flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
    else
        flags &= ~btCollisionObject::CF_NO_CONTACT_RESPONSE;
    if (kinematic_)
        flags |= btCollisionObject::CF_KINEMATIC_OBJECT;
    else
        flags &= ~btCollisionObject::CF_KINEMATIC_OBJECT;
    body_->setCollisionFlags(flags);
    body_->forceActivationState(kinematic_ ? DISABLE_DEACTIVATION : ISLAND_SLEEPING);

    if (!IsEnabledEffective())
        return;

    btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
    world->addRigidBody(body_, (short)collisionLayer_, (short)collisionMask_);
    inWorld_ = true;
    readdBody_ = false;

    if (mass_ > 0.0f)
        Activate();
    else
    {
        SetLinearVelocity(Vector3::ZERO);
        SetAngularVelocity(Vector3::ZERO);
    }
}
Example #18
0
void DebugRenderer::Render()
{
    if (!HasContent())
        return;

    Graphics* graphics = GetSubsystem<Graphics>();
    // Engine does not render when window is closed or device is lost
    assert(graphics && graphics->IsInitialized() && !graphics->IsDeviceLost());

    URHO3D_PROFILE(RenderDebugGeometry);

    ShaderVariation* vs = graphics->GetShader(VS, "Basic", "VERTEXCOLOR");
    ShaderVariation* ps = graphics->GetShader(PS, "Basic", "VERTEXCOLOR");

    unsigned numVertices = (lines_.Size() + noDepthLines_.Size()) * 2 + (triangles_.Size() + noDepthTriangles_.Size()) * 3;
    // Resize the vertex buffer if too small or much too large
    if (vertexBuffer_->GetVertexCount() < numVertices || vertexBuffer_->GetVertexCount() > numVertices * 2)
        vertexBuffer_->SetSize(numVertices, MASK_POSITION | MASK_COLOR, true);

    float* dest = (float*)vertexBuffer_->Lock(0, numVertices, true);
    if (!dest)
        return;

    for (unsigned i = 0; i < lines_.Size(); ++i)
    {
        const DebugLine& line = lines_[i];

        dest[0] = line.start_.x_;
        dest[1] = line.start_.y_;
        dest[2] = line.start_.z_;
        ((unsigned&)dest[3]) = line.color_;
        dest[4] = line.end_.x_;
        dest[5] = line.end_.y_;
        dest[6] = line.end_.z_;
        ((unsigned&)dest[7]) = line.color_;

        dest += 8;
    }

    for (unsigned i = 0; i < noDepthLines_.Size(); ++i)
    {
        const DebugLine& line = noDepthLines_[i];

        dest[0] = line.start_.x_;
        dest[1] = line.start_.y_;
        dest[2] = line.start_.z_;
        ((unsigned&)dest[3]) = line.color_;
        dest[4] = line.end_.x_;
        dest[5] = line.end_.y_;
        dest[6] = line.end_.z_;
        ((unsigned&)dest[7]) = line.color_;

        dest += 8;
    }

    for (unsigned i = 0; i < triangles_.Size(); ++i)
    {
        const DebugTriangle& triangle = triangles_[i];

        dest[0] = triangle.v1_.x_;
        dest[1] = triangle.v1_.y_;
        dest[2] = triangle.v1_.z_;
        ((unsigned&)dest[3]) = triangle.color_;

        dest[4] = triangle.v2_.x_;
        dest[5] = triangle.v2_.y_;
        dest[6] = triangle.v2_.z_;
        ((unsigned&)dest[7]) = triangle.color_;

        dest[8] = triangle.v3_.x_;
        dest[9] = triangle.v3_.y_;
        dest[10] = triangle.v3_.z_;
        ((unsigned&)dest[11]) = triangle.color_;

        dest += 12;
    }

    for (unsigned i = 0; i < noDepthTriangles_.Size(); ++i)
    {
        const DebugTriangle& triangle = noDepthTriangles_[i];

        dest[0] = triangle.v1_.x_;
        dest[1] = triangle.v1_.y_;
        dest[2] = triangle.v1_.z_;
        ((unsigned&)dest[3]) = triangle.color_;

        dest[4] = triangle.v2_.x_;
        dest[5] = triangle.v2_.y_;
        dest[6] = triangle.v2_.z_;
        ((unsigned&)dest[7]) = triangle.color_;

        dest[8] = triangle.v3_.x_;
        dest[9] = triangle.v3_.y_;
        dest[10] = triangle.v3_.z_;
        ((unsigned&)dest[11]) = triangle.color_;

        dest += 12;
    }

    vertexBuffer_->Unlock();

    graphics->SetBlendMode(lineAntiAlias_ ? BLEND_ALPHA : BLEND_REPLACE);
    graphics->SetColorWrite(true);
    graphics->SetCullMode(CULL_NONE);
    graphics->SetDepthWrite(true);
    graphics->SetLineAntiAlias(lineAntiAlias_);
    graphics->SetScissorTest(false);
    graphics->SetStencilTest(false);
    graphics->SetShaders(vs, ps);
    graphics->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
    graphics->SetShaderParameter(VSP_VIEW, view_);
    graphics->SetShaderParameter(VSP_VIEWINV, view_.Inverse());
    graphics->SetShaderParameter(VSP_VIEWPROJ, gpuProjection_ * view_);
    graphics->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));
    graphics->SetVertexBuffer(vertexBuffer_);

    unsigned start = 0;
    unsigned count = 0;
    if (lines_.Size())
    {
        count = lines_.Size() * 2;
        graphics->SetDepthTest(CMP_LESSEQUAL);
        graphics->Draw(LINE_LIST, start, count);
        start += count;
    }
    if (noDepthLines_.Size())
    {
        count = noDepthLines_.Size() * 2;
        graphics->SetDepthTest(CMP_ALWAYS);
        graphics->Draw(LINE_LIST, start, count);
        start += count;
    }

    graphics->SetBlendMode(BLEND_ALPHA);

    if (triangles_.Size())
    {
        count = triangles_.Size() * 3;
        graphics->SetDepthTest(CMP_LESSEQUAL);
        graphics->Draw(TRIANGLE_LIST, start, count);
        start += count;
    }
    if (noDepthTriangles_.Size())
    {
        count = noDepthTriangles_.Size() * 3;
        graphics->SetDepthTest(CMP_ALWAYS);
        graphics->Draw(TRIANGLE_LIST, start, count);
    }

    graphics->SetLineAntiAlias(false);
}
Example #19
0
void CustomGeometry::Commit()
{
    URHO3D_PROFILE(CommitCustomGeometry);

    unsigned totalVertices = 0;
    boundingBox_.Clear();

    for (unsigned i = 0; i < vertices_.Size(); ++i)
    {
        totalVertices += vertices_[i].Size();

        for (unsigned j = 0; j < vertices_[i].Size(); ++j)
            boundingBox_.Merge(vertices_[i][j].position_);
    }

    // Make sure world-space bounding box will be updated
    OnMarkedDirty(node_);

    // Resize (recreate) the vertex buffer only if necessary
    if (vertexBuffer_->GetVertexCount() != totalVertices || vertexBuffer_->GetElementMask() != elementMask_ ||
        vertexBuffer_->IsDynamic() != dynamic_)
        vertexBuffer_->SetSize(totalVertices, elementMask_, dynamic_);

    if (totalVertices)
    {
        unsigned char* dest = (unsigned char*)vertexBuffer_->Lock(0, totalVertices, true);
        if (dest)
        {
            unsigned vertexStart = 0;

            for (unsigned i = 0; i < vertices_.Size(); ++i)
            {
                unsigned vertexCount = 0;

                for (unsigned j = 0; j < vertices_[i].Size(); ++j)
                {
                    *((Vector3*)dest) = vertices_[i][j].position_;
                    dest += sizeof(Vector3);

                    if (elementMask_ & MASK_NORMAL)
                    {
                        *((Vector3*)dest) = vertices_[i][j].normal_;
                        dest += sizeof(Vector3);
                    }
                    if (elementMask_ & MASK_COLOR)
                    {
                        *((unsigned*)dest) = vertices_[i][j].color_;
                        dest += sizeof(unsigned);
                    }
                    if (elementMask_ & MASK_TEXCOORD1)
                    {
                        *((Vector2*)dest) = vertices_[i][j].texCoord_;
                        dest += sizeof(Vector2);
                    }
                    if (elementMask_ & MASK_TANGENT)
                    {
                        *((Vector4*)dest) = vertices_[i][j].tangent_;
                        dest += sizeof(Vector4);
                    }

                    ++vertexCount;
                }

                geometries_[i]->SetVertexBuffer(0, vertexBuffer_, elementMask_);
                geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, vertexStart, vertexCount);
                vertexStart += vertexCount;
            }

            vertexBuffer_->Unlock();
        }
        else
            URHO3D_LOGERROR("Failed to lock custom geometry vertex buffer");
    }
    else
    {
        for (unsigned i = 0; i < geometries_.Size(); ++i)
        {
            geometries_[i]->SetVertexBuffer(0, vertexBuffer_, elementMask_);
            geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, 0, 0);
        }
    }

    vertexBuffer_->ClearDataLost();
}
Example #20
0
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data)
{
    URHO3D_PROFILE(SetTextureData);

    if (!object_)
    {
        URHO3D_LOGERROR("No texture created, can not set data");
        return false;
    }

    if (!data)
    {
        URHO3D_LOGERROR("Null source for setting data");
        return false;
    }

    if (level >= levels_)
    {
        URHO3D_LOGERROR("Illegal mip level for setting data");
        return false;
    }

    if (graphics_->IsDeviceLost())
    {
        URHO3D_LOGWARNING("Texture data assignment while device is lost");
        dataPending_ = true;
        return true;
    }

    if (IsCompressed())
    {
        x &= ~3;
        y &= ~3;
    }

    int levelWidth = GetLevelWidth(level);
    int levelHeight = GetLevelHeight(level);
    int levelDepth = GetLevelDepth(level);
    if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 ||
        height <= 0 || depth <= 0)
    {
        URHO3D_LOGERROR("Illegal dimensions for setting data");
        return false;
    }

    D3DLOCKED_BOX d3dLockedBox;
    D3DBOX d3dBox;
    d3dBox.Left = (UINT)x;
    d3dBox.Top = (UINT)y;
    d3dBox.Front = (UINT)z;
    d3dBox.Right = (UINT)(x + width);
    d3dBox.Bottom = (UINT)(y + height);
    d3dBox.Back = (UINT)(z + depth);

    DWORD flags = 0;
    if (level == 0 && x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth &&
        pool_ == D3DPOOL_DEFAULT)
        flags |= D3DLOCK_DISCARD;

    HRESULT hr = ((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags);
    if (FAILED(hr))
    {
        URHO3D_LOGD3DERROR("Could not lock texture", hr);
        return false;
    }

    if (IsCompressed())
    {
        height = (height + 3) >> 2;
        y >>= 2;
    }

    unsigned char* src = (unsigned char*)data;
    unsigned rowSize = GetRowDataSize(width);

    // GetRowDataSize() returns CPU-side (source) data size, so need to convert for X8R8G8B8
    if (format_ == D3DFMT_X8R8G8B8)
        rowSize = rowSize / 3 * 4;

    // Perform conversion from RGB / RGBA as necessary
    switch (format_)
    {
    default:
        for (int k = 0; k < levelDepth; ++k)
        {
            for (int i = 0; i < height; ++i)
            {
                unsigned char
                    * dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch;
                memcpy(dest, src, rowSize);
                src += rowSize;
            }
        }
        break;

    case D3DFMT_X8R8G8B8:
        for (int k = 0; k < levelDepth; ++k)
        {
            for (int i = 0; i < height; ++i)
            {
                unsigned char
                    * dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch;
                for (int j = 0; j < width; ++j)
                {
                    *dest++ = src[2];
                    *dest++ = src[1];
                    *dest++ = src[0];
                    *dest++ = 255;
                    src += 3;
                }
            }
        }
        break;

    case D3DFMT_A8R8G8B8:
        for (int k = 0; k < levelDepth; ++k)
        {
            for (int i = 0; i < height; ++i)
            {
                unsigned char
                    * dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch;
                for (int j = 0; j < width; ++j)
                {
                    *dest++ = src[2];
                    *dest++ = src[1];
                    *dest++ = src[0];
                    *dest++ = src[3];
                    src += 4;
                }
            }
        }
        break;
    }

    ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level);
    return true;
}
Example #21
0
void GraphicsWorld::HandlePostRenderUpdate(StringHash /*eventType*/, VariantMap& /*eventData*/)
{
    URHO3D_PROFILE(GraphicsWorld_PostRenderUpdate);

    visibleEntities_.Clear();

    Urho3D::Renderer* renderer = GetSubsystem<Urho3D::Renderer>();
    Camera* cameraComp = renderer_->MainCameraComponent();

    if (IsActive() && renderer)
    {
        Urho3D::Camera* cam = cameraComp ? cameraComp->UrhoCamera() : nullptr;
        Urho3D::Viewport* vp = renderer->GetViewport(0);
        Urho3D::View* view = vp ? vp->GetView() : nullptr;
        if (view)
        {
            const Urho3D::PODVector<Urho3D::Drawable*>& geometries = view->GetGeometries();
            for (uint i = 0; i < geometries.Size(); ++i)
            {
                // Verify that the geometry is in main camera view, as also eg. shadow geometries get listed
                Urho3D::Drawable* dr = geometries[i];
                if (!dr || !dr->IsInView(cam))
                    continue;
                EntityWeakPtr ent(static_cast<Entity*>(dr->GetNode()->GetVar(entityLink).GetPtr()));
                if (!ent)
                    continue;
                
                visibleEntities_.Insert(ent);
            }
        }
    }

    // Perform visibility change tracking
    for (HashMap<EntityWeakPtr, bool>::Iterator i = visibilityTrackedEntities_.Begin(); i != visibilityTrackedEntities_.End();)
    {
        // Check whether entity has expired
        if (!i->first_)
            i = visibilityTrackedEntities_.Erase(i);
        else
        {
            bool current = visibleEntities_.Contains(i->first_);
            bool prev = i->second_;
            if (current != prev)
            {
                i->second_ = current;
                if (current)
                {
                    i->first_->EmitEnterView(cameraComp);
                    EntityEnterView.Emit(i->first_.Get());
                }
                else
                {
                    i->first_->EmitLeaveView(cameraComp);
                    EntityLeaveView.Emit(i->first_.Get());
                }
            }

            ++i;
        }
    }
}
Example #22
0
bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data)
{
    URHO3D_PROFILE(SetTextureData);

    if (!object_)
    {
        URHO3D_LOGERROR("No texture created, can not set data");
        return false;
    }

    if (!data)
    {
        URHO3D_LOGERROR("Null source for setting data");
        return false;
    }

    if (level >= levels_)
    {
        URHO3D_LOGERROR("Illegal mip level for setting data");
        return false;
    }

    int levelWidth = GetLevelWidth(level);
    int levelHeight = GetLevelHeight(level);
    if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0)
    {
        URHO3D_LOGERROR("Illegal dimensions for setting data");
        return false;
    }

    // If compressed, align the update region on a block
    if (IsCompressed())
    {
        x &= ~3;
        y &= ~3;
        width += 3;
        width &= 0xfffffffc;
        height += 3;
        height &= 0xfffffffc;
    }

    unsigned char* src = (unsigned char*)data;
    unsigned rowSize = GetRowDataSize(width);
    unsigned rowStart = GetRowDataSize(x);
    unsigned subResource = D3D11CalcSubresource(level, 0, levels_);

    if (usage_ == TEXTURE_DYNAMIC)
    {
        if (IsCompressed())
        {
            height = (height + 3) >> 2;
            y >>= 2;
        }

        D3D11_MAPPED_SUBRESOURCE mappedData;
        mappedData.pData = 0;

        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
            &mappedData);
        if (FAILED(hr) || !mappedData.pData)
        {
            URHO3D_LOGD3DERROR("Failed to map texture for update", hr);
            return false;
        }
        else
        {
            for (int row = 0; row < height; ++row)
                memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
        }
    }
    else
    {
Example #23
0
bool NamedPipe::Open(const String& pipeName, bool isServer)
{
#ifdef __EMSCRIPTEN__
    URHO3D_LOGERROR("Opening a named pipe not supported on Web platform");
    return false;
#else
    URHO3D_PROFILE(OpenNamedPipe);

    Close();

    isServer_ = false;

    String serverReadName = pipePath + pipeName + "SR";
    String clientReadName = pipePath + pipeName + "CR";

    // Make sure SIGPIPE is ignored and will not lead to process termination
    signal(SIGPIPE, SIG_IGN);

    if (isServer)
    {
        mkfifo(serverReadName.CString(), 0660);
        mkfifo(clientReadName.CString(), 0660);

        readHandle_ = open(serverReadName.CString(), O_RDONLY | O_NDELAY);
        writeHandle_ = open(clientReadName.CString(), O_WRONLY | O_NDELAY);

        if (readHandle_ == -1 && writeHandle_ == -1)
        {
            URHO3D_LOGERROR("Failed to create named pipe " + pipeName);
            SAFE_CLOSE(readHandle_);
            SAFE_CLOSE(writeHandle_);
            unlink(serverReadName.CString());
            unlink(clientReadName.CString());
            return false;
        }
        else
        {
            URHO3D_LOGDEBUG("Created named pipe " + pipeName);
            pipeName_ = pipeName;
            isServer_ = true;
            return true;
        }
    }
    else
    {
        readHandle_ = open(clientReadName.CString(), O_RDONLY | O_NDELAY);
        writeHandle_ = open(serverReadName.CString(), O_WRONLY | O_NDELAY);
        if (readHandle_ == -1 && writeHandle_ == -1)
        {
            URHO3D_LOGERROR("Failed to connect to named pipe " + pipeName);
            SAFE_CLOSE(readHandle_);
            SAFE_CLOSE(writeHandle_);
            return false;
        }
        else
        {
            URHO3D_LOGDEBUG("Connected to named pipe " + pipeName);
            pipeName_ = pipeName;
            return true;
        }
    }
#endif
}
Example #24
0
void Constraint::CreateConstraint()
{
    URHO3D_PROFILE(CreateConstraint);

    cachedWorldScale_ = node_->GetWorldScale();

    ReleaseConstraint();

    ownBody_ = GetComponent<RigidBody>();
    btRigidBody* ownBody = ownBody_ ? ownBody_->GetBody() : 0;
    btRigidBody* otherBody = otherBody_ ? otherBody_->GetBody() : 0;

    // If no physics world available now mark for retry later
    if (!physicsWorld_ || !ownBody)
    {
        retryCreation_ = true;
        return;
    }

    if (!otherBody)
        otherBody = &btTypedConstraint::getFixedBody();

    Vector3 ownBodyScaledPosition = position_ * cachedWorldScale_ - ownBody_->GetCenterOfMass();
    Vector3 otherBodyScaledPosition = otherBody_ ? otherPosition_ * otherBody_->GetNode()->GetWorldScale() -
                                                   otherBody_->GetCenterOfMass() : otherPosition_;

    switch (constraintType_)
    {
    case CONSTRAINT_POINT:
        {
            constraint_ = new btPoint2PointConstraint(*ownBody, *otherBody, ToBtVector3(ownBodyScaledPosition),
                ToBtVector3(otherBodyScaledPosition));
        }
        break;

    case CONSTRAINT_HINGE:
        {
            btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
            btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
            constraint_ = new btHingeConstraint(*ownBody, *otherBody, ownFrame, otherFrame);
        }
        break;

    case CONSTRAINT_SLIDER:
        {
            btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
            btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
            constraint_ = new btSliderConstraint(*ownBody, *otherBody, ownFrame, otherFrame, false);
        }
        break;

    case CONSTRAINT_CONETWIST:
        {
            btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
            btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
            constraint_ = new btConeTwistConstraint(*ownBody, *otherBody, ownFrame, otherFrame);
        }
        break;

    default:
        break;
    }

    if (constraint_)
    {
        constraint_->setUserConstraintPtr(this);
        constraint_->setEnabled(IsEnabledEffective());
        ownBody_->AddConstraint(this);
        if (otherBody_)
            otherBody_->AddConstraint(this);

        ApplyLimits();

        physicsWorld_->GetWorld()->addConstraint(constraint_, disableCollision_);
    }

    recreateConstraint_ = false;
    framesDirty_ = false;
    retryCreation_ = false;
}
Example #25
0
bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data)
{
    URHO3D_PROFILE(SetTextureData);

    if (!object_ || !graphics_)
    {
        URHO3D_LOGERROR("No texture created, can not set data");
        return false;
    }

    if (!data)
    {
        URHO3D_LOGERROR("Null source for setting data");
        return false;
    }

    if (level >= levels_)
    {
        URHO3D_LOGERROR("Illegal mip level for setting data");
        return false;
    }

    if (graphics_->IsDeviceLost())
    {
        URHO3D_LOGWARNING("Texture data assignment while device is lost");
        dataPending_ = true;
        return true;
    }

    if (IsCompressed())
    {
        x &= ~3;
        y &= ~3;
    }

    int levelWidth = GetLevelWidth(level);
    int levelHeight = GetLevelHeight(level);
    if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0)
    {
        URHO3D_LOGERROR("Illegal dimensions for setting data");
        return false;
    }

    graphics_->SetTextureForUpdate(this);

    bool wholeLevel = x == 0 && y == 0 && width == levelWidth && height == levelHeight;
    unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;

    if (!IsCompressed())
    {
        if (wholeLevel)
            glTexImage2D(target_, level, format, width, height, 0, GetExternalFormat(format_), GetDataType(format_), data);
        else
            glTexSubImage2D(target_, level, x, y, width, height, GetExternalFormat(format_), GetDataType(format_), data);
    }
    else
    {
        if (wholeLevel)
            glCompressedTexImage2D(target_, level, format, width, height, 0, GetDataSize(width, height), data);
        else
            glCompressedTexSubImage2D(target_, level, x, y, width, height, format, GetDataSize(width, height), data);
    }

    graphics_->SetTexture(0, 0);
    return true;
}
Example #26
0
void Graphics::PrecacheShaders(Deserializer& source)
{
    URHO3D_PROFILE(PrecacheShaders);

    ShaderPrecache::LoadShaders(this, source);
}