// ---------------------------------------------------------------------------- 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(); }
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); } }
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(); }
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; } }
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; } }
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); }
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; }
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; }
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_); } }
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(); } }
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; } }
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; } }
/// 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); } }
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(); }
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); } }
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); }
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(); }
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; }
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; } } }
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 {
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 }
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; }
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; }
void Graphics::PrecacheShaders(Deserializer& source) { URHO3D_PROFILE(PrecacheShaders); ShaderPrecache::LoadShaders(this, source); }