MonoObject* ScriptSerializableUtility::internal_Create(MonoReflectionType* reflType)
	{
		if (reflType == nullptr)
			return nullptr;

		::MonoClass* monoClass = MonoUtil::getClass(reflType);
		MonoClass* engineClass = MonoManager::instance().findClass(monoClass);

		SPtr<ManagedSerializableTypeInfo> typeInfo = ScriptAssemblyManager::instance().getTypeInfo(engineClass);
		if (typeInfo == nullptr)
		{
			LOGWRN("Cannot create an instance of type \"" + 
				engineClass->getFullName() + "\", it is not marked as serializable.");
			return nullptr;
		}
			
		SPtr<ManagedSerializableFieldData> data = ManagedSerializableFieldData::createDefault(typeInfo);
		MemorySerializer ms;

		// Note: This code unnecessarily encodes to binary and decodes from it. I could have added a specialized create method that does it directly,
		// but didn't feel the extra code was justified.
		UINT32 size = 0;
		UINT8* encodedData = ms.encode(data.get(), size);
		SPtr<ManagedSerializableFieldData> createdData = std::static_pointer_cast<ManagedSerializableFieldData>(ms.decode(encodedData, size));
		createdData->deserialize();

		return createdData->getValueBoxed(typeInfo);
	}
	void GUICanvas::drawPolyLine(const Vector<Vector2I>& vertices, const Color& color)
	{
		if(vertices.size() < 2)
		{
			LOGWRN("Invalid number of vertices. Ignoring call.");
			return;
		}

		mElements.push_back(CanvasElement());
		CanvasElement& element = mElements.back();

		element.type = CanvasElementType::Line;
		element.color = color;
		element.dataId = (UINT32)mTriangleElementData.size();
		element.vertexStart = (UINT32)mVertexData.size();
		element.numVertices = (UINT32)vertices.size();

		mTriangleElementData.push_back(TriangleElementData());
		TriangleElementData& elemData = mTriangleElementData.back();
		elemData.matInfo.groupId = 0;
		elemData.matInfo.tint = color;

		for (auto& vertex : vertices)
		{
			Vector2 point = Vector2((float)vertex.x, (float)vertex.y);
			point += Vector2(0.5f, 0.5f); // Offset to the middle of the pixel

			mVertexData.push_back(point);
		}

		mForceTriangleBuild = true;
		_markContentAsDirty();
	}
	void GUICanvas::drawTriangleStrip(const Vector<Vector2I>& vertices, const Color& color)
	{
		if (vertices.size() < 3)
		{
			LOGWRN("Invalid number of vertices. Ignoring call.");
			return;
		}

		mElements.push_back(CanvasElement());
		CanvasElement& element = mElements.back();

		element.type = CanvasElementType::Triangle;
		element.color = color;
		element.dataId = (UINT32)mTriangleElementData.size();
		element.vertexStart = (UINT32)mVertexData.size();
		element.numVertices = (UINT32)(vertices.size() - 2) * 3;

		// Convert strip to list
		for(UINT32 i = 2; i < (UINT32)vertices.size(); i++)
		{
			mVertexData.push_back(Vector2((float)vertices[i - 2].x, (float)vertices[i - 2].y));
			mVertexData.push_back(Vector2((float)vertices[i - 1].x, (float)vertices[i - 1].y));
			mVertexData.push_back(Vector2((float)vertices[i - 0].x, (float)vertices[i - 0].y));
		}

		mTriangleElementData.push_back(TriangleElementData());
		TriangleElementData& elemData = mTriangleElementData.back();
		elemData.matInfo.groupId = 0;
		elemData.matInfo.tint = color;
		elemData.matInfo.type = SpriteMaterial::ImageAlpha;

		mForceTriangleBuild = true;
		_markContentAsDirty();
	}
void PhysXRigidbody::setFlags(Flag flags)
{
    bool ccdEnabledOld = mInternal->getRigidBodyFlags() & PxRigidBodyFlag::eENABLE_CCD;
    bool ccdEnabledNew = ((UINT32)flags & (UINT32)Flag::CCD) != 0;

    if(ccdEnabledOld != ccdEnabledNew)
    {
        if(ccdEnabledNew)
        {
            if (!gPhysics().hasFlag(PhysicsFlag::CCD_Enable))
                LOGWRN("Enabling CCD on a Rigidbody but CCD is not enabled globally.");
        }

        mInternal->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, ccdEnabledNew);

        // Enable/disable CCD on shapes so the filter can handle them properly
        UINT32 numShapes = mInternal->getNbShapes();
        PxShape** shapes = (PxShape**)bs_stack_alloc(sizeof(PxShape*) * numShapes);

        mInternal->getShapes(shapes, sizeof(PxShape*) * numShapes);

        for (UINT32 i = 0; i < numShapes; i++)
        {
            Collider* collider = (Collider*)shapes[i]->userData;
            collider->_getInternal()->_setCCD(ccdEnabledNew);
        }
    }

    Rigidbody::setFlags(flags);
}
	void GUICanvas::drawPolyLine(const Vector<Vector2I>& vertices, const Color& color)
	{
		if(vertices.size() < 2)
		{
			LOGWRN("Invalid number of vertices. Ignoring call.");
			return;
		}

		mElements.push_back(CanvasElement());
		CanvasElement& element = mElements.back();

		element.type = CanvasElementType::Line;
		element.color = color;
		element.dataId = (UINT32)mTriangleElementData.size();
		element.vertexStart = (UINT32)mVertexData.size();
		element.numVertices = (UINT32)vertices.size();

		// TODO - Add actual triangle line data here
		for (auto& vertex : vertices)
			mVertexData.push_back(Vector2((float)vertex.x, (float)vertex.y));

		mTriangleElementData.push_back(TriangleElementData());
		TriangleElementData& elemData = mTriangleElementData.back();
		elemData.matInfo.groupId = 0;
		elemData.matInfo.tint = color;
		elemData.matInfo.type = SpriteMaterial::ImageAlpha; // TODO - Use line material here

		mForceTriangleBuild = true;
		_markContentAsDirty();
	}
	D3DDECLTYPE D3D9Mappings::get(VertexElementType vType)
	{
		switch (vType)
		{
		case VET_COLOR:
		case VET_COLOR_ABGR:
		case VET_COLOR_ARGB:
			return D3DDECLTYPE_D3DCOLOR;
		case VET_FLOAT1:
			return D3DDECLTYPE_FLOAT1;
		case VET_FLOAT2:
			return D3DDECLTYPE_FLOAT2;
		case VET_FLOAT3:
			return D3DDECLTYPE_FLOAT3;
		case VET_FLOAT4:
			return D3DDECLTYPE_FLOAT4;
        case VET_SHORT2:
			return D3DDECLTYPE_SHORT2;
        case VET_SHORT4:
			return D3DDECLTYPE_SHORT4;
        case VET_UBYTE4:
            return D3DDECLTYPE_UBYTE4;
		default:
			LOGWRN("Invalid vertex element type for DX9.");
			break;
		}

		return D3DDECLTYPE_FLOAT3;
	}
	void GLGpuBufferCore::initialize()
	{
		LOGWRN("Generic buffers are not supported in OpenGL. Creating a dummy buffer. All operations on it will either be no-op or return a nullptr.");

		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuBuffer);
		GpuBufferCore::initialize();
	}
	void GUICanvas::drawTriangleList(const Vector<Vector2I>& vertices, const Color& color)
	{
		if (vertices.size() < 3 || vertices.size() % 3 != 0)
		{
			LOGWRN("Invalid number of vertices. Ignoring call.");
			return;
		}

		mElements.push_back(CanvasElement());
		CanvasElement& element = mElements.back();

		element.type = CanvasElementType::Triangle;
		element.color = color;
		element.dataId = (UINT32)mTriangleElementData.size();
		element.vertexStart = (UINT32)mVertexData.size();
		element.numVertices = (UINT32)vertices.size();

		for (auto& vertex : vertices)
			mVertexData.push_back(Vector2((float)vertex.x, (float)vertex.y));

		mTriangleElementData.push_back(TriangleElementData());
		TriangleElementData& elemData = mTriangleElementData.back();
		elemData.matInfo.groupId = 0;
		elemData.matInfo.tint = color;

		mForceTriangleBuild = true;
		_markContentAsDirty();
	}
Exemple #9
0
	void TGpuParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
	{
		if (mParent == nullptr)
			return;

		GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot);
		if (paramBlock == nullptr)
			return;

		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);

#if BS_DEBUG_MODE
		if (sizeBytes > elementSizeBytes)
		{
			LOGWRN("Provided element size larger than maximum element size. Maximum size: " +
				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
		}

		if (arrayIdx >= mParamDesc->arraySize)
		{
			BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
				toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
		}
#endif
		sizeBytes = std::min(elementSizeBytes, sizeBytes);

		paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
	}
	void D3D11RenderAPI::applyInputLayout()
	{
		if(mActiveVertexDeclaration == nullptr)
		{
			LOGWRN("Cannot apply input layout without a vertex declaration. Set vertex declaration before calling this method.");
			return;
		}

		if(mActiveVertexShader == nullptr)
		{
			LOGWRN("Cannot apply input layout without a vertex shader. Set vertex shader before calling this method.");
			return;
		}

		ID3D11InputLayout* ia = mIAManager->retrieveInputLayout(mActiveVertexShader->getInputDeclaration(), mActiveVertexDeclaration, *mActiveVertexShader);

		mDevice->getImmediateContext()->IASetInputLayout(ia);
	}
void PhysXRigidbody::setInertiaTensor(const Vector3& tensor)
{
    if (((UINT32)mFlags & (UINT32)Flag::AutoTensors) != 0)
    {
        LOGWRN("Attempting to set Rigidbody inertia tensor, but it has automatic tensor calculation turned on.");
        return;
    }

    mInternal->setMassSpaceInertiaTensor(toPxVector(tensor));
}
void PhysXRigidbody::setCenterOfMass(const Vector3& position, const Quaternion& rotation)
{
    if (((UINT32)mFlags & (UINT32)Flag::AutoTensors) != 0)
    {
        LOGWRN("Attempting to set Rigidbody center of mass, but it has automatic tensor calculation turned on.");
        return;
    }

    mInternal->setCMassLocalPose(toPxTransform(position, rotation));
}
	bool ScriptSceneObject::checkIfDestroyed(ScriptSceneObject* nativeInstance)
	{
		if (nativeInstance->mSceneObject.isDestroyed())
		{
			LOGWRN("Trying to access a destroyed SceneObject with instance ID: " + toString(nativeInstance->mSceneObject.getInstanceId()));
			return true;
		}

		return false;
	}
void PhysXRigidbody::setMass(float mass)
{
    if(((UINT32)mFlags & (UINT32)Flag::AutoMass) != 0)
    {
        LOGWRN("Attempting to set Rigidbody mass, but it has automatic mass calculation turned on.");
        return;
    }

    mInternal->setMass(mass);
}
Exemple #15
0
	const GUIElementStyle* GUISkin::getStyle(const String& guiElemType) const
	{
		auto iterFind = mStyles.find(guiElemType);

		if(iterFind != mStyles.end())
			return &iterFind->second;

		LOGWRN("Cannot find GUI style with name: " + guiElemType + ". Returning default style.");

		return &DefaultStyle;
	}
	void D3D11RenderAPI::dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY, UINT32 numGroupsZ)
	{
		mDevice->getImmediateContext()->Dispatch(numGroupsX, numGroupsY, numGroupsZ);

#if BS_DEBUG_MODE
		if (mDevice->hasError())
			LOGWRN(mDevice->getErrorDescription());
#endif

		BS_INC_RENDER_STAT(NumComputeCalls);
	}
	void FMODAudio::setActiveDevice(const AudioDevice& device)
	{
		for(UINT32 i = 0; i < (UINT32)mAllDevices.size(); i++)
		{
			if(device.name == mAllDevices[i].name)
			{
				mFMOD->setDriver(i);
				return;
			}
		}

		LOGWRN("Failed changing audio device to: " + toString(device.name));
	}
	void HandleManager::updateInput(const SPtr<Camera>& camera, const Vector2I& inputPos, const Vector2I& inputDelta)
	{
		if(!mInputStarted)
		{
			LOGWRN("Updating handle input without calling beginInput() first. Input won't be processed.");
			return;
		}

		if (mSettings != nullptr && mSettingsHash != mSettings->getHash())
			updateFromEditorSettings();

		mSliderManager->update(camera, inputPos, inputDelta);
	}
	ManagedResource::ManagedResource(MonoObject* managedInstance)
		:Resource(false), mManagedInstance(nullptr)
	{
		SPtr<ManagedResourceMetaData> metaData = bs_shared_ptr_new<ManagedResourceMetaData>();
		mMetaData = metaData;

		MonoUtil::getClassName(managedInstance, metaData->typeNamespace, metaData->typeName);

		MonoClass* managedClass = MonoManager::instance().findClass(metaData->typeNamespace, metaData->typeName);
		if (managedClass == nullptr)
		{
			LOGWRN("Cannot create managed component: " + metaData->typeNamespace + "." + metaData->typeName + " because that type doesn't exist.");
			return;
		}
	}
Exemple #20
0
	FileEncoder::FileEncoder(const Path& fileLocation)
		:mWriteBuffer(nullptr)
	{
		mWriteBuffer = (UINT8*)bs_alloc(WRITE_BUFFER_SIZE);

		Path parentDir = fileLocation.getDirectory();
		if (!FileSystem::exists(parentDir))
			FileSystem::createDir(parentDir);

		mOutputStream.open(fileLocation.toPlatformString().c_str(), std::ios::out | std::ios::binary);
		if (mOutputStream.fail())
		{
			LOGWRN("Failed to save file: \"" + fileLocation.toString() + "\". Error: " + strerror(errno) + ".");
		}
	}
	void CRigidbody::checkForNestedRigibody()
	{
		HSceneObject currentSO = SO()->getParent();

		while(currentSO != nullptr)
		{
			if(currentSO->hasComponent<CRigidbody>())
			{
				LOGWRN("Nested Rigidbodies detected. This will result in inconsistent transformations. To parent one " \
					"Rigidbody to another move its colliders to the new parent, but remove the Rigidbody component.");
				return;
			}

			currentSO = currentSO->getParent();
		}
	}
Exemple #22
0
	void ObjectRenderer::initElement(RendererObject& owner, BeastRenderableElement& element)
	{
		SPtr<Shader> shader = element.material->getShader();
		if (shader == nullptr)
		{
			element.perCameraBindingIdx = -1;

			LOGWRN("Missing shader on material.");
			return;
		}

		// Note: Perhaps perform buffer validation to ensure expected buffer has the same size and layout as the provided
		// buffer, and show a warning otherwise. But this is perhaps better handled on a higher level.
		const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlockDescs = shader->getParamBlocks();

		for (auto& paramBlockDesc : paramBlockDescs)
		{
			if (paramBlockDesc.second.rendererSemantic == RBS_PerFrame)
				element.params->setParamBlockBuffer(paramBlockDesc.second.name, mPerFrameParamBuffer, true);
			else if (paramBlockDesc.second.rendererSemantic == RBS_PerObject)
			{
				element.params->setParamBlockBuffer(paramBlockDesc.second.name,
													owner.perObjectParamBuffer, true);
			}
			else if (paramBlockDesc.second.rendererSemantic == RBS_PerCall)
			{
				element.params->setParamBlockBuffer(paramBlockDesc.second.name,
													owner.perCallParamBuffer, true);
			}
		}

		const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferDescs = shader->getBufferParams();
		String boneMatricesParamName;

		for(auto& entry : bufferDescs)
		{
			if (entry.second.rendererSemantic == RPS_BoneMatrices)
				boneMatricesParamName = entry.second.name;
		}
		
		if (!boneMatricesParamName.empty())
		{
			MaterialParamBuffer boneMatricesParam = element.material->getParamBuffer(boneMatricesParamName);
			boneMatricesParam.set(element.boneMatrixBuffer);
		}
	}
Exemple #23
0
	void TMaterialParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
	{
		if (mMaterial == nullptr)
			return;

		if (arrayIdx >= mArraySize)
		{
			LOGWRN("Array index out of range. Provided index was " + toString(arrayIdx) +
				" but array length is " + toString(mArraySize));
			return;
		}

		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);

		params->setStructData(*data, value, sizeBytes, arrayIdx);
		mMaterial->_markCoreDirty();
	}
	MonoObject* ScriptSceneObject::internal_getChild(ScriptSceneObject* nativeInstance, UINT32 idx)
	{
		if (checkIfDestroyed(nativeInstance))
			return nullptr;

		UINT32 numChildren = nativeInstance->mSceneObject->getNumChildren();
		if(idx >= numChildren)
		{
			LOGWRN("Attempting to access an out of range SceneObject child. Provided index: \"" + toString(idx)
				+ "\". Valid range: [0 .. " + toString(numChildren) + ")");
			return nullptr;
		}

		HSceneObject childSO = nativeInstance->mSceneObject->getChild(idx);
		ScriptSceneObject* childScriptSO = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(childSO);

		return childScriptSO->getManagedInstance();
	}
	void ScriptSerializableProperty::internal_CreateInstance(MonoObject* instance, MonoReflectionType* reflType)
	{
		if (reflType == nullptr)
			return;

		::MonoClass* monoClass = MonoUtil::getClass(reflType);
		MonoClass* engineClass = MonoManager::instance().findClass(monoClass);

		SPtr<ManagedSerializableTypeInfo> typeInfo = ScriptAssemblyManager::instance().getTypeInfo(engineClass);
		if (typeInfo == nullptr)
		{
			LOGWRN("Cannot create an instance of type \"" +
				engineClass->getFullName() + "\", it is not marked as serializable.");
			return;
		}

		new (bs_alloc<ScriptSerializableProperty>()) ScriptSerializableProperty(instance, typeInfo);
	}
Exemple #26
0
int SThread::join()
{
	SMutex::Autolock _l(mLock);

	if (mThread == getThreadId()) {
		LOGWRN(
	        "Thread (this=%p): don't call join() from this "
			"Thread object's thread. It's a guaranteed deadlock!",
			this);

		return SMP_WOULD_BLOCK;
	}

	while (mRunning == true) {
		mThreadExitedCondition.wait(mLock);
	}

	return mStatus;
}
	void MultiRenderTextureCore::initialize()
	{
		RenderTargetCore::initialize();

		mColorSurfaces.resize(BS_MAX_MULTIPLE_RENDER_TARGETS);

		for (size_t i = 0; i < mDesc.colorSurfaces.size(); i++)
		{
			if (mDesc.colorSurfaces[i].texture != nullptr)
			{
				if (i >= BS_MAX_MULTIPLE_RENDER_TARGETS)
				{
					LOGWRN("Render texture index is larger than the maximum number of supported render targets. Index: " + toString((int)i) +
						". Max. number of render targets: " + toString(BS_MAX_MULTIPLE_RENDER_TARGETS));

					continue;
				}

				SPtr<TextureCore> texture = mDesc.colorSurfaces[i].texture;

				if (texture->getProperties().getUsage() != TU_RENDERTARGET)
					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");

				mColorSurfaces[i] = TextureCore::requestView(texture, mDesc.colorSurfaces[i].mipLevel, 1,
					mDesc.colorSurfaces[i].face, mDesc.colorSurfaces[i].numFaces, GVU_RENDERTARGET);
			}
		}

		if (mDesc.depthStencilSurface.texture != nullptr)
		{
			SPtr<TextureCore> texture = mDesc.depthStencilSurface.texture;

			if (texture->getProperties().getUsage() != TU_DEPTHSTENCIL)
				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");

			mDepthStencilSurface = TextureCore::requestView(texture, mDesc.depthStencilSurface.mipLevel, 1,
				mDesc.depthStencilSurface.face, 0, GVU_DEPTHSTENCIL);
		}

		throwIfBuffersDontMatch();
	}
	void OAAudioClip::getSamples(UINT8* samples, UINT32 offset, UINT32 count) const
	{
		Lock lock(mMutex);

		// Try to read from normal stream, and if that fails read from in-memory stream if it exists
		if (mStreamData != nullptr)
		{
			if (mNeedsDecompression)
			{
				mVorbisReader.seek(offset);
				mVorbisReader.read(samples, count);
			}
			else
			{
				UINT32 bytesPerSample = mDesc.bitDepth / 8;
				UINT32 size = count * bytesPerSample;
				UINT32 streamOffset = mStreamOffset + offset * bytesPerSample;

				mStreamData->seek(streamOffset);
				mStreamData->read(samples, size);
			}

			return;
		}

		if (mSourceStreamData != nullptr)
		{
			assert(!mNeedsDecompression); // Normal stream must exist if decompressing

			UINT32 bytesPerSample = mDesc.bitDepth / 8;
			UINT32 size = count * bytesPerSample;
			UINT32 streamOffset = offset * bytesPerSample;

			mSourceStreamData->seek(streamOffset);
			mSourceStreamData->read(samples, size);
			return;
		}

		LOGWRN("Attempting to read samples while sample data is not available.");
	}
	void D3D11RenderAPI::draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount)
	{
		THROW_IF_NOT_CORE_THREAD;

		applyInputLayout();

		if(instanceCount <= 1)
			mDevice->getImmediateContext()->Draw(vertexCount, vertexOffset);
		else
			mDevice->getImmediateContext()->DrawInstanced(vertexCount, instanceCount, vertexOffset, 0);

#if BS_DEBUG_MODE
		if(mDevice->hasError())
			LOGWRN(mDevice->getErrorDescription());
#endif

		UINT32 primCount = vertexCountToPrimCount(mActiveDrawOp, vertexCount);

		BS_INC_RENDER_STAT(NumDrawCalls);
		BS_ADD_RENDER_STAT(NumVertices, vertexCount);
		BS_ADD_RENDER_STAT(NumPrimitives, primCount);
	}
	void ColorGradient::setKeys(const Vector<ColorGradientKey>& keys)
	{
#if BS_DEBUG_MODE
		// Ensure keys are sorted
		if(!keys.empty())
		{
			float time = keys[0].time;
			for (UINT32 i = 1; i < (UINT32)keys.size(); i++)
			{
				assert(keys[i].time >= time);
				time = keys[i].time;
			}
		}
#endif

		if(keys.size() > MAX_KEYS)
		{
			LOGWRN("Number of keys in ColorGradient exceeds the support number (" + 
				toString(MAX_KEYS) + "). Keys will be ignored.");
		}

		if(!keys.empty())
			mDuration = keys.back().time;
		else
			mDuration = 0.0f;


		mNumKeys = 0;
		for(auto& key : keys)
		{
			if(mNumKeys >= MAX_KEYS)
				break;

			mColors[mNumKeys] = key.color.getAsRGBA();
			mTimes[mNumKeys] = Bitwise::unormToUint<16>(key.time / mDuration);

			mNumKeys++;
		}
	}