Beispiel #1
0
void Camera3::teleport()
{
	Vector3 p1Min = minPos(Vector3(-435.088, 10, 50.0353), 10, 15, 10);
	Vector3 p1Max = maxPos(Vector3(-435.088, 10, 50.0353), 10, 15, 10);

	Vector3 p2Min = minPos(Vector3(0,10,40), 10, 15, 10);
	Vector3 p2Max = maxPos(Vector3(0,10, 40), 10, 15, 10);

	if (position.x > p1Min.x && position.y > p1Min.y && position.z > p1Min.z
		&& position.x < p1Max.x && position.y  < p1Max.y && position.z < p1Max.z)
	{
		position.x = 0;
		position.y = 10; 
		position.z = 0;
		inBase = true;
	}

	if (position.x > p2Min.x && position.y > p2Min.y && position.z > p2Min.z
		&& position.x < p2Max.x && position.y < p2Max.y && position.z < p2Max.z)
	{
		position.x = -400; 
		position.y = 10; 
		position.z = 50;
		inBase = false;
	}
}
Beispiel #2
0
void Camera3::Init(const Vector3& pos, const Vector3& target, const Vector3& up)
{
	maxCameraX = 49.99f;
	cameraSpeed = 2.5f;

	this->position = defaultPosition = pos;
	this->target = defaultTarget = target;
	Vector3 view = (target - position).Normalized();
	Vector3 right = view.Cross(up);
	right.y = 0;
	right.Normalize();
	this->up = defaultUp = right.Cross(view).Normalized();
	directionRotation = Vector3(0, -180, 0);
	gunRecoil = Vector3(0,0,0);
	camerarotation = Vector3(0,0,0);
	speed = 100;
	location = (0,0,0);
	location2 = (0, 0, 0);
	//direction2 = (0, 0, 0);
	//mouseControl = true;
	//delay = 0;
	delay2 = 0;
	//cd = 10;
	cameraStore = 0;
	cRecoilCd = 0;
	stamina = 300;
	staminaDelay = 0;
	glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

	//for hitboxes
	minVectors.push_back(minPos(Vector3(-338, 0, 38), 20, 120, 90));
	minVectors.push_back(minPos(Vector3(-460, 0, 38), 20, 120, 90));
	minVectors.push_back(minPos(Vector3(-400, 0, 73), 120, 120, 20));
	minVectors.push_back(minPos(Vector3(-360, 0, 0), 70, 100, 30));
	minVectors.push_back(minPos(Vector3(-435, 0, 0), 58, 120, 20));

	maxVectors.push_back(maxPos(Vector3(-338, 0, 38), 20, 120, 90));
	maxVectors.push_back(maxPos(Vector3(-460, 0, 38), 20, 120, 90));
	maxVectors.push_back(maxPos(Vector3(-400, 0, 73), 120, 120, 20));
	maxVectors.push_back(maxPos(Vector3(-360, 0, 0), 70, 100, 30));
	maxVectors.push_back(maxPos(Vector3(-435, 0, 0), 52, 120, 20));	

	//Minerals hitbox
	MineralVectors.push_back(Vector3(-113, 5, -66));
	MineralVectors.push_back(Vector3(-126, 5, -394));
	MineralVectors.push_back(Vector3(590, 5, -395));
	MineralVectors.push_back(Vector3(270, 5, 201));
	MineralVectors.push_back(Vector3(223, 5, 934));
	MineralVectors.push_back(Vector3(84, 5, 522));
	MineralVectors.push_back(Vector3(-516, 5, 809));
	MineralVectors.push_back(Vector3(361, 5, 772));
	MineralVectors.push_back(Vector3(-643, 5, 825));
	MineralVectors.push_back(Vector3(-415, 5, 174));

}
int minPos(int a, int b, int node = 1, int left = 0, int right = maxn - 1) {
	if (left > b || right < a)
		return -1;
	if (left >= a && right <= b)
		return tminPos[node];
	int mid = (left + right) >> 1;
	int p1 = minPos(a, b, node * 2, left, mid);
	int p2 = minPos(a, b, node * 2 + 1, mid + 1, right);
	if (p1 == -1)
		return p2;
	if (p2 == -1)
		return p1;
	return t[tminPos[p1]] <= t[tminPos[p2]] ? p1 : p2;
}
Beispiel #4
0
float3 CUnitTracker::CalcExtentsPos() const
{
    float3 minPos(+1e9f, +1e9f, +1e9f);
    float3 maxPos(-1e9f, -1e9f, -1e9f);
    std::set<int>::const_iterator it;
    for (it = trackGroup.begin(); it != trackGroup.end(); ++it) {
        const float3& p = unitHandler->GetUnitUnsafe(*it)->drawPos;

        if (p.x < minPos.x) {
            minPos.x = p.x;
        }
        if (p.y < minPos.y) {
            minPos.y = p.y;
        }
        if (p.z < minPos.z) {
            minPos.z = p.z;
        }
        if (p.x > maxPos.x) {
            maxPos.x = p.x;
        }
        if (p.y > maxPos.y) {
            maxPos.y = p.y;
        }
        if (p.z > maxPos.z) {
            maxPos.z = p.z;
        }
    }
    return (minPos + maxPos) / 2.0f;
}
void calcBoundingVolume(const VertList& p_Vertices, std::array<DirectX::XMFLOAT3, 8>& p_Volume)
{
	DirectX::XMFLOAT3 minPos(
		std::numeric_limits<float>::max(),
		std::numeric_limits<float>::max(),
		std::numeric_limits<float>::max());
	DirectX::XMFLOAT3 maxPos(
		std::numeric_limits<float>::min(),
		std::numeric_limits<float>::min(),
		std::numeric_limits<float>::min());

	for (const auto& vert : p_Vertices)
	{
		if (vert.m_Position.x < minPos.x) minPos.x = vert.m_Position.x;
		if (vert.m_Position.x > maxPos.x) maxPos.x = vert.m_Position.x;
		if (vert.m_Position.y < minPos.y) minPos.y = vert.m_Position.y;
		if (vert.m_Position.y > maxPos.y) maxPos.y = vert.m_Position.y;
		if (vert.m_Position.z < minPos.z) minPos.z = vert.m_Position.z;
		if (vert.m_Position.z > maxPos.z) maxPos.z = vert.m_Position.z;
	}

	p_Volume[0] = DirectX::XMFLOAT3(minPos.x, minPos.y, minPos.z);
	p_Volume[1] = DirectX::XMFLOAT3(minPos.x, minPos.y, maxPos.z);
	p_Volume[2] = DirectX::XMFLOAT3(minPos.x, maxPos.y, minPos.z);
	p_Volume[3] = DirectX::XMFLOAT3(minPos.x, maxPos.y, maxPos.z);
	p_Volume[4] = DirectX::XMFLOAT3(maxPos.x, minPos.y, minPos.z);
	p_Volume[5] = DirectX::XMFLOAT3(maxPos.x, minPos.y, maxPos.z);
	p_Volume[6] = DirectX::XMFLOAT3(maxPos.x, maxPos.y, minPos.z);
	p_Volume[7] = DirectX::XMFLOAT3(maxPos.x, maxPos.y, maxPos.z);
}
void MeshRenderProcessorGLSR::centerViewOnGeometry() {
    if (!inport_.hasData()) return;

    vec3 worldMin(std::numeric_limits<float>::max());
    vec3 worldMax(std::numeric_limits<float>::lowest());

    for (const auto& mesh : inport_) {
        vec3 minPos(std::numeric_limits<float>::max());
        vec3 maxPos(std::numeric_limits<float>::lowest());
        for (auto buff : mesh->getBuffers()) {
            if (buff.first == BufferType::PositionAttrib) {
                const Vec3BufferRAM* posbuff =
                    dynamic_cast<const Vec3BufferRAM*>(buff.second->getRepresentation<BufferRAM>());

                if (posbuff) {
                    const std::vector<vec3>* pos = posbuff->getDataContainer();
                    for (const auto& p : *pos) {
                        minPos = glm::min(minPos, p);
                        maxPos = glm::max(maxPos, p);
                    }
                }
            }
        }

        mat4 trans = mesh->getCoordinateTransformer().getDataToWorldMatrix();

        worldMin = glm::min(worldMin, (trans * vec4(minPos, 1.f)).xyz());
        worldMax = glm::max(worldMax, (trans * vec4(maxPos, 1.f)).xyz());
    }
    camera_.setLook(camera_.getLookFrom(), 0.5f * (worldMin + worldMax), camera_.getLookUp());
}
Beispiel #7
0
UmbralModelPtr CUmbralMap::CreateBgPartObject(const MapLayoutPtr& mapLayout, const std::shared_ptr<CMapLayout::BGPARTS_BASE_OBJECT_NODE>& node)
{
	UmbralModelPtr result;

	auto modelResource = CResourceManager::GetInstance().GetResource(node->resourceName);
	assert(modelResource);
	if(!modelResource) return result;

	auto modelChunk = modelResource->SelectNode<CModelChunk>();
	assert(modelChunk);
	if(!modelChunk) return result;

	CVector3 minPos(node->minX, node->minY, node->minZ);
	CVector3 maxPos(node->maxX, node->maxY, node->maxZ);

	CVector3 bgPartSize = (maxPos - minPos) / 2;
	CVector3 bgPartPos = (maxPos + minPos) / 2;

	result = std::make_shared<CUmbralModel>(modelChunk);
	result->SetPosition(bgPartPos);
	result->SetScale(bgPartSize);
				
	result->TraverseNodes(
		[&] (const Palleon::SceneNodePtr& node)
		{
			if(auto mesh = std::dynamic_pointer_cast<CUmbralMesh>(node))
			{
				mesh->RebuildIndices();
			}
			return true;
		}
	);

	return result;
}
Beispiel #8
0
RemoteInformation deserializeDataSourceData( const ::zeq::Event& event )
{
    if( event.getType() != EVENT_DATASOURCE_DATA )
        return RemoteInformation();

    auto data = GetVolumeInformation( event.getData( ));
    RemoteInformation info;
    livre::VolumeInformation& vi = info.second;

    info.first.low() = data->eventLow();
    info.first.high() = data->eventHigh();
    vi.isBigEndian = data->isBigEndian();
    vi.compCount = data->compCount();
    vi.dataType = DataType( data->dataType( ));
    vi.overlap = _deserializeVector3< unsigned >( data->overlap( ));
    vi.maximumBlockSize = _deserializeVector3< unsigned >(
                                 data->maximumBlockSize( ));
    vi.minPos = _deserializeVector3< float >( data->minPos( ));
    vi.maxPos = _deserializeVector3< float >( data->maxPos( ));
    vi.voxels = _deserializeVector3< unsigned >( data->voxels( ));
    vi.worldSize = _deserializeVector3< float >( data->worldSize( ));
    vi.boundingBox.getMin() = _deserializeVector3< float >(
                                     data->boundingBoxMin( ));
    vi.boundingBox.getMax() = _deserializeVector3< float >(
                                     data->boundingBoxMax( ));
    vi.worldSpacePerVoxel = data->worldSpacePerVoxel();

    const Vector3ui& blockSize = vi.maximumBlockSize - vi.overlap * 2;
    Vector3ui blocksSize = vi.voxels / blockSize;
    blocksSize = blocksSize / ( 1u << data->depth( ));

    vi.rootNode = RootNode( data->depth(), blocksSize );
    return info;
}
Vec2 TouchTracker::Calibrator::getBinPosition(Vec2 pIn) const
{
	// Soundplane A
	static MLRange binRangeX(2.0, 61.0, 0., mWidth);
	static MLRange binRangeY(0.5, 6.5, 0., mHeight);
	Vec2 minPos(2.5, 0.5);
	Vec2 maxPos(mWidth - 2.5f, mHeight - 0.5f);
	Vec2 pos(binRangeX(pIn.x()), binRangeY(pIn.y()));
	return vclamp(pos, minPos, maxPos);
}
Beispiel #10
0
void GdsNode::CreateOctree()
{
	RENDER_OBJECT_CONTAINER::iterator it = m_list_RenderObject.begin();
	for ( ; it != m_list_RenderObject.end() ; ++it )
	{
		VOID* pVB;
		GdsRenderObject* rendertoken = it->first;
		LPDIRECT3DVERTEXBUFFER9 vb = rendertoken->GetVertexBuffer();
		if (  SUCCEEDED( vb->Lock( 0 , rendertoken->GetVertexMaxCount() * sizeof( GDSVERTEX ) , (void**)&pVB , 0 ) ) )
		{
			D3DXVECTOR3 minPos( 0,0,0 );
			D3DXVECTOR3 maxPos( 0,0,0 );
			for ( int i=0 ; i < rendertoken->GetVertexMaxCount() ; i++ )
			{				
				GDSVERTEX* v = (GDSVERTEX*)pVB + i;

				if ( minPos.x > v->p.x )
					minPos.x = v->p.x;

				if ( minPos.y > v->p.y )
					minPos.y = v->p.y;

				if ( minPos.z > v->p.z )
					minPos.z = v->p.z;

				if ( maxPos.x < v->p.x )
					maxPos.x = v->p.x;
				if ( maxPos.y < v->p.y )
					maxPos.y = v->p.y;
				if ( maxPos.z < v->p.z )
					maxPos.z = v->p.z;
			}

			m_pOctreeRootNode = NULL;
			m_pVert = (GDSVERTEX*)pVB;
			if ( m_pOctreeRootNode == NULL )
				m_pOctreeRootNode = new Node( rendertoken->GetIndexMaxCount() , minPos , maxPos );

			VOID* pI;
			LPDIRECT3DINDEXBUFFER9 pIB = rendertoken->GetIndexBuffer();
			pIB->Lock( 0 , rendertoken->GetIndexMaxCount() * sizeof( GDSINDEX ) , (void**)&pI , 0 );
			memcpy( m_pOctreeRootNode->m_pFace , pI , sizeof( GDSINDEX ) * rendertoken->GetIndexMaxCount() );
			pIB->Unlock();
			m_pOctreeRootNode->m_iNumOfChild = 0;	

			build( m_pOctreeRootNode );
			
		}		
		vb->Unlock();
	}

	m_bUseOctree = true;
	m_iCountOfOctreeNode = 0;
}
Beispiel #11
0
	RectF FontData::getRegion(const String& codePoints, const double lineSpacingScale)
	{
		if (!render(codePoints))
		{
			return RectF(0);
		}

		Vec2 penPos(0, 0);
		Vec2 minPos(DBL_MAX, DBL_MAX);
		Vec2 maxPos(DBL_MIN, DBL_MIN);
		int32 lineCount = 0;

		for (const auto codePoint : codePoints)
		{
			if (codePoint == U'\n')
			{
				penPos.x = 0;
				penPos.y += m_lineSpacing * lineSpacingScale;
				++lineCount;
			}
			else if (codePoint == U'\t')
			{
				minPos.x = std::min(minPos.x, penPos.x);
				minPos.y = std::min(minPos.y, penPos.y + m_ascender);
				maxPos.x = std::max(maxPos.x, penPos.x + m_tabWidth);
				maxPos.y = std::max(maxPos.y, penPos.y);
				penPos.x += m_tabWidth;
			}
			else if (!IsControl(codePoint))
			{
				if (lineCount == 0)
				{
					++lineCount;
				}

				const auto& glyphInfo = m_glyphs[m_glyphIndexTable[codePoint]];
				const RectF region(penPos + glyphInfo.offset, glyphInfo.bitmapRect.size);
				const int32 characterWidth = glyphInfo.xAdvance;
				minPos.x = std::min(minPos.x, region.x);
				minPos.y = std::min(minPos.y, region.y);
				maxPos.x = std::max(maxPos.x, penPos.x + characterWidth);
				maxPos.y = std::max(maxPos.y, region.y + region.h);
				penPos.x += glyphInfo.xAdvance;
			}
		}

		if (minPos == Vec2(DBL_MAX, DBL_MAX))
		{
			return RectF(0);
		}

		return RectF(0, 0, maxPos.x, lineCount * m_lineSpacing * lineSpacingScale);
	}
Beispiel #12
0
Position Selection::minPosition() const
{
	Position minPos(0x10000, 0x10000, 0x10);
	for(TileVector::const_iterator tile = tiles.begin(); tile != tiles.end(); ++tile) {
		Position pos((*tile)->getPosition());
		if(minPos.x > pos.x)
			minPos.x = pos.x;
		if(minPos.y > pos.y)
			minPos.y = pos.y;
		if(minPos.z > pos.z)
			minPos.z = pos.z;
	}
	return minPos;
}
Beispiel #13
0
bool Camera3::craftUi()
{
	Vector3 min = minPos(Vector3(0,10, -35), 15, 15, 15);
	Vector3 max = maxPos(Vector3(0,10,-35), 15, 15, 15);

	if (position.x > min.x && position.y > min.y && position.z > min.z
		&& position.x < max.x && position.y < max.y && position.z < max.z)
	{
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #14
0
bool Camera3::startBossGM()
{
	Vector3 kMin = minPos(Vector3(-40, 10, 0), 15, 10, 15);
	Vector3 kMax = maxPos(Vector3(-40, 10, 0), 15, 10, 15);


	if (location.x > kMin.x && location.y > kMin.y && location.z > kMin.z
		&& location.x < kMax.x && location.y  < kMax.y && location.z < kMax.z)
	{
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #15
0
void CMainFrame::CopyControl()
{
	if (CWndControl::s_selection.GetSize() < 1
		|| !CWndControl::s_selection[0]
		|| CWndControl::s_selection[0]->GetType() == WTYPE_GUI_EDITOR_WND)
		return;

	int i;
	for (i = 0; i < m_clipboardControls.GetSize(); i++)
		Delete(m_clipboardControls[i]);
	m_clipboardControls.RemoveAll();

	CWndControl* ctrl;
	for (i = 0; i < CWndControl::s_selection.GetSize(); i++)
	{
		ctrl = CWndControl::s_selection[i];
		WindowData* wnd = m_dataMng->GetWindow(ctrl->GetParent()->GetID());
		if (wnd)
		{
			ControlData* data = wnd->GetControl(ctrl->GetID());
			if (data)
			{
				ControlData* newData = new ControlData();
				(*newData) = (*data);
				m_clipboardControls.Append(newData);
			}
		}
	}

	QPoint minPos(99999, 99999);
	for (i = 0; i < m_clipboardControls.GetSize(); i++)
	{
		if (m_clipboardControls[i]->rect.left() < minPos.x())
			minPos.setX(m_clipboardControls[i]->rect.left());
		if (m_clipboardControls[i]->rect.top() < minPos.y())
			minPos.setY(m_clipboardControls[i]->rect.top());
	}

	for (i = 0; i < m_clipboardControls.GetSize(); i++)
	{
		m_clipboardControls[i]->rect = QRect(m_clipboardControls[i]->rect.topLeft() - minPos,
			m_clipboardControls[i]->rect.size());
	}
}
// input: the pressure data, after static calibration (tare) but otherwise raw.
// input feeds a state machine that first collects a normalization map, then
// collects a touch shape, or kernel, at each point. 
int TouchTracker::Calibrator::addSample(const MLSignal& m)
{
	int r = 0;
	static Vec2 intPeak1;
	
	static MLSignal f2(mSrcWidth, mSrcHeight);
	static MLSignal input(mSrcWidth, mSrcHeight);
	static MLSignal tare(mSrcWidth, mSrcHeight);
	static MLSignal normTemp(mSrcWidth, mSrcHeight);
    
    // decreasing this will collect a wider area during normalization,
    // smoothing the results.
    const float kNormalizeThreshold = 0.125f;
	
	float kc, ke, kk;
	kc = 4./16.; ke = 2./16.; kk=1./16.;
	
	// simple lopass time filter for calibration
	f2 = m;
	f2.subtract(mFilteredInput);
	f2.scale(0.1f);
	mFilteredInput.add(f2);
	input = mFilteredInput;
	input.sigMax(0.);		
		
	// get peak of sample data
	Vec3 testPeak = input.findPeak();	
	float peakZ = testPeak.z();
	
	const int startupSamples = 1000;
	const int waitAfterNormalize = 2000;
	if (mTotalSamples < startupSamples)
	{
		age = 0;
		mStartupSum += peakZ;
		if(mTotalSamples % 100 == 0)
		{
			MLConsole() << ".";
		}
	}
	else if (mTotalSamples == startupSamples)
	{
		age = 0;
		//mAutoThresh = kNormalizeThresh;
		mAutoThresh = mStartupSum / (float)startupSamples * 10.f;	
		MLConsole() << "\n****************************************************************\n\n";
		MLConsole() << "OK, done collecting silence (auto threshold: " << mAutoThresh << "). \n";
		MLConsole() << "Now please slide your palm across the surface,  \n";
		MLConsole() << "applying a firm and even pressure, until all the rectangles \n";
		MLConsole() << "at left turn blue.  \n\n";
		
		mNormalizeMap.clear();
		mNormalizeCount.clear();
		mCollectingNormalizeMap = true;
	}		
	else if (mCollectingNormalizeMap)
	{
		// smooth temp signal, duplicating values at border
		normTemp.copy(input);		
		normTemp.convolve3x3rb(kc, ke, kk);
		normTemp.convolve3x3rb(kc, ke, kk);
		normTemp.convolve3x3rb(kc, ke, kk);
	
		if(peakZ > mAutoThresh)
		{
			// collect additions in temp signals
			mTemp.clear(); // adds to map
			mTemp2.clear(); // adds to sample count
			
			// where input > thresh and input is near max current input, add data. 		
			for(int j=0; j<mHeight; ++j)
			{
				for(int i=0; i<mWidth; ++i)
				{
					// test threshold with smoothed data
					float zSmooth = normTemp(i, j);
					// but add actual samples from unsmoothed input
					float z = input(i, j);
					if(zSmooth > peakZ * kNormalizeThreshold)
					{
						// map must = count * z/peakZ
						mTemp(i, j) = z / peakZ;
						mTemp2(i, j) = 1.0f;	
					}
				}
			}
			
			// add temp signals to data						
			mNormalizeMap.add(mTemp);
			mNormalizeCount.add(mTemp2);
			mVisSignal.copy(mNormalizeCount);
			mVisSignal.scale(1.f / (float)kNormMapSamples);
		}
		
		if(doneCollectingNormalizeMap())
		{				
			float mapMaximum = makeNormalizeMap();	
						
			MLConsole() << "\n****************************************************************\n\n";
			MLConsole() << "\n\nOK, done collecting normalize map. (max = " << mapMaximum << ").\n";
			MLConsole() << "Please lift your hands.";
			mCollectingNormalizeMap = false;
			mWaitSamplesAfterNormalize = 0;
			mVisSignal.clear();
			mStartupSum = 0;
		}
	}
	else
	{
		if(mWaitSamplesAfterNormalize < waitAfterNormalize)
		{
			mStartupSum += peakZ;
			mWaitSamplesAfterNormalize++;
			if(mTotalSamples % 100 == 0)
			{
				MLConsole() << ".";
			}
		}
		else if(mWaitSamplesAfterNormalize == waitAfterNormalize)
		{
			mWaitSamplesAfterNormalize++;
			mAutoThresh *= 1.5f;
			MLConsole() << "\nOK, done collecting silence again (auto threshold: " << mAutoThresh << "). \n";

			MLConsole() << "\n****************************************************************\n\n";
			MLConsole() << "Now please slide a single finger over the  \n";
			MLConsole() << "Soundplane surface, visiting each area twice \n";
			MLConsole() << "until all the areas are colored green at left.  \n";
			MLConsole() << "Sliding over a key the first time will turn it gray.  \n";
			MLConsole() << "Sliding over a key the second time will turn it green.\n";
			MLConsole() << "\n";
		}
		else if(peakZ > mAutoThresh)
		{
			// normalize input
			mTemp.copy(input);
			mTemp.multiply(mNormalizeMap);
		
			// smooth input	
			mTemp.convolve3x3r(kc, ke, kk);
			mTemp.convolve3x3r(kc, ke, kk);
			mTemp.convolve3x3r(kc, ke, kk);
			
			// get corrected peak
			mPeak = mTemp.findPeak();
			mPeak = mTemp.correctPeak(mPeak.x(), mPeak.y());							
			Vec2 minPos(2.0, 0.);
			Vec2 maxPos(mWidth - 2., mHeight - 1.);
			mPeak = vclamp(mPeak, minPos, maxPos);
		
			age++; // continue touch
			// get sample from input around peak and normalize
			mIncomingSample.clear();
			mIncomingSample.add2D(m, -mPeak + Vec2(kTemplateRadius, kTemplateRadius)); 
			mIncomingSample.sigMax(0.f);
			mIncomingSample.scale(1.f / mIncomingSample(kTemplateRadius, kTemplateRadius));

			// get integer bin	
			Vec2 binPeak = getBinPosition(mPeak);
			mVisPeak = binPeak - Vec2(0.5, 0.5);		
			int bix = binPeak.x();			
			int biy = binPeak.y();
			// clamp to calibratable area
			bix = clamp(bix, 2, mWidth - 2);
			biy = clamp(biy, 0, mHeight - 1);
			Vec2 bIntPeak(bix, biy);

			// count sum and minimum of all kernel samples for the bin
			int dataIdx = biy*mWidth + bix;
			mDataSum[dataIdx].add(mIncomingSample); 
			mData[dataIdx].sigMin(mIncomingSample); 
			mSampleCount[dataIdx]++;
            
			if(bIntPeak != intPeak1)
			{
				// entering new bin.
				intPeak1 = bIntPeak;
				if(mPassesCount[dataIdx] < kPassesToCalibrate)
				{
					mPassesCount[dataIdx]++;
					mVisSignal(bix, biy) = (float)mPassesCount[dataIdx] / (float)kPassesToCalibrate;
				}
			}			
			
			// check for done
			if(isDone())
			{
				mCalibrateSignal.setDims(kTemplateSize, kTemplateSize, mWidth*mHeight);
				
				// get result for each junction
				for(int j=0; j<mHeight; ++j)
				{
					for(int i=0; i<mWidth; ++i)
					{						
						int idx = j*mWidth + i;
						// copy to 3d signal
						mCalibrateSignal.setFrame(idx, mData[idx]);
					}
				}
				
				getAverageTemplateDistance();
				mHasCalibration = true;
				mActive = false;	
				r = 1;	
							
				MLConsole() << "\n****************************************************************\n\n";
				MLConsole() << "Calibration is now complete and will be auto-saved in the file \n";
				MLConsole() << "SoundplaneAppState.txt. \n";
				MLConsole() << "\n****************************************************************\n\n";
			}	
		}
		else
		{
			age = 0;
			intPeak1 = Vec2(-1, -1);
			mVisPeak = Vec2(-1, -1);
		}
	}
	mTotalSamples++;
	return r;
}
Beispiel #17
0
HRESULT GdsNode::Update( float fElapsedtime )
{	
	if ( m_bCull )
		return FALSE;

	D3DXMATRIX matTrans, matScale, matRot;
	D3DXMatrixIdentity( &matTrans );
	D3DXMatrixIdentity( &matScale );
	D3DXMatrixIdentity( &matRot );

	D3DXMatrixTranslation(&matTrans, m_vTranslate.x, m_vTranslate.y, m_vTranslate.z);
	D3DXMatrixScaling(&matScale, m_vScale.x, m_vScale.y, m_vScale.z);
	D3DXMatrixRotationQuaternion(&matRot, &m_qRotate);

	m_matLocal = matTrans * matRot * matScale;

	if( GetParent() )
	{
		D3DXMATRIX parTM;
		parTM = GetParent()->GetWorldMatrix();
		//m_matWorld = m_matLocal * m_matAni * m_pParent->GetWorldMatrix();
		m_matWorld = m_matLocal * parTM;
	}
	else
	{
		m_matWorld = m_matLocal;
	}

	m_vWorldTranslate = D3DXVECTOR3(m_matWorld._41, m_matWorld._42, m_matWorld._43 ) ;
	D3DXQuaternionRotationMatrix(&m_qWorldRotate, &m_matWorld);
	// 뷰 판정
	if ( CAMMGR.GetCurCam()->GetFrustum().VertexIsInFrustum( m_vWorldTranslate ) == false )	
	{
		return FALSE;
	}


	if ( m_bShowAxis )
	{
		D3DXVECTOR3 cenPos( 5.f , 5.f , 5.f );
		RENDERER.DrawAxis( m_matWorld , cenPos );
	}
	if ( m_bShowBox )
	{
		D3DXVECTOR3 minPos( -10.f , -10.f , -10.f );
		D3DXVECTOR3 maxPos( 10.f , 10.f , 10.f );
		RENDERER.DrawBox( m_matWorld , minPos , maxPos );
	}


	if ( m_bUseOctree )
	{
		GenOctreeFaceIndex();
	}

	if ( !m_list_RenderObject.empty() )
	{
		RENDER_OBJECT_CONTAINER::iterator it = m_list_RenderObject.begin();
		for ( ; it != m_list_RenderObject.end() ; ++it )
		{
			it->first->SetMatrix( m_matWorld );
			//RENDERER.GetRenderFrame()->AttachRenderObject( it->first , it->second );
		}			
	}		

	vUpdate( fElapsedtime );


	if ( !m_ChildNode.empty() )
	{
		for( CHILDNODE_CONTAINER::iterator it = m_ChildNode.begin() ; it != m_ChildNode.end() ; ++it )
		{
			(*it)->Update(fElapsedtime);
		}
	}		

	return TRUE;
}
Beispiel #18
0
void AabbSpawnUtil::getNewSpawnPosition(const hkVector4& aabbDims, hkVector4& positionOut)
{
	// Try each volume in turn
	while (1)
	{
		hkVector4 avaliableDiag; avaliableDiag.setSub4( m_spawnVolumes[m_currentSpawnVolume].m_max, m_spawnVolumes[m_currentSpawnVolume].m_min );
		avaliableDiag.sub4(aabbDims);
		if ( avaliableDiag(0) < 0  || avaliableDiag(2) < 0 )
		{
			HK_ASSERT2(0, 0, "No spawn space large enough for requested aabb");
			return;
		}

		// Try 100 random positions in the volume
		int numTries = m_allowOverlaps ? 1 : 100;
		for (int j = 0; j < numTries; ++j)
		{
			hkVector4 minPos(m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01() );
			
			if (avaliableDiag(1) < 0)
			{
				minPos(1) = 0;
			}

			minPos.mul4(avaliableDiag);
			minPos.add4(m_spawnVolumes[m_currentSpawnVolume].m_min);


			hkVector4 maxPos; maxPos.setAdd4( minPos, aabbDims );
			hkAabb candidate( minPos, maxPos );
			bool aabbCollides = false;

			if (!m_allowOverlaps)
			{
				for ( int k = 0; k < m_spawnedAabbs[m_currentSpawnVolume].getSize(); k++ )
				{
					if ( m_spawnedAabbs[m_currentSpawnVolume][k].overlaps(candidate))
					{
						aabbCollides = true;
						break;
					}
				}
			}
			if ( !aabbCollides )
			{
				m_spawnedAabbs[m_currentSpawnVolume].pushBack(candidate);
				hkVector4 position; positionOut.setInterpolate4( candidate.m_min, candidate.m_max, .5f );

				// If we allow penetrations, take each spawn volume in turn
				if ( m_allowOverlaps )
				{
					m_currentSpawnVolume++;
					if (m_currentSpawnVolume == m_spawnVolumes.getSize())
					{
						m_currentSpawnVolume = 0;
					}
				}
				return;
			}
		}
		// If we couldn't find a space, try the next volume
		m_currentSpawnVolume++;
		if (m_currentSpawnVolume == m_spawnVolumes.getSize())
		{
			m_currentSpawnVolume = 0;
			m_allowOverlaps = true;
		}
	}
}
Beispiel #19
0
//==================================================================
void Hider::Bust(
				const HiderBucket	&bucket,
				ShadedGrid			&shadGrid,
				const WorkGrid		&workGrid,
				DVec<HiderPixel>	&pixels,
				u_int				screenWd,
				u_int				screenHe ) const
{
	const SlColor	*pOi = (const SlColor *)workGrid.mSymbolIs.FindSymbolIData( "Oi" );
	const SlColor	*pCi = (const SlColor *)workGrid.mSymbolIs.FindSymbolIData( "Ci" );

	//const Float3_	 *pN = (const Float3_  *)workGrid.mSymbolIs.FindSymbolIData( "N"	);

	{
		static const Float_	one( 1 );

		Float_ screenCx  = Float_( screenWd * 0.5f );
		Float_ screenCy  = Float_( screenHe * 0.5f );
		Float_ screenHWd = Float_( screenWd * 0.5f );
		Float_ screenHHe = Float_( screenHe * 0.5f );

		const Float3_	*pPointsCS	= (const Float3_ *)workGrid.mpPointsCS;

		size_t	blocksN = DMT_SIMD_BLOCKS( workGrid.mPointsN );
		for (size_t blkIdx=0; blkIdx < blocksN; ++blkIdx)
		{
			Float4_		homoP = V4__V3W1_Mul_M44<Float_>( pPointsCS[ blkIdx ], mOptions.mMtxCamProj );

			Float4_		projP = homoP / homoP.w();

			shadGrid.mpPointsCS[ blkIdx ]			= pPointsCS[ blkIdx ];
			//shadGrid.mpPointsCloseCS[ blkIdx ]	= 0;

			shadGrid.mpPosWin[ blkIdx ][0] =  projP.x() * screenHWd + screenCx;
			shadGrid.mpPosWin[ blkIdx ][1] = -projP.y() * screenHHe + screenCy;

			shadGrid.mpCi[ blkIdx ] = pCi[ blkIdx ];
			shadGrid.mpOi[ blkIdx ] = pOi[ blkIdx ];
		}
	}

	DASSERT( workGrid.mXDim == DMT_SIMD_BLOCKS( workGrid.mXDim ) * DMT_SIMD_FLEN );

	u_int	xN		= workGrid.mXDim - 1;
	u_int	yN		= workGrid.mYDim - 1;

	u_int	buckWd	= bucket.GetWd();
	u_int	buckHe	= bucket.GetHe();

	if ( mParams.mDbgRasterizeVerts )
	{
		// scan the grid.. for every vertex
		size_t	srcVertIdx = 0;
		for (u_int i=0; i < yN; ++i)
		{
			for (u_int j=0; j < xN; ++j, ++srcVertIdx)
			{
				u_int	blk = (u_int)srcVertIdx / DMT_SIMD_FLEN;
				u_int	sub = (u_int)srcVertIdx & (DMT_SIMD_FLEN-1);

				int pixX = (int)floor( shadGrid.mpPosWin[ blk ][0][ sub ] - (float)bucket.mX1 );
				int pixY = (int)floor( shadGrid.mpPosWin[ blk ][1][ sub ] - (float)bucket.mY1 );

				if ( pixX >= 0 && pixY >= 0 && pixX < (int)buckWd && pixY < (int)buckHe )
				{
					HiderPixel	&pixel = pixels[ pixY * buckWd + pixX ];

					HiderSampleData &sampData = Dgrow( pixel.mpSampDataLists[0] );

					sampData.mOi[0] = shadGrid.mpOi[ blk ][0][ sub ];
					sampData.mOi[1] = shadGrid.mpOi[ blk ][1][ sub ];
					sampData.mOi[2] = shadGrid.mpOi[ blk ][2][ sub ];

					sampData.mCi[0] = shadGrid.mpCi[ blk ][0][ sub ];
					sampData.mCi[1] = shadGrid.mpCi[ blk ][1][ sub ];
					sampData.mCi[2] = shadGrid.mpCi[ blk ][2][ sub ];

					sampData.mDepth = shadGrid.mpPointsCS[ blk ][2][ sub ];
				}
			}

			srcVertIdx += 1;
		}
	}
	else
	{
		// scan the grid.. for every potential micro-polygon
		size_t	srcVertIdx = 0;
		for (u_int i=0; i < yN; ++i)
		{
			for (u_int j=0; j < xN; ++j, ++srcVertIdx)
			{
				// vector coords of the micro-poly
				u_int	vidx[4] = {
							(u_int)srcVertIdx + 0,
							(u_int)srcVertIdx + 1,
							(u_int)srcVertIdx + xN+1,
							(u_int)srcVertIdx + xN+2 };

				Float3	minPos(  FLT_MAX,  FLT_MAX,  FLT_MAX );
				Float3	maxPos( -FLT_MAX, -FLT_MAX, -FLT_MAX );

				// calculate the bounds in window space and orientation
				//	--------
				//	| /\   |
				//	|/   \ |
				//	|\    /|
				//	|  \ / |
				//	--------
				size_t	blk[4];
				size_t	sub[4];
				Float3	buckPos[4];

				for (size_t k=0; k < 4; ++k)
				{
					blk[k] = vidx[k] / DMT_SIMD_FLEN;
					sub[k] = vidx[k] & (DMT_SIMD_FLEN-1);

					buckPos[k][0] = shadGrid.mpPosWin[ blk[k] ][0][ sub[k] ] - (float)bucket.mX1;
					buckPos[k][1] = shadGrid.mpPosWin[ blk[k] ][1][ sub[k] ] - (float)bucket.mY1;
					buckPos[k][2] = shadGrid.mpPointsCS[ blk[k] ][2][ sub[k] ];

					updateMinMax( minPos, maxPos, buckPos[k] );
				}

				// sample only from the first vertex.. no bilinear
				// interpolation in the micro-poly !
				float valOi[3] =
					{
						shadGrid.mpOi[ blk[0] ][0][ sub[0] ],
						shadGrid.mpOi[ blk[0] ][1][ sub[0] ],
						shadGrid.mpOi[ blk[0] ][2][ sub[0] ]
					};
				float valCi[3] =
					{
						shadGrid.mpCi[ blk[0] ][0][ sub[0] ],
						shadGrid.mpCi[ blk[0] ][1][ sub[0] ],
						shadGrid.mpCi[ blk[0] ][2][ sub[0] ]
					};

				addMPSamples(
						*bucket.mpSampCoordsBuff,
						&pixels[0],
						minPos,
						maxPos,
						(int)buckWd,
						(int)buckHe,
						buckPos,
						valOi,
						valCi );
			}

			srcVertIdx += 1;
		}
	}
}
Beispiel #20
0
void GameScreen::createExplosion(glm::vec3 const& position, float size, float duration, bool removeBlocks)
{
	// Add new explosion
	explosions.push_back(Explosion(position, glm::vec2(size), duration));
	// Limit explosion sounds to one per frame
	if (explosionsThisFrame < 1)
	{
		game->getSoundManager()->playSound("Sounds/bombexplosion.mp3", position, 30.f);
	}
	explosionsThisFrame++;

	// Find all bombs within the explosion radius
	Bomb::id_set nearbyBombs;
	glm::vec2 groundPos(glm::swizzle<glm::X, glm::Z>(position));
	getNearbyBombs(groundPos, size * 0.5f, nearbyBombs);
	BOOST_FOREACH(Bomb::id const& id, nearbyBombs)
	{
		// Only deal with the players own bombs
		if (id.first == myID)
		{
			Bomb& bomb = myEntities[id.second];
			if (bomb.isAlive())
			{
				Packet::ptr packet(new Packet13RemoveBomb(myID, id.second, true));
				client->write(packet);

				bomb.setIsAlive(false);
			}
		}
	}
	
	// Blow up blocks
	if (removeBlocks)
	{
		float blockExplosionRadius = size * 0.8f;

		glm::vec2 bPos = groundPos - glm::vec2(0.5f);

		glm::ivec2 minPos(glm::floor(bPos - glm::vec2(blockExplosionRadius)));
		glm::ivec2 maxPos(glm::ceil(bPos + glm::vec2(blockExplosionRadius)));

		minPos = glm::max(minPos, 0);
		maxPos = glm::min(maxPos, blockMap.getSize() - glm::ivec2(1));

		std::vector<glm::ivec2> blocks;

		// For every block in a square...
		for (int x = minPos.x; x <= maxPos.x; x++)
		{
			for (int y = minPos.y; y <= maxPos.y; y++)
			{
				glm::ivec2 oPos(x, y);

				Block::ptr block = blockMap.getBlock(oPos);			

				if (block && block->isDestructible() && glm::distance(glm::vec2(oPos), bPos) < blockExplosionRadius)
				{
					blocks.push_back(oPos);
				}
			}
		}

		// If any block to remove was found...
		if (!blocks.empty())
		{
			Packet::ptr packet(new Packet14RemoveBlocks(blocks));
			client->write(packet);
		}
	}

	// Give score for every explosion close to the opponents base
	if (glm::distance(position, opponentBasePos) < size * 0.5f)
	{
		scoreThisFrame += BASE_POINTS_PER_BOMB;
	}
}
Beispiel #21
0
void ePageView::_onOperatorPaste()
{
    eGuiOpPage *guiPage = (eGuiOpPage *)scene();
    eASSERT(guiPage != eNULL);

    // Check if clipboard format is correct.
    const QMimeData *md = QApplication::clipboard()->mimeData();
    eASSERT(md != eNULL);

    if (!md->hasFormat("operator/xml"))
    {
        return;
    }

    // Get operator with smallest (x, y) position,
    // needed to calculate new positions for
    // pasted operators.
    QDomDocument xml;
    xml.setContent(md->data("operator/xml"));
    QDomElement xmlOp = xml.firstChild().firstChildElement("operator");

    ePoint minPos(eS32_MAX, eS32_MAX);

    while (!xmlOp.isNull())
    {
        const eInt x = xmlOp.attribute("xpos").toInt();
        const eInt y = xmlOp.attribute("ypos").toInt();

        if (x < minPos.x)
        {
            minPos.x = x;
        }

        if (y < minPos.y)
        {
            minPos.y = y;
        }

        xmlOp = xmlOp.nextSiblingElement("operator");
    }

    // Iterate the second time through operators. This
    // time the operators are added to the page using
    // the previously calculated minimum relative
    // position.
    xmlOp = xml.firstChild().firstChildElement("operator");

    while (!xmlOp.isNull())
    {
        const QString opType = xmlOp.attribute("type");
        const eU32 xpos = xmlOp.attribute("xpos").toInt();
        const eU32 ypos = xmlOp.attribute("ypos").toInt();
        const eU32 width = xmlOp.attribute("width").toInt();
        const eID opId = xmlOp.attribute("id").toInt();

        const ePoint newPos = guiPage->getInsertAt()+(ePoint(xpos, ypos)-minPos);
        eASSERT(newPos.x >= 0 && newPos.y >= 0);

        // Only add operator, if its position
        // lies on operator page.
        if (newPos.y < eOperatorPage::HEIGHT &&
            newPos.x+width <= eOperatorPage::WIDTH)
        {
            eGuiOperator *guiOp = new eGuiOperator(opType.toAscii().constData(), newPos, guiPage, width, eFALSE, opId);
            eASSERT(guiOp != eNULL);

            // Was adding of operator successful?
            if (guiOp->getOperator())
            {
                guiOp->loadFromXml(xmlOp);
                scene()->addItem(guiOp);
            }
            else
            {
                eSAFE_DELETE(guiOp);
            }
        }

        xmlOp = xmlOp.nextSiblingElement("operator");
    }

    // Finally, after adding all operators,
    // update links on page.
    guiPage->getPage()->updateLinks();
    scene()->invalidate();
}
Beispiel #22
0
bool DicomVolume::initData(const std::string& DICOMpath){
  m_DicomParser.GetDirInfo(DICOMpath);

  //multiple files in folder, don't know which to take
  if(m_DicomParser.m_FileStacks.size() < 1){
  std::cout <<"[DICOMVolume] no correct dicom file "<<m_DicomParser.m_FileStacks.size()<<std::endl;
    return false;
  }

    //need better dimensions later !
    m_vDimensions.x = m_DicomParser.m_FileStacks[0]->m_ivSize.x;
    m_vDimensions.y = m_DicomParser.m_FileStacks[0]->m_ivSize.y;
    m_vDimensions.z = m_DicomParser.m_FileStacks[0]->m_Elements.size();

    m_vAspectRatio =  m_DicomParser.m_FileStacks[0]->m_fvfAspect;
    std::cout << "[DICOMVolume] dimensions"<< m_DicomParser.m_FileStacks[0]->m_fvfAspect << std::endl;

    Vec3f minPos(1000.0f,1000.0f,1000.0f);
    Vec3f maxPos(-1000.0f,-1000.0f,-1000.0f);
    for(int i = 0; i < m_DicomParser.m_FileStacks[0]->m_Elements.size();++i){
            SimpleDICOMFileInfo* dicomInfo = (SimpleDICOMFileInfo*)(m_DicomParser.m_FileStacks[0]->m_Elements[i]);
            if(dicomInfo->m_fvPatientPosition.x < minPos.x){ minPos.x = dicomInfo->m_fvPatientPosition.x; }
            if(dicomInfo->m_fvPatientPosition.y < minPos.y){ minPos.y = dicomInfo->m_fvPatientPosition.y; }
            if(dicomInfo->m_fvPatientPosition.z < minPos.z){ minPos.z = dicomInfo->m_fvPatientPosition.z; }

            if(dicomInfo->m_fvPatientPosition.x > maxPos.x){ maxPos.x = dicomInfo->m_fvPatientPosition.x; }
            if(dicomInfo->m_fvPatientPosition.y > maxPos.y){ maxPos.y = dicomInfo->m_fvPatientPosition.y; }
            if(dicomInfo->m_fvPatientPosition.z > maxPos.z){ maxPos.z = dicomInfo->m_fvPatientPosition.z; }
    }
    std::cout <<"[DICOMVolume] Patient minPos: "<< minPos << std::endl;
    std::cout <<"[DICOMVolume] Patient maxPos: "<< maxPos << std::endl;

    SimpleDICOMFileInfo* test = (SimpleDICOMFileInfo*)(m_DicomParser.m_FileStacks[0]->m_Elements[0]);
    //std::cout <<"[DICOMVolume] Patient Position: "<< test->m_fvPatientPosition << std::endl;
    std::cout <<"[DICOMVolume] Patient scale: "<< test->m_fScale << std::endl;
    std::cout <<"[DICOMVolume] Patient Bias: "<< test->m_fBias << std::endl;
    std::cout <<"[DICOMVolume] Patient windowwidth: "<< test->m_fWindowWidth << std::endl;
    std::cout <<"[DICOMVolume] Patient windowcenter: "<< test->m_fWindowCenter << std::endl;

    uint32_t voxelCount = m_vDimensions.x*m_vDimensions.y*m_vDimensions.z;
    uint32_t bytePerElement = m_DicomParser.m_FileStacks[0]->m_iAllocated/8;

    std::cout << voxelCount << " " << m_DicomParser.m_FileStacks[0]->m_ivSize << " " <<m_DicomParser.m_FileStacks[0]->m_Elements.size() << std::endl;
    std::cout <<"[DICOMVolume] byte per element: "<< bytePerElement << std::endl;

    //resize the vector to fit the complete volume
    //m_vData.resize(voxelCount*bytePerElement);
    m_vData.resize(voxelCount);

    //read each dicome slide and store them in the volume
    uint32_t dataOffset = 0;
    uint16_t* offsetPointer;
    for(int i = 0; i < m_DicomParser.m_FileStacks[0]->m_Elements.size();++i){
        dataOffset = i * (m_DicomParser.m_FileStacks[0]->m_ivSize.x *
                        m_DicomParser.m_FileStacks[0]->m_ivSize.y
                        );
        offsetPointer = &(m_vData[dataOffset]);
        m_DicomParser.m_FileStacks[0]->m_Elements[i]->GetData((char*)offsetPointer,m_DicomParser.m_FileStacks[0]->m_Elements[i]->GetDataSize(), 0);
    }
    //calculate the histogram;
    uint16_t currentValue = 0;
    uint16_t largestValue = 0;

    //find max value
    unsigned int sum = 0;
    for(int i = 0; i < m_vData.size();++i){
        currentValue = m_vData[i];
        //if(i < 100000)
            sum+= currentValue;

        if(largestValue < currentValue) largestValue = currentValue;
    }

    std::cout <<"[DICOMVolume] largest found value: "<< largestValue << std::endl;
    std::cout <<"[DICOMVolume] sum: "<< sum << std::endl;

    m_vHistogram.resize(largestValue+1);
    for(int i = 0; i < m_vData.size();++i){
        currentValue = m_vData[i];
        m_vHistogram[currentValue]++;
    }

    m_vHistogram.resize(largestValue);

    return true;
}
Beispiel #23
0
bool GPSGridClient::checkCell( Result* result, QVector< UnsignedCoordinate >* path, NodeID gridX, NodeID gridY, const UnsignedCoordinate& coordinate, double gridRadius2, double gridHeadingPenalty2, double heading ) {
	static const int width = 32 * 32 * 32;
	ProjectedCoordinate minPos( ( double ) gridX / width, ( double ) gridY / width );
	ProjectedCoordinate maxPos( ( double ) ( gridX + 1 ) / width, ( double ) ( gridY + 1 ) / width );
	UnsignedCoordinate min( minPos );
	UnsignedCoordinate max( maxPos );
	if ( gridDistance2( min, max, coordinate ) >= result->gridDistance2 )
		return false;

	qint64 cellNumber = ( qint64( gridX ) << 32 ) + gridY;
	if ( !cache.contains( cellNumber ) ) {
		qint64 position = index->GetIndex( gridX, gridY );
		if ( position == -1 )
			return true;
		gridFile->seek( position );
		int size;
		gridFile->read( (char* ) &size, sizeof( size ) );
		unsigned char* buffer = new unsigned char[size + 8]; // reading buffer + 4 bytes

		gridFile->read( ( char* ) buffer, size );
		gg::Cell* cell = new gg::Cell();
		cell->read( buffer, min, max );
		cache.insert( cellNumber, cell, cell->edges.size() * sizeof( gg::Cell::Edge ) );
		delete[] buffer;
	}
	gg::Cell* cell = cache.object( cellNumber );
	if ( cell == NULL )
		return true;

	UnsignedCoordinate nearestPoint;
	for ( std::vector< gg::Cell::Edge >::const_iterator i = cell->edges.begin(), e = cell->edges.end(); i != e; ++i ) {
		bool found = false;

		for ( int pathID = 1; pathID < i->pathLength; pathID++ ) {
			UnsignedCoordinate sourceCoord = cell->coordinates[pathID + i->pathID - 1];
			UnsignedCoordinate targetCoord = cell->coordinates[pathID + i->pathID];
			double percentage = 0;

			double gd2 = gridDistance2( &nearestPoint, &percentage, sourceCoord, targetCoord, coordinate );

			// Do 2 independent checks:
			//  * gd2 with gridRadius
			//  * gd2 (+ gridHeadingPenalty2) with result->gridDistance2
			if ( gd2 > gridRadius2 || gd2 > result->gridDistance2 ) {
				continue;
			}

			if ( gridHeadingPenalty2 > 0 ) {
				double xDiff = ( double ) targetCoord.x - sourceCoord.x;
				double yDiff = ( double ) targetCoord.y - sourceCoord.y;
				double direction = fmod( atan2( yDiff, xDiff ), 2 * M_PI );
				double penalty = fmod( fabs( direction - heading ), 2 * M_PI );
				if ( penalty > M_PI )
					penalty = 2 * M_PI - penalty;
				if ( i->bidirectional && penalty > M_PI / 2 )
					penalty = M_PI - penalty;
				penalty = penalty / M_PI * gridHeadingPenalty2;
				gd2 += penalty;
			}

			if ( gd2 < result->gridDistance2 ) {
				result->nearestPoint = nearestPoint;
				result->gridDistance2 = gd2;
				result->previousWayCoordinates = pathID;
				result->percentage = percentage;
				found = true;
			}
		}

		if ( found ) {
			result->source = i->source;
			result->target = i->target;
			result->edgeID = i->edgeID;
			path->clear();
			for ( int pathID = 0; pathID < i->pathLength; pathID++ )
				path->push_back( cell->coordinates[pathID + i->pathID] );
		}
	}

	return true;
}
Beispiel #24
0
bool SGFParser::doParse(const QString &toParseStr)
{
	if (toParseStr.isNull() || toParseStr.isEmpty())
	{
		qWarning("Failed loading from file. Is it empty?");
		return false;
	}
	QString tmp;

	if(!loadedfromfile)
	{
		/* This bit of ugliness is because sgfs are used to duplicate boards as well
		 * as load from file FIXME */
		parseProperty(toParseStr, "CA", tmp);		//codec
		if (!tmp.isEmpty())
			readCodec = QTextCodec::codecForName(tmp.toLatin1().constData());
	}
	
	const MyString *toParse = NULL;

//////TODO	if (static_cast<Codec>(setting->readIntEntry("CODEC")) == codecNone)
/////////		toParse = new MySimpleString(toParseStr);
///////	else
		toParse = new MyString(toParseStr);

	Q_CHECK_PTR(toParse);
	
	int 	pos = 0,
		posVarBegin = 0,
		posVarEnd = 0,
		posNode = 0,
		moves = 0,
		i, x=-1, y=-1;

	int 	a_offset = QChar::fromLatin1('a').unicode() - 1 ;

	unsigned int pointer = 0,
		strLength = toParse->length();
	bool black = true,
		setup = false,
        old_label = false;
	isRoot = true;
	bool remember_root;
	QString unknownProperty;
	State state;
	MarkType markType;
	QString moveStr, commentStr;
	Position *position;
	MoveNum *moveNum;
	QStack<Move*> stack;
	QStack<MoveNum*> movesStack;
	/* FIXME toRemove, et., al., appears unused Remove it */
	QStack<Position*> toRemove;
/*
////TODO	stack.setAutoDelete(false);
	movesStack.setAutoDelete(true);
	toRemove.setAutoDelete(true);
*/
	// Initialises the tree with board size
	parseProperty(toParseStr, "SZ", tmp);
//	Tree *tree = new Tree(tmp.isEmpty() ? 19 : tmp.toInt()) ;// boardHandler->getTree();
	
	state = stateVarBegin;
	
	bool cancel = false;
    //FIXME abort does nothing!!
	
	// qDebug("File length = %d", strLength);
	
    tree->setLoadingSGF(true);
	
	QString sss="";
    do {
		posVarBegin = toParse->find('(', pointer);
		posVarEnd = toParse->find(')', pointer);
		posNode = toParse->find(';', pointer);
		
		pos = minPos(posVarBegin, posVarEnd, posNode);

		// Switch states

		// Node -> VarEnd
		if (state == stateNode && pos == posVarEnd)
			state = stateVarEnd;
		
		// Node -> VarBegin
		if (state == stateNode && pos == posVarBegin)
			state = stateVarBegin;
		
		// VarBegin -> Node
		else if (state == stateVarBegin && pos == posNode)
			state = stateNode;
		
		// VarEnd -> VarBegin
		else if (state == stateVarEnd && pos == posVarBegin)
			state = stateVarBegin;
		
		// qDebug("State after switch = %d", state);
		
		// Do the work
		switch (state)
		{
		case stateVarBegin:
			if (pos != posVarBegin)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("Var BEGIN at %d, moves = %d", pos, moves);
			
			stack.push(tree->getCurrent());
			moveNum = new MoveNum;
			moveNum->n = moves;
			movesStack.push(moveNum);
			pointer = pos + 1;
			break;
			
		case stateVarEnd:
			if (pos != posVarEnd)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("VAR END");
			
			if (!movesStack.isEmpty() && !stack.isEmpty())
			{
				Move *m = stack.pop();
				Q_CHECK_PTR(m);
				x = movesStack.pop()->n;
				
				// qDebug("Var END at %d, moves = %d, moves from stack = %d", pos, moves, x);
				
				for (i=moves; i > x; i--)
				{
					position = toRemove.pop();
					if (position == NULL)
						continue;
///////////////////			boardHandler->getStoneHandler()->removeStone(position->x, position->y);
//					tree->removeStone(position->x, position->y);
					// qDebug("Removing %d %d from stoneHandler.", position->x, position->y);
				}
				
				moves = x;
 							
				
				tree->setCurrent(m);
			}
			pointer = pos + 1;
			break;
			
		case stateNode:
			if (pos != posNode)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("Node at %d", pos);
			commentStr = QString();
			setup = false;
			markType = markNone;
			
			// Create empty node
			remember_root = isRoot;
			if (!isRoot)
			{
/////////////////////		boardHandler->createMoveSGF();
//				qDebug("############### Before creating move ####################");
//				qDebug(toParse->Str.toLatin1().constData());
				//tree->createMoveSGF();
				/* This does happen, why??? FIXME */
//				qDebug("###############                      ####################");
//				qDebug(toParse->Str.toLatin1().constData());
//				qDebug("############### After creating move ####################");
				unknownProperty = QString();
#ifdef FIXME	//why is this a warning? this happens on loading a file with time info
				if (tree->getCurrent()->getTimeinfo())
				qWarning("*** Timeinfo set !!!!");
#endif //FIXME
				//tree->getCurrent()->setTimeinfo(false);
			}
			else
				isRoot = false;
						
			Property prop;
			pos ++;

			do {
				uint tmppos=0;
				pos = toParse->next_nonspace (pos);
				
                if ((tmppos = toParse->isProperty("B",pos)))
				{
					prop = moveBlack;
					pos = tmppos;
					black = true;
				}
                else if ((tmppos = toParse->isProperty("W",pos)))
				{
					prop = moveWhite;
					pos = tmppos;
					black = false;
				}
                else if ((tmppos = toParse->isProperty("N",pos)))
				{
					prop = nodeName;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("AB",pos)))
				{
					prop = editBlack;
					pos = tmppos;
					setup = true;
					black = true;
				}
                else if ((tmppos = toParse->isProperty("AW",pos)))
				{
					prop = editWhite;
					pos = tmppos;
					setup = true;
					black = false;
				}
                else if ((tmppos = toParse->isProperty("AE",pos)))
				{
					prop = editErase;
					pos = tmppos;
					setup = true;
				}
                else if ((tmppos = toParse->isProperty("TR",pos)))
				{
					prop = editMark;
					markType = markTriangle;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("CR",pos)))
				{
					prop = editMark;
					markType = markCircle;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("SQ",pos)))
				{
					prop = editMark;
					markType = markSquare;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("MA",pos)))
				{
					prop = editMark;
					markType = markCross;
					pos = tmppos;
				}
				// old definition
                else if ((tmppos = toParse->isProperty("M",pos)))
				{
					prop = editMark;
					markType = markCross;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("LB",pos)))
				{
					prop = editMark;
					markType = markText;
					pos = tmppos;
					old_label = false;
				}
				// Added old L property. This is not SGF4, but many files contain this tag.
                else if ((tmppos = toParse->isProperty("L",pos)))
				{
					prop = editMark;
					markType = markText;
					pos = tmppos;
					old_label = true;
				}
                else if ((tmppos = toParse->isProperty("C",pos)))
				{
					prop = comment;
					pos = tmppos;
				}
                else if ((tmppos = toParse->isProperty("TB",pos)))
				{
					prop = editMark;
					markType = markTerrBlack;
					pos = tmppos;
					black = true;
				}
                else if ((tmppos = toParse->isProperty("TW",pos)))
				{
					prop = editMark;
					markType = markTerrWhite;
					pos = tmppos;
					black = false;
				}
                else if ((tmppos = toParse->isProperty("BL",pos)))
				{
					prop = timeLeft;
					pos = tmppos;
					black = true;
				}
                else if ((tmppos = toParse->isProperty("WL",pos)))
				{
					prop = timeLeft;
					pos = tmppos;
					black = false;
				}
                else if ((tmppos = toParse->isProperty("OB",pos)))
				{
					prop = openMoves;
					pos = tmppos;
					black = true;
				}
                else if ((tmppos = toParse->isProperty("OW",pos)))
				{
					prop = openMoves;
					pos = tmppos;
					black = false;
				}
                else if ((tmppos = toParse->isProperty("PL",pos)))
				{
					prop = nextMove;
					pos = tmppos;
				}
                    else if ((tmppos = toParse->isProperty("RG",pos)))
				{
					prop = unknownProp;
					pos = tmppos;
          				setup = true;
				}
				// Empty node
				else if (toParse->at(pos) == ';' || toParse->at(pos) == '(' || toParse->at(pos) == ')')
				{
					qDebug("Found empty node at %d", pos);
					while (toParse->at(pos).isSpace())
						pos++;
					continue;
				}
				else
				{
					// handle like comment
					prop = unknownProp;
					pos = toParse->next_nonspace (pos);
					//qDebug("SGF: next nonspace (1st):" + QString(toParse->at(pos)) + QString(toParse->at(pos+1)) + QString(toParse->at(pos+2)));
				}
				
				//qDebug("Start do loop : FOUND PROP %d, pos at %d now", prop, pos);
				//qDebug(toParse->getStr());			//causes crash
				// Next is one or more '[xx]'.
				// Only one in a move property, several in a setup propery
				do {
					if (toParse->at(pos) != '[' && prop != unknownProp)
					{
						delete toParse;
						return corruptSgf(pos);
					}
					
					// Empty type
					if (toParse->at(pos+1) == ']')
					{
						// CGoban stores pass as 'B[]' or 'W[]'
						if (prop == moveBlack || prop == moveWhite)
						{
							tree->doPass(true);
							
							// Remember this move for later, to remove from the matrix.
							position = new Position;
							position->x = x;
							position->y = y;
							toRemove.push(position);
							moves ++;
						}
						
						pos += 2;
						continue;
					}
					
					switch (prop)
					{
					case moveBlack:
					case moveWhite:
						// rare case: root contains move or placed stone:
						if (remember_root)
						{
							qDebug("root contains stone -> node created");
							/* Something is screwy here, inconsistencies
							 * in the way SGF's are treated. Like the below:
							 * the whole point of "remember_root", FIXME*/
							tree->addEmptyMove();
							isRoot = false;
							unknownProperty = QString();
#ifdef FIXME	//why is this a warning?
							if (tree->getCurrent()->getTimeinfo())
								qWarning("*** Timeinfo set (2)!!!!");
#endif //FIXME
							//tree->getCurrent()->setTimeinfo(false);
						}
					case editBlack:
					case editWhite:
					case editErase:
					{
						x = toParse->at(pos+1).unicode() - a_offset ;// - 'a';// + 1;
						y = toParse->at(pos+2).unicode() - a_offset ; //- 'a' + 1;

						int x1, y1;
						bool compressed_list;

						// check for compressed lists
						if (toParse->at(pos+3) == ':')
						{
							x1 = toParse->at(pos+4).unicode() -a_offset;// - 'a' + 1;
							y1 = toParse->at(pos+5).unicode() -a_offset;// - 'a' + 1;
							compressed_list = true;
						}
						else
						{
							x1 = x;
							y1 = y;
							compressed_list = false;
						}
/*								
*						TODO Do we nned this when the tree is created from file ?
*						boardHandler->setModeSGF(setup || compressed_list ? modeEdit : modeNormal);
*/
						
						int i, j;
						for (i = x; i <= x1; i++)
							for (j = y; j <= y1; j++)
                            {
                                if (prop == editErase)
								{
									tree->addStoneToCurrentMove(stoneErase, i, j);
								}
								else
								{
									if(setup)
									{
                                        if ((!remember_root) && (stack.top() == tree->getCurrent()))
                                            tree->addEmptyMove(); //if this is first in branch we need to add an empty move

										tree->addStoneToCurrentMove(black ? stoneBlack : stoneWhite, i, j);
									}
									else
                                    {
                                        Move *result = tree->getCurrent()->makeMove(black ? stoneBlack : stoneWhite, i, j);
                                        if (result)
                                            tree->setCurrent(result);
                                    }
								}
								// tree->getCurrent()->getMatrix()->debug();
								//qDebug("ADDING MOVE %s %d/%d", black?"B":"W", x, y);
								
								// Remember this move for later, to remove from the matrix.
								position = new Position;
								position->x = i;
								position->y = j;
								toRemove.push(position);
								moves ++;
							}
												
						if (compressed_list)
							// Advance pos by 7
							pos += 7;
						else
							// Advance pos by 4
							pos += 4;
						break;
					}
						
					case nodeName:
					{
						commentStr = QString();
						bool skip = false;
						
						while (toParse->at(++pos) != ']')
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Nodename string ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Nodename string ended immediately");
							}

							// white spaces
							if (toParse->at(pos) == '\\')
							{
								while (toParse->at(pos+1).isSpace() &&
									static_cast<unsigned int>(pos) < strLength-2)
									pos++;
								if (toParse->at(pos).isSpace())
									pos++;

								// case: "../<cr><lf>]"
								if (toParse->at(pos) == ']')
								{
									pos--;
									skip = true;
								}
							}

							// escaped chars: '\', ']', ':'
							if (!(toParse->at(pos) == '\\' &&
								(toParse->at(pos+1) == ']' ||
								 toParse->at(pos+1) == '\\' ||
								 toParse->at(pos+1) == ':')) &&
								 !skip &&
								 // no formatting
								!(toParse->at(pos) == '\n') &&
								!(toParse->at(pos) == '\r'))
								commentStr.append(toParse->at(pos));
						}
						
					 	//qDebug("Node name read: %s", commentStr.toLatin1().constData());
						if (!commentStr.isEmpty())
							// add comment; skip 'C[]'
							tree->getCurrent()->setNodeName(commentStr);
						pos++;
						break;
					}

					case comment:
					{
						commentStr = QString();
						bool skip = false;
						
						while (toParse->at(++pos) != ']' ||
							(toParse->at(pos-1) == '\\' && toParse->at(pos) == ']'))
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Comment string ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Comment string ended immediately");
							}

							// white spaces
							if (toParse->at(pos) == '\\')
							{
								while (toParse->at(pos+1).isSpace() &&
									static_cast<unsigned int>(pos) < strLength-2)
									pos++;
								if (toParse->at(pos).isSpace())
									pos++;

								// case: "../<cr><lf>]"
								if (toParse->at(pos) == ']')
								{
									pos--;
									skip = true;
								}
							}

							// escaped chars: '\', ']', ':'
							if (!(toParse->at(pos) == '\\' &&
								(toParse->at(pos+1) == ']' ||
								 toParse->at(pos+1) == '\\' ||
								 toParse->at(pos+1) == ':')) &&
								 !skip)
								commentStr.append(toParse->at(pos));
						}

						//qDebug("Comment read: %s", commentStr.toLatin1().constData());
						if (!commentStr.isEmpty())
						{
							// add comment; skip 'C[]'
							if(readCodec)
								tree->getCurrent()->setComment(readCodec->toUnicode(commentStr.toLatin1().constData()));
							else
								tree->getCurrent()->setComment(commentStr.toLatin1().constData());
						}
						pos ++;
						break;
					}

					case unknownProp:
					{
						// skip if property is known anyway
						bool skip = false;

						// save correct property name (or p.n. + '[')
						commentStr = QString(toParse->at(pos));
						commentStr += toParse->at(tmppos = toParse->next_nonspace (pos + 1));
						pos = tmppos;

						// check if it's really necessary to hold properties
						// maybe they are handled at another position
						if (commentStr == "WR" ||
							commentStr == "BR" ||
							commentStr == "PW" ||
							commentStr == "PB" ||
							commentStr == "SZ" ||
							commentStr == "KM" ||
							commentStr == "HA" ||
							commentStr == "RE" ||
							commentStr == "DT" ||
							commentStr == "PC" ||
							commentStr == "CP" ||
							commentStr == "GN" ||
							commentStr == "OT" ||
							commentStr == "TM" ||
							// now: general options
							commentStr == "GM" ||
							commentStr == "ST" ||
							commentStr == "AP" ||
							commentStr == "FF")
						{
							skip = true;
						}
						sss= toParse->at(pos);
						while (toParse->at(++pos) != ']' ||
							(toParse->at(pos-1) == '\\' && toParse->at(pos) == ']'))
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Unknown property ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Unknown property ended immediately");
							}
              						sss= toParse->at(pos);
							if (!skip)
								commentStr.append(toParse->at(pos));
						}

						if (!skip)
							commentStr.append("]");

						// qDebug("Comment read: %s", commentStr.latin1());
						if ((!commentStr.isEmpty()) && (!skip))
						{
							// cumulate unknown properties; skip empty property 'XZ[]'
							unknownProperty += commentStr;
							tree->getCurrent()->setUnknownProperty(unknownProperty);
						}
						pos ++;
            					sss= toParse->at(pos);
						break;
					}

					case editMark:
						// set moveStr for increment labels of old 'L[]' property
						moveStr = "A";
						while (toParse->at(pos) == '[' &&
							static_cast<unsigned int>(pos) < strLength)
						{
							x = toParse->at(pos+1).unicode() -a_offset;// - 'a' + 1;
							y = toParse->at(pos+2).unicode() -a_offset;// - 'a' + 1;
							// qDebug("MARK: %d at %d/%d", markType, x, y);
							pos += 3;
							
							// 'LB' property? Then we need to get the text
							if (markType == markText && !old_label)
							{
								if (toParse->at(pos) != ':')
								{
									delete toParse;
									return corruptSgf(pos);
								}
								moveStr = "";
								while (toParse->at(++pos) != ']' &&
									static_cast<unsigned int>(pos) < strLength)
									moveStr.append(toParse->at(pos));
								// qDebug("LB TEXT = %s", moveStr.latin1());
								// It might me a number mark?
								bool check = false;
								moveStr.toInt(&check);  // Try to convert to Integer
								// treat integers as characters...
								check = false;
								
								if (check)
									tree->getCurrent()->getMatrix()->
									insertMark(x, y, markNumber);  // Worked, its a number
								else
									tree->getCurrent()->getMatrix()->
									insertMark(x, y, markType);    // Nope, its a letter
								tree->getCurrent()->getMatrix()->
										setMarkText(x, y, moveStr);
							
								/*else	//fastload
								{
									if (check)  // Number
										tree->getCurrent()->insertFastLoadMark(x, y, markNumber);
									else        // Text
										tree->getCurrent()->insertFastLoadMark(x, y, markType, moveStr);
								}*/
							}
							else
							{
								int x1, y1;
								bool compressed_list;

								// check for compressed lists
								if (toParse->at(pos) == ':')
								{
									x1 = toParse->at(pos+1).unicode() -a_offset;// - 'a' + 1;
									y1 = toParse->at(pos+2).unicode() -a_offset;// - 'a' + 1;
									compressed_list = true;
								}
								else
								{
									x1 = x;
									y1 = y;
									compressed_list = false;
								}
								
								int i, j;
								for (i = x; i <= x1; i++)
									for (j = y; j <= y1; j++)
									{
										tree->getCurrent()->getMatrix()->insertMark(i, j, markType);
										//else	//fastload
										//	tree->getCurrent()->insertFastLoadMark(i, j, markType);

										// auto increment for old property 'L'
										if (old_label)
										{
											tree->getCurrent()->getMatrix()->
												setMarkText(x, y, moveStr);
											QChar c1 = moveStr[0];
											if (c1 == 'Z')
												moveStr = QString("a");
											else
												moveStr = c1.unicode() + 1;
										}
									}

//								new_node = false;

								if (compressed_list)
									// Advance pos by 3
									pos += 3;

								if((markType == markTerrWhite || markType == markTerrBlack) && !tree->getCurrent()->isTerritoryMarked())
									tree->getCurrent()->setTerritoryMarked();
							}

							//old_label = false;
							pos ++;
							while (toParse->at(pos).isSpace()) pos++;
						}
						break;

					case openMoves:
					{
						QString tmp_mv;
						while (toParse->at(++pos) != ']')
							tmp_mv += toParse->at(pos);
						tree->getCurrent()->setOpenMoves(tmp_mv.toInt());
						pos++;

						if (!tree->getCurrent()->getTimeinfo())
						{
							tree->getCurrent()->setTimeinfo(true);
							tree->getCurrent()->setTimeLeft(0);
						}
						break;
					}

					case timeLeft:
					{
						QString tmp_mv;
						while (toParse->at(++pos) != ']')
							tmp_mv += toParse->at(pos);
						tree->getCurrent()->setTimeLeft(tmp_mv.toFloat());
						pos++;

						if (!tree->getCurrent()->getTimeinfo())
						{
							tree->getCurrent()->setTimeinfo(true);
							tree->getCurrent()->setOpenMoves(0);
						}
						break;
					}

					case nextMove:
						if (toParse->at(++pos) == 'W')
							tree->getCurrent()->setPLinfo(stoneWhite);
						else if (toParse->at(pos) == 'B')
							tree->getCurrent()->setPLinfo(stoneBlack);

						pos += 2;
						break;

					default:
						break;
				}
		
				while (toParse->at(pos).isSpace())
			    		pos++;
        	
				sss= toParse->at(pos);

			} while (setup && toParse->at(pos) == '[');
			
//			tree->getCurrent()->getMatrix()->debug();
//			qDebug("end do loop");
//			qDebug(toParse->getStr());
			
			while (toParse->at(pos).isSpace())
				pos++;

		} while (toParse->at(pos) != ';' && toParse->at(pos) != '(' && toParse->at(pos) != ')' &&    static_cast<unsigned int>(pos) < strLength);
		
		// Advance pointer
		pointer = pos;
	
		break;
	
	default:
		delete toParse;
		return corruptSgf(pointer);
	}
	
	} while (pointer < strLength && pos >= 0);

	tree->setLoadingSGF(false);
	
	delete toParse;
	return !cancel;
}
Beispiel #25
0
void SplitPanel::updateLayout(void)
{
    Pnt2f TopLeft, BottomRight;
    getInsideBorderBounds(TopLeft, BottomRight);
    Vec2f BorderSize(BottomRight - TopLeft);

    UInt32 AxisIndex(0);
    if(getOrientation() != SplitPanel::HORIZONTAL_ORIENTATION ) AxisIndex = 1;

    Vec2f minSize(0,0);
    Vec2f maxSize(0,0);
    Vec2f divSize(0,0);
    Pnt2f minPos(0,0);
    Pnt2f maxPos(0,0);
    Pnt2f divPos(0,0);

    if (getDividerPosition() < 0.0)
        setDividerPosition(0.5);
    if (getMinDividerPosition() < 0.0)
        setMinDividerPosition(0.0);
    if (getMaxDividerPosition() < 0.0)
        setMaxDividerPosition(1.0);

    UInt32 dividerPosition(getDividerPosition());
    if (getDividerPosition() <= 1.0)
        dividerPosition = BorderSize[AxisIndex] * getDividerPosition();

    // check the divider's min and max
    if (getMinDividerPosition() <= 1.0)
    {
        if (dividerPosition < getMinDividerPosition() * BorderSize[AxisIndex])
            dividerPosition = getMinDividerPosition() * BorderSize[AxisIndex];
    }
    else
    {
        if (dividerPosition < getMinDividerPosition())
            dividerPosition = getMinDividerPosition();
    }
    if (getMaxDividerPosition() <= 1.0)
    {
        if (dividerPosition > getMaxDividerPosition() * BorderSize[AxisIndex])
            dividerPosition = getMaxDividerPosition() * BorderSize[AxisIndex];
    }
    else
    {
        if (dividerPosition > getMaxDividerPosition())
            dividerPosition = getMaxDividerPosition();
    }

    // set the minimum component's size
    minSize[AxisIndex] = dividerPosition - getDividerSize()/2;

    // check its min and max
    if (getMinComponent() != NULL)
    {
        if (minSize[AxisIndex] < getMinComponent()->getMinSize()[AxisIndex])
        {
            dividerPosition -= getMinComponent()->getMinSize()[AxisIndex] - minSize[AxisIndex];
            minSize[AxisIndex] = getMinComponent()->getMinSize()[AxisIndex];
        }
        if (minSize[AxisIndex] > getMinComponent()->getMaxSize()[AxisIndex])
        {
            dividerPosition += minSize[AxisIndex] - getMinComponent()->getMaxSize()[AxisIndex];
            minSize[AxisIndex] = getMinComponent()->getMaxSize()[AxisIndex];
        }
    }

    // set the maximum component's size
    maxSize[AxisIndex] = BorderSize[AxisIndex] - minSize[AxisIndex] - getDividerSize();

    // check its min and max
    if (getMaxComponent() != NULL)
    {
        if (maxSize[AxisIndex] < getMaxComponent()->getMinSize()[AxisIndex])
        {
            dividerPosition -= getMaxComponent()->getMinSize()[AxisIndex] - maxSize[AxisIndex];
            minSize[AxisIndex] -= getMaxComponent()->getMinSize()[AxisIndex] - maxSize[AxisIndex];
            maxSize[AxisIndex] = getMaxComponent()->getMinSize()[AxisIndex];
        }
        if (maxSize[AxisIndex] > getMaxComponent()->getMaxSize()[AxisIndex])
        {
            dividerPosition += maxSize[AxisIndex] - getMaxComponent()->getMaxSize()[AxisIndex];
            minSize[AxisIndex] += maxSize[AxisIndex] - getMaxComponent()->getMaxSize()[AxisIndex];
            maxSize[AxisIndex] = getMaxComponent()->getMaxSize()[AxisIndex];
        }
    }

    // set the minor axis' size and max's position
    minSize[(AxisIndex+1)%2] = maxSize[(AxisIndex+1)%2] = BorderSize[(AxisIndex+1)%2];
    maxPos[AxisIndex] = minSize[AxisIndex] + getDividerSize();

    // set the divider's size and position
    divSize[AxisIndex] = getDividerSize();
    divSize[(AxisIndex+1)%2] = BorderSize[(AxisIndex+1)%2];
    divPos[AxisIndex] = dividerPosition - getDividerSize()/2;

    // set the components to the right size and positions
    if (getMinComponent() != NULL)
    {
        if(getMinComponent()->getSize() != minSize)
        {
            getMinComponent()->setSize(minSize);
        }
        if(getMinComponent()->getPosition() != minPos)
        {
            getMinComponent()->setPosition(minPos);
        }
    }
    if (getMaxComponent() != NULL)
    {
        if(getMaxComponent()->getSize() != maxSize)
        {
            getMaxComponent()->setSize(maxSize);
        }
        if(getMaxComponent()->getPosition() != maxPos)
        {
            getMaxComponent()->setPosition(maxPos);
        }
    }
    if (getDividerDrawObject() != NULL)
    {
        if(getDividerDrawObject()->getSize() != divSize)
        {
            getDividerDrawObject()->setSize(divSize);
        }
        if(getDividerDrawObject()->getPosition() != divPos)
        {
            getDividerDrawObject()->setPosition(divPos);
        }
    }
}
Beispiel #26
0
void GdsNode::build( Node* node )
{
	int iNumChildren = 0;
	int iCountOfFace = node->m_iCountOfFace;

	Node* pChild[8];
	for (int i=0;i<8 ;i++)
		pChild[i] = NULL;//node->pChild[i];

	// 리프 노드는 바로 리턴
	if( iCountOfFace <= m_iLimitedCountOfFacePerNode)
		return;

	// 각 자식에 속하는 평면의 개수 셈
	D3DXVECTOR3 p0, p1, p2;
	int iFaceCount0 = 0, iFaceCount1 = 0, iFaceCount2 = 0, iFaceCount3 = 0;
	int iFaceCount4 = 0, iFaceCount5 = 0, iFaceCount6 = 0, iFaceCount7 = 0, iFaceCount8 = 0;
	GDSINDEX* pTempFace = NULL;

	D3DXVECTOR3 m_cenPos = node->m_cenPos;
	D3DXVECTOR3 m_minPos = node->m_minPos;
	D3DXVECTOR3 m_maxPos = node->m_maxPos;

	for(int i = 0; i < iCountOfFace ; ++i)
	{
		p0 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._0].p.x);
		p1 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._1].p.x);
		p2 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._2].p.x);

		if(
			// 아래 왼쪽 뒤
			(p0.x <= m_cenPos.x && p0.y <= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y <= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y <= m_cenPos.y && p2.z <= m_cenPos.z)
			) 
			++iFaceCount0;
		else if(
			// 아래 오른쪽 뒤
			(p0.x >= m_cenPos.x && p0.y <= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y <= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y <= m_cenPos.y && p2.z <= m_cenPos.z)
			)
			++iFaceCount1;
		else if(
			// 아래 왼쪽 앞
			(p0.x <= m_cenPos.x && p0.y <= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y <= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y <= m_cenPos.y && p2.z >= m_cenPos.z)
			)
			++iFaceCount2;
		else if(
			// 아래 오른쪽 앞
			(p0.x >= m_cenPos.x && p0.y <= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y <= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y <= m_cenPos.y && p2.z >= m_cenPos.z)
			) 
			++iFaceCount3;
		else if(
			// 위 왼쪽 뒤
			(p0.x <= m_cenPos.x && p0.y >= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y >= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y >= m_cenPos.y && p2.z <= m_cenPos.z)
			) 
			++iFaceCount4;
		else if(
			// 위 오른쪽 뒤
			(p0.x >= m_cenPos.x && p0.y >= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y >= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y >= m_cenPos.y && p2.z <= m_cenPos.z)
			) 
			++iFaceCount5;
		else if(
			// 위 왼쪽 앞
			(p0.x <= m_cenPos.x && p0.y >= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y >= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y >= m_cenPos.y && p2.z >= m_cenPos.z)
			) 
			++iFaceCount6;
		else if(
			// 위 오른쪽 앞
			(p0.x >= m_cenPos.x && p0.y >= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y >= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y >= m_cenPos.y && p2.z >= m_cenPos.z)
			) 
			++iFaceCount7;
		else{
			// 여러 자식에 걸쳐있는 평면
			++iFaceCount8;
		}
	}

	// 평면을 가진 자식만 생성
	if(iFaceCount0 > 0)
	{
		++iNumChildren;
		pChild[0] = new Node(iFaceCount0, m_minPos, m_cenPos);
	}
	if(iFaceCount1 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_cenPos.x, m_minPos.y, m_minPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_maxPos.x, m_cenPos.y, m_cenPos.z);
		pChild[1] = new Node(iFaceCount1, minPos , maxPos );
	}
	if(iFaceCount2 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_minPos.x, m_minPos.y, m_cenPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_cenPos.x, m_cenPos.y, m_maxPos.z);
		pChild[2] = new Node(iFaceCount2, minPos , maxPos );
	}
	if(iFaceCount3 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_cenPos.x, m_minPos.y, m_cenPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_maxPos.x, m_cenPos.y, m_maxPos.z);
		pChild[3] = new Node(iFaceCount3, minPos, maxPos);
	}
	if(iFaceCount4 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_minPos.x, m_cenPos.y, m_minPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_cenPos.x, m_maxPos.y, m_cenPos.z);
		pChild[4] = new Node(iFaceCount4, minPos, maxPos);
	}
	if(iFaceCount5 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_cenPos.x, m_cenPos.y, m_minPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_maxPos.x, m_maxPos.y, m_cenPos.z);
		pChild[5] = new Node(iFaceCount5, minPos, maxPos);
	}
	if(iFaceCount6 > 0)
	{
		++iNumChildren;
		D3DXVECTOR3 minPos = D3DXVECTOR3(m_minPos.z, m_cenPos.y, m_cenPos.z);
		D3DXVECTOR3 maxPos = D3DXVECTOR3(m_cenPos.x, m_maxPos.y, m_maxPos.z);
		pChild[6] = new Node(iFaceCount6, minPos, maxPos);
	}
	if(iFaceCount7 > 0)
	{
		++iNumChildren;
		pChild[7] = new Node(iFaceCount7, m_cenPos, m_maxPos);
	}
	if(iFaceCount8 > 0)
	{
		pTempFace = new GDSINDEX[iFaceCount8];
	}

	// 자식에 속하는 평면을 모두 추가
	iFaceCount0 = 0, iFaceCount1 = 0, iFaceCount2 = 0, iFaceCount3 = 0;
	iFaceCount4 = 0, iFaceCount5 = 0, iFaceCount6 = 0, iFaceCount7 = 0, iFaceCount8 = 0;

	for(int i = 0; i < iCountOfFace; ++i)
	{
		p0 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._0].p.x);
		p1 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._1].p.x);
		p2 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._2].p.x);

		if(pChild[0] &&
			(p0.x <= m_cenPos.x && p0.y <= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y <= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y <= m_cenPos.y && p2.z <= m_cenPos.z)
			) 
			pChild[0]->m_pFace[iFaceCount0++] = node->m_pFace[i];
		else if(pChild[1] &&
			(p0.x >= m_cenPos.x && p0.y <= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y <= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y <= m_cenPos.y && p2.z <= m_cenPos.z)
			)
			pChild[1]->m_pFace[iFaceCount1++] = node->m_pFace[i];
		else if(pChild[2] &&
			(p0.x <= m_cenPos.x && p0.y <= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y <= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y <= m_cenPos.y && p2.z >= m_cenPos.z)
			)
			pChild[2]->m_pFace[iFaceCount2++] = node->m_pFace[i];
		else if(pChild[3] &&
			(p0.x >= m_cenPos.x && p0.y <= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y <= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y <= m_cenPos.y && p2.z >= m_cenPos.z)
			)
			pChild[3]->m_pFace[iFaceCount3++] = node->m_pFace[i];
		else if(pChild[4] &&
			(p0.x <= m_cenPos.x && p0.y >= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y >= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y >= m_cenPos.y && p2.z <= m_cenPos.z)
			)
			pChild[4]->m_pFace[iFaceCount4++] = node->m_pFace[i];
		else if(pChild[5] &&
			(p0.x >= m_cenPos.x && p0.y >= m_cenPos.y && p0.z <= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y >= m_cenPos.y && p1.z <= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y >= m_cenPos.y && p2.z <= m_cenPos.z)
			)
			pChild[5]->m_pFace[iFaceCount5++] = node->m_pFace[i];
		else if(pChild[6] &&
			(p0.x <= m_cenPos.x && p0.y >= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x <= m_cenPos.x && p1.y >= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x <= m_cenPos.x && p2.y >= m_cenPos.y && p2.z >= m_cenPos.z)
			)
			pChild[6]->m_pFace[iFaceCount6++] = node->m_pFace[i];
		else if(pChild[7] &&
			(p0.x >= m_cenPos.x && p0.y >= m_cenPos.y && p0.z >= m_cenPos.z) &&
			(p1.x >= m_cenPos.x && p1.y >= m_cenPos.y && p1.z >= m_cenPos.z) &&
			(p2.x >= m_cenPos.x && p2.y >= m_cenPos.y && p2.z >= m_cenPos.z)
			)
			pChild[7]->m_pFace[iFaceCount7++] = node->m_pFace[i];
		else
		{
			pTempFace[iFaceCount8] = node->m_pFace[i];
			++iFaceCount8;
		}
	}

	for (int i=0;i<8 ;i++)
		node->m_pChild[i] = pChild[i];
	m_iCountOfOctreeNode += iNumChildren;
	node->m_iNumOfChild = iNumChildren;
	// 리프 노드가 아니므로 평면 제거
	if(node->m_pFace)
	{
		SAFE_DELETE( node->m_pFace );
		iCountOfFace = 0;
	}
	if(pTempFace)
	{
		node->m_pFace = pTempFace;
		iCountOfFace = iFaceCount8;

		//페이스에 대한 minPos, maxPos를 갱신한다.
		D3DXVECTOR3 p0 , p1 , p2;
		D3DXVECTOR3 minPos( 0,0,0 );
		D3DXVECTOR3 maxPos( 0,0,0 );
		for(int i = 0; i < iCountOfFace ; ++i)
		{
			p0 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._0].p.x);
			p1 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._1].p.x);
			p2 = D3DXVECTOR3(&m_pVert[node->m_pFace[i]._2].p.x);
			
			if ( minPos.x > p0.x )
				minPos.x = p0.x;
			if ( minPos.y > p0.y )
				minPos.y = p0.y;
			if ( minPos.z > p0.z )
				minPos.z = p0.z;
			if ( maxPos.x < p0.x )
				maxPos.x = p0.x;
			if ( maxPos.y < p0.y )
				maxPos.y = p0.y;
			if ( maxPos.z < p0.z )
				maxPos.z = p0.z;

			if ( minPos.x > p1.x )
				minPos.x = p1.x;
			if ( minPos.y > p1.y )
				minPos.y = p1.y;
			if ( minPos.z > p1.z )
				minPos.z = p1.z;
			if ( maxPos.x < p1.x )
				maxPos.x = p1.x;
			if ( maxPos.y < p1.y )
				maxPos.y = p1.y;
			if ( maxPos.z < p1.z )
				maxPos.z = p1.z;

			if ( minPos.x > p2.x )
				minPos.x = p2.x;
			if ( minPos.y > p2.y )
				minPos.y = p2.y;
			if ( minPos.z > p2.z )
				minPos.z = p2.z;
			if ( maxPos.x < p2.x )
				maxPos.x = p2.x;
			if ( maxPos.y < p2.y )
				maxPos.y = p2.y;
			if ( maxPos.z < p2.z )
				maxPos.z = p2.z;
		}

		node->m_minPos = minPos;
		node->m_maxPos = maxPos;
		node->m_cenPos = (minPos+maxPos)*0.5;

	}

	D3DXVECTOR3 dist( m_cenPos - m_minPos );
	node->m_fRadius = D3DXVec3Length( &dist );
	node->m_iCountOfFace = iCountOfFace;

	// 자식 노드 재귀 호출
	if(node->m_pChild[0]) build( node->m_pChild[0] );
	if(node->m_pChild[1]) build( node->m_pChild[1] );
	if(node->m_pChild[2]) build( node->m_pChild[2] );
	if(node->m_pChild[3]) build( node->m_pChild[3] );
	if(node->m_pChild[4]) build( node->m_pChild[4] );
	if(node->m_pChild[5]) build( node->m_pChild[5] );
	if(node->m_pChild[6]) build( node->m_pChild[6] );
	if(node->m_pChild[7]) build( node->m_pChild[7] );
}
// expire or move existing touches based on new signal input. 
// 
void TouchTracker::updateTouches(const MLSignal& in)
{
	// copy input signal to border land
	int width = in.getWidth();
	int height = in.getHeight();
	
	mTemp.copy(in);
	mTemplateMask.clear();
	
	// sort active touches by Z
	// copy into sorting container, referring back to unsorted touches
	int activeTouches = 0;
	for(int i = 0; i < mMaxTouchesPerFrame; ++i)
	{
		Touch& t = mTouches[i];
		if (t.isActive())
		{
			t.unsortedIdx = i;
			mTouchesToSort[activeTouches++] = t;
		}
	}

	std::sort(mTouchesToSort.begin(), mTouchesToSort.begin() + activeTouches, compareTouchZ());

	// update active touches in sorted order, referring to existing touches in place
	for(int i = 0; i < activeTouches; ++i)
	{
		int refIdx = mTouchesToSort[i].unsortedIdx;
		Touch& t = mTouches[refIdx];
		Vec2 pos(t.x, t.y); 
		Vec2 newPos = pos;
		float newX = t.x;
		float newY = t.y;
		float newZ = in.getInterpolatedLinear(pos);
		
		// if not preparing to remove, update position.
		if (t.releaseCtr == 0)
		{
			Vec2 minPos(0, 0);
			Vec2 maxPos(width, height);
			int ix = floor(pos.x() + 0.5f);
			int iy = floor(pos.y() + 0.5f);		
			
			// move to any higher neighboring integer value
			Vec2 newPeak;
			newPeak = adjustPeak(mTemp, ix, iy);			
			Vec2 newPeakI, newPeakF;
			newPeak.getIntAndFracParts(newPeakI, newPeakF);
			int newPx = newPeakI.x();
			int newPy = newPeakI.y();
			
			// get exact location and new key
			Vec2 correctPos = mTemp.correctPeak(newPx, newPy);
			newPos = correctPos;	
			int newKey = getKeyIndexAtPoint(newPos);												
			
			// move the touch.  
			if((newKey == t.key) || !keyIsOccupied(newKey))
			{			
				// This must be the only place a touch can move from key to key.
				pos = newPos;
				newX = pos.x();
				newY = pos.y();					
				t.key = newKey;
			}							
		}
		
		// look for reasons to release
		newZ = in.getInterpolatedLinear(newPos);
		bool thresholdTest = (newZ > mOffThreshold);			
		float inhibit = getInhibitThreshold(pos);
		bool inhibitTest = (newZ > inhibit);
		t.tDist = mCalibrator.differenceFromTemplateTouchWithMask(mTemp, pos, mTemplateMask);
		bool templateTest = (t.tDist < mTemplateThresh);
		bool overrideTest = (newZ > mOverrideThresh);
						
		t.age++;

		// handle release		
		// TODO get releaseDetect: evidence that touch has been released.
		// from matching release curve over ~ 50 samples. 
		if (!thresholdTest || (!templateTest && !overrideTest) || (!inhibitTest))
		{			
			/* debug
			if(!thresholdTest && (t.releaseCtr == 0))
			{
				debug() << refIdx << " REL thresholdFail: " << newZ << " at " << pos << "\n";	
			}
			if(!inhibitTest && (t.releaseCtr == 0))
			{
				debug() << refIdx << " REL inhibitFail: " << newZ << " < " << inhibit << "\n";	
			}
			if(!templateTest && (t.releaseCtr == 0))
			{
				debug() << refIdx << " REL templateFail: " << t.tDist << " at " << pos << "\n";	
			}			
			*/
			if(t.releaseCtr == 0)
			{
				t.releaseSlope = t.z / (float)kTouchReleaseFrames;
			}
			t.releaseCtr++;
			newZ = t.z - t.releaseSlope;
		}
		else
		{	
			// reset off counter 
			t.releaseCtr = 0;	
		}

		// filter position and assign new touch values
		const float e = 2.718281828;
		float xyCutoff = (newZ - mOnThreshold) / (mMaxForce*0.25);
		xyCutoff = clamp(xyCutoff, 0.f, 1.f);
		xyCutoff *= xyCutoff;
		xyCutoff *= xyCutoff;
		xyCutoff = xyCutoff*100.;
		xyCutoff = clamp(xyCutoff, 1.f, 100.f);
		float x = powf(e, -kMLTwoPi * xyCutoff / (float)mSampleRate);
		float a0 = 1.f - x;
		float b1 = -x;
		t.dz = newZ - t.z;	
		
		// these can't be filtered too much or updateTouches will not work
		// for fast movements.  Revisit when we rewrite the touch tracker.		
		t.x = a0*newX - b1*t.x;
		t.y = a0*newY - b1*t.y;
		t.z = newZ;
		
		// filter z based on user lowpass setting and touch age
		float lp = mLopass;
		lp -= t.age*(mLopass*0.75f/kAttackFrames);
		lp = clamp(lp, mLopass, mLopass*0.25f);	// WTF???		
				
		float xz = powf(e, -kMLTwoPi * lp / (float)mSampleRate);
		float a0z = 1.f - xz;
		float b1z = -xz;
		t.zf = a0z*(newZ - mOnThreshold) - b1z*t.zf;	
				
		
		// remove touch if filtered z is below threshold
		if(t.zf < 0.)
		{
			// debug() << refIdx << " OFF with z:" << t.z << " td:" << t.tDist <<  "\n";	
			removeTouchAtIndex(refIdx);
		}
		
		// subtract updated touch from the input sum.
		// mTemplateScaled is scratch space. 
		mTemplateScaled.clear();
		mTemplateScaled.add2D(mCalibrator.getTemplate(pos), 0, 0);
		mTemplateScaled.scale(-t.z*mCalibrator.getZAdjust(pos)); 
														
		mTemp.add2D(mTemplateScaled, Vec2(pos - Vec2(kTemplateRadius, kTemplateRadius)));
		mTemp.sigMax(0.0);

		// add touch neighborhood to template mask. This allows crowded touches
		// to pass the template test by ignoring areas shared with other touches.
		Vec2 maskPos(t.x, t.y);
		const MLSignal& tmplate = mCalibrator.getTemplate(maskPos);
		mTemplateMask.add2D(tmplate, maskPos - Vec2(kTemplateRadius, kTemplateRadius));
	}
}
Beispiel #28
0
bool SGFParser::doParse(const QString &toParseStr, bool fastLoad)
{
	if (toParseStr.isNull() || toParseStr.isEmpty())
	{
		qWarning("Failed loading from file. Is it empty?");
		return false;
	}
	
	const MyString *toParse = NULL;
	if (static_cast<Codec>(setting->readIntEntry("CODEC")) == codecNone)
		toParse = new MySimpleString(toParseStr);
	else
		toParse = new MyString(toParseStr);
	CHECK_PTR(toParse);
	
	int pos = 0,
		posVarBegin = 0,
		posVarEnd = 0,
		posNode = 0,
		moves = 0,
		i, x=-1, y=-1;
	unsigned int pointer = 0,
		strLength = toParse->length();
	bool black = true,
		setup = false,
		old_label = false,
		new_node = false;
	isRoot = true;
	bool remember_root;
	QString unknownProperty;
	State state;
	MarkType markType;
	QString moveStr, commentStr;
	Position *position;
	MoveNum *moveNum;
	QPtrStack<Move> stack;
	QPtrStack<MoveNum> movesStack;
	QPtrStack<Position> toRemove;
	stack.setAutoDelete(FALSE);
	movesStack.setAutoDelete(TRUE);
	toRemove.setAutoDelete(TRUE);
	Tree *tree = boardHandler->getTree();
	
	state = stateVarBegin;
	
	bool cancel = false;
	int progressCounter = 0;
	QProgressDialog progress(Board::tr("Reading sgf file..."), Board::tr("Abort"), strLength,
		boardHandler->board, "progress", true);
	
	// qDebug("File length = %d", strLength);
	
	progress.setProgress(0);
	QString sss="";
	do {
		if (!(++progressCounter%10))
		{
			progress.setProgress(pointer);
			if (progress.wasCancelled())
			{
				cancel = true;
				break;
			}
		}
		
		// qDebug("POINTER = %d: %c", pointer, toParse->Str[pointer]);
		
		posVarBegin = toParse->find('(', pointer);
		posVarEnd = toParse->find(')', pointer);
		posNode = toParse->find(';', pointer);
		
		pos = minPos(posVarBegin, posVarEnd, posNode);
		// qDebug("VarBegin %d, VarEnd %d, Move %d, MINPOS %d", posVarBegin, posVarEnd, posNode, pos);

		// qDebug("State before switch = %d", state);

		// Switch states

		// Node -> VarEnd
		if (state == stateNode && pos == posVarEnd)
			state = stateVarEnd;
		
		// Node -> VarBegin
		if (state == stateNode && pos == posVarBegin)
			state = stateVarBegin;
		
		// VarBegin -> Node
		else if (state == stateVarBegin && pos == posNode)
			state = stateNode;
		
		// VarEnd -> VarBegin
		else if (state == stateVarEnd && pos == posVarBegin)
			state = stateVarBegin;
		
		// qDebug("State after switch = %d", state);
		
		// Do the work
		switch (state)
		{
		case stateVarBegin:
			if (pos != posVarBegin)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("Var BEGIN at %d, moves = %d", pos, moves);
			
			stack.push(tree->getCurrent());
			moveNum = new MoveNum;
			moveNum->n = moves;
			movesStack.push(moveNum);
			pointer = pos + 1;
			break;
			
		case stateVarEnd:
			if (pos != posVarEnd)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("VAR END");
			
			if (!movesStack.isEmpty() && !stack.isEmpty())
			{
				Move *m = stack.pop();
				CHECK_PTR(m);
				x = movesStack.pop()->n;
				
				// qDebug("Var END at %d, moves = %d, moves from stack = %d", pos, moves, x);
				
				for (i=moves; i > x; i--)
				{
					position = toRemove.pop();
					if (position == NULL)
						continue;
					boardHandler->getStoneHandler()->removeStone(position->x, position->y);
					// qDebug("Removing %d %d from stoneHandler.", position->x, position->y);
				}
				
				moves = x;
				
				if (!fastLoad)
					boardHandler->getStoneHandler()->updateAll(m->getMatrix(), false);
				
				tree->setCurrent(m);
			}
			pointer = pos + 1;
			break;
			
		case stateNode:
			if (pos != posNode)
			{
				delete toParse;
				return corruptSgf(pos);
			}
			
			// qDebug("Node at %d", pos);
			commentStr = QString();
			setup = false;
			markType = markNone;
			
			// Create empty node
			remember_root = isRoot;
			if (!isRoot)
			{
				boardHandler->createMoveSGF();
				unknownProperty = QString();
if (tree->getCurrent()->getTimeinfo())
	qWarning("*** Timeinfo set !!!!");
				//tree->getCurrent()->setTimeinfo(false);
			}
			else
				isRoot = false;
			
			new_node = true;
			
			Property prop;
			pos ++;

			do {
				uint tmppos=0;
				pos = toParse->next_nonspace (pos);
				
				// qDebug("READING PROPERTY AT %d: %c", pos, toParse->at(pos));
				
				// if (toParse->find("B[", pos) == pos)
				if (toParse->at(pos) == 'B' && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = moveBlack;
					pos = tmppos;
					black = true;
				}
				// else if (toParse->find("W[", pos) == pos)
				else if (toParse->at(pos) == 'W' && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = moveWhite;
					pos = tmppos;
					black = false;
				}
				else if (toParse->at(pos) == 'N' && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = nodeName;
					pos = tmppos;
				}
				else if (toParse->find("AB", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editBlack;
					pos = tmppos;
					setup = true;
					black = true;
				}
				else if (toParse->find("AW", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editWhite;
					pos = tmppos;
					setup = true;
					black = false;
				}
				else if (toParse->find("AE", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editErase;
					pos = tmppos;
					setup = true;
				}
				else if (toParse->find("TR", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markTriangle;
					pos = tmppos;
				}
				else if (toParse->find("CR", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markCircle;
					pos = tmppos;
				}
				else if (toParse->find("SQ", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markSquare;
					pos = tmppos;
				}
				else if (toParse->find("MA", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markCross;
					pos = tmppos;
				}
				// old definition
				else if (toParse->find("M", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = editMark;
					markType = markCross;
					pos = tmppos;
				}
				else if (toParse->find("LB", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markText;
					pos = tmppos;
					old_label = false;
				}
				// Added old L property. This is not SGF4, but many files contain this tag.
				else if (toParse->at(pos) == 'L' && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = editMark;
					markType = markText;
					pos = tmppos;
					old_label = true;
				}
				else if (toParse->at(pos) == 'C' && toParse->at(tmppos = toParse->next_nonspace (pos + 1)) == '[')
				{
					prop = comment;
					pos = tmppos;
				}
				else if (toParse->find("TB", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markTerrBlack;
					pos = tmppos;
					black = true;
				}
				else if (toParse->find("TW", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = editMark;
					markType = markTerrWhite;
					pos = tmppos;
					black = false;
				}
				else if (toParse->find("BL", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = timeLeft;
					pos = tmppos;
					black = true;
				}
				else if (toParse->find("WL", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = timeLeft;
					pos = tmppos;
					black = false;
				}
				else if (toParse->find("OB", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = openMoves;
					pos = tmppos;
					black = true;
				}
				else if (toParse->find("OW", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = openMoves;
					pos = tmppos;
					black = false;
				}
				else if (toParse->find("PL", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = nextMove;
					pos = tmppos;
				}
        else if (toParse->find("RG", pos) == pos && toParse->at(tmppos = toParse->next_nonspace (pos + 2)) == '[')
				{
					prop = unknownProp;
					pos = tmppos;
          setup = true;
				}
				// Empty node
				else if (toParse->at(pos) == ';' || toParse->at(pos) == '(' || toParse->at(pos) == ')')
				{
					qDebug("Found empty node at %d", pos);
					while (toParse->at(pos).isSpace())
						pos++;
					continue;
				}
				else
				{
					// handle like comment
					prop = unknownProp;
					pos = toParse->next_nonspace (pos);
//qDebug("SGF: next nonspace (1st):" + QString(toParse->at(pos)) + QString(toParse->at(pos+1)) + QString(toParse->at(pos+2)));
				}
				
				// qDebug("FOUND PROP %d, pos at %d now", prop, pos);
				
				// Next is one or more '[xx]'.
				// Only one in a move property, several in a setup propery
				do {
					if (toParse->at(pos) != '[' && prop != unknownProp)
					{
						delete toParse;
						return corruptSgf(pos);
					}
					
					// Empty type
					if (toParse->at(pos+1) == ']')
					{
						// CGoban stores pass as 'B[]' or 'W[]'
						if (prop == moveBlack || prop == moveWhite)
						{
							boardHandler->doPass(true);
							
							// Remember this move for later, to remove from the matrix.
							position = new Position;
							position->x = x;
							position->y = y;
							toRemove.push(position);
							moves ++;
						}
						
						pos += 2;
						continue;
					}
					
					switch (prop)
					{
					case moveBlack:
					case moveWhite:
						// rare case: root contains move or placed stone:
						if (remember_root)
						{
							qDebug("root contains stone -> node created");
							boardHandler->createMoveSGF();
							unknownProperty = QString();
							isRoot = false;
if (tree->getCurrent()->getTimeinfo())
	qWarning("*** Timeinfo set !!!!");
							//tree->getCurrent()->setTimeinfo(false);
						}
					case editBlack:
					case editWhite:
					case editErase:
					{
						x = toParse->at(pos+1) - 'a' + 1;
						y = toParse->at(pos+2) - 'a' + 1;

						int x1, y1;
						bool compressed_list;

						// check for compressed lists
						if (toParse->at(pos+3) == ':')
						{
							x1 = toParse->at(pos+4) - 'a' + 1;
							y1 = toParse->at(pos+5) - 'a' + 1;
							compressed_list = true;
						}
						else
						{
							x1 = x;
							y1 = y;
							compressed_list = false;
						}
						
						boardHandler->setModeSGF(setup || compressed_list ? modeEdit : modeNormal);
						
						int i, j;
						for (i = x; i <= x1; i++)
							for (j = y; j <= y1; j++)
							{
								if (i == 20 && j == 20)
									boardHandler->doPass(true);
								else if (prop == editErase)
								{
									if (!fastLoad)
										boardHandler->removeStone(i, j, true, false);
									else
									{
										tree->getCurrent()->setX(0);
										tree->getCurrent()->setY(0);
										tree->getCurrent()->setColor(stoneNone);
									}
								}
								else
								{
									if (!fastLoad)
										boardHandler->addStoneSGF(black ? stoneBlack : stoneWhite, i, j, new_node);
									else
									{
										tree->getCurrent()->setX(i);
										tree->getCurrent()->setY(j);
										tree->getCurrent()->setColor(black? stoneBlack : stoneWhite);
									}
								}
								// tree->getCurrent()->getMatrix()->debug();
								// qDebug("ADDING MOVE %s %d/%d", black?"B":"W", x, y);
								
								// Remember this move for later, to remove from the matrix.
								position = new Position;
								position->x = i;
								position->y = j;
								toRemove.push(position);
								moves ++;
							}
						
						new_node = false;
						
						if (compressed_list)
							// Advance pos by 7
							pos += 7;
						else
							// Advance pos by 4
							pos += 4;
						break;
					}
						
					case nodeName:
					{
						commentStr = QString();
						bool skip = false;
						
						while (toParse->at(++pos) != ']')
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Nodename string ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Nodename string ended immediately");
							}

							// white spaces
							if (toParse->at(pos) == '\\')
							{
								while (toParse->at(pos+1).isSpace() &&
									static_cast<unsigned int>(pos) < strLength-2)
									pos++;
								if (toParse->at(pos).isSpace())
									pos++;

								// case: "../<cr><lf>]"
								if (toParse->at(pos) == ']')
								{
									pos--;
									skip = true;
								}
							}

							// escaped chars: '\', ']', ':'
							if (!(toParse->at(pos) == '\\' &&
								(toParse->at(pos+1) == ']' ||
								 toParse->at(pos+1) == '\\' ||
								 toParse->at(pos+1) == ':')) &&
								 !skip &&
								 // no formatting
								!(toParse->at(pos) == '\n') &&
								!(toParse->at(pos) == '\r'))
								commentStr.append(toParse->at(pos));
						}

						// qDebug("Comment read: %s", commentStr.latin1());
						if (commentStr)
							// add comment; skip 'C[]'
							tree->getCurrent()->setNodeName(commentStr);
						pos++;
						break;
					}

					case comment:
					{
						commentStr = QString();
						bool skip = false;
						
						while (toParse->at(++pos) != ']' ||
							(toParse->at(pos-1) == '\\' && toParse->at(pos) == ']'))
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Comment string ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Comment string ended immediately");
							}

							// white spaces
							if (toParse->at(pos) == '\\')
							{
								while (toParse->at(pos+1).isSpace() &&
									static_cast<unsigned int>(pos) < strLength-2)
									pos++;
								if (toParse->at(pos).isSpace())
									pos++;

								// case: "../<cr><lf>]"
								if (toParse->at(pos) == ']')
								{
									pos--;
									skip = true;
								}
							}

							// escaped chars: '\', ']', ':'
							if (!(toParse->at(pos) == '\\' &&
								(toParse->at(pos+1) == ']' ||
								 toParse->at(pos+1) == '\\' ||
								 toParse->at(pos+1) == ':')) &&
								 !skip)
								commentStr.append(toParse->at(pos));
						}

						// qDebug("Comment read: %s", commentStr.latin1());
						if (commentStr)
						{
							// add comment; skip 'C[]'
							tree->getCurrent()->setComment(commentStr);
						}
						pos ++;
						break;
					}

					case unknownProp:
					{
						// skip if property is known anyway
						bool skip = false;

						// save correct property name (or p.n. + '[')
						commentStr = toParse->at(pos);
						commentStr += toParse->at(tmppos = toParse->next_nonspace (pos + 1));
						pos = tmppos;

						// check if it's really necessary to hold properties
						// maybe they are handled at another position
						if (commentStr == "WR" ||
							commentStr == "BR" ||
							commentStr == "PW" ||
							commentStr == "PB" ||
							commentStr == "SZ" ||
							commentStr == "KM" ||
							commentStr == "HA" ||
							commentStr == "RE" ||
							commentStr == "DT" ||
							commentStr == "PC" ||
							commentStr == "CP" ||
							commentStr == "GN" ||
							commentStr == "OT" ||
							commentStr == "TM" ||
							// now: general options
							commentStr == "GM" ||
							commentStr == "ST" ||
							commentStr == "AP" ||
							commentStr == "FF")
						{
							skip = true;
						}
						sss= toParse->at(pos);
						while (toParse->at(++pos) != ']' ||
							(toParse->at(pos-1) == '\\' && toParse->at(pos) == ']'))
						{
							if (static_cast<unsigned int>(pos) > strLength-1)
							{
								qDebug("SGF: Unknown property ended immediately");
								delete toParse;
								return corruptSgf(pos, "SGF: Unknown property ended immediately");
							}
              sss= toParse->at(pos);
							if (!skip)
								commentStr.append(toParse->at(pos));
						}

						if (!skip)
							commentStr.append("]");

						// qDebug("Comment read: %s", commentStr.latin1());
						if (commentStr && !skip)
						{
							// cumulate unknown properties; skip empty property 'XZ[]'
							unknownProperty += commentStr;
							tree->getCurrent()->setUnknownProperty(unknownProperty);
						}
						pos ++;
            sss= toParse->at(pos);
						break;
					}

					case editMark:
						// set moveStr for increment labels of old 'L[]' property
						moveStr = "A";
						while (toParse->at(pos) == '[' &&
							static_cast<unsigned int>(pos) < strLength)
						{
							x = toParse->at(pos+1) - 'a' + 1;
							y = toParse->at(pos+2) - 'a' + 1;
							// qDebug("MARK: %d at %d/%d", markType, x, y);
							pos += 3;
							
							// 'LB' property? Then we need to get the text
							if (markType == markText && !old_label)
							{
								if (toParse->at(pos) != ':')
								{
									delete toParse;
									return corruptSgf(pos);
								}
								moveStr = "";
								while (toParse->at(++pos) != ']' &&
									static_cast<unsigned int>(pos) < strLength)
									moveStr.append(toParse->at(pos));
								// qDebug("LB TEXT = %s", moveStr.latin1());
								// It might me a number mark?
								bool check = false;
								moveStr.toInt(&check);  // Try to convert to Integer
// treat integers as characters...
check = false;
								
								if (!fastLoad)
								{
									if (check)
										tree->getCurrent()->getMatrix()->
										insertMark(x, y, markNumber);  // Worked, its a number
									else
										tree->getCurrent()->getMatrix()->
										insertMark(x, y, markType);    // Nope, its a letter
									tree->getCurrent()->getMatrix()->
										setMarkText(x, y, moveStr);
								}
								else
								{
									if (check)  // Number
										tree->getCurrent()->insertFastLoadMark(x, y, markNumber);
									else        // Text
										tree->getCurrent()->insertFastLoadMark(x, y, markType, moveStr);
								}
							}
							else
							{
								int x1, y1;
								bool compressed_list;

								// check for compressed lists
								if (toParse->at(pos) == ':')
								{
									x1 = toParse->at(pos+1) - 'a' + 1;
									y1 = toParse->at(pos+2) - 'a' + 1;
									compressed_list = true;
								}
								else
								{
									x1 = x;
									y1 = y;
									compressed_list = false;
								}
								
//								boardHandler->setModeSGF(setup || compressed_list ? modeEdit : modeNormal);
								
								int i, j;
								for (i = x; i <= x1; i++)
									for (j = y; j <= y1; j++)
									{
										if (!fastLoad)
											tree->getCurrent()->getMatrix()->insertMark(i, j, markType);
										else
											tree->getCurrent()->insertFastLoadMark(i, j, markType);

										// auto increment for old property 'L'
										if (old_label)
										{
											tree->getCurrent()->getMatrix()->
												setMarkText(x, y, moveStr);
											QChar c1 = moveStr[0];
											if (c1 == 'Z')
												moveStr = QString("a");
											else
												moveStr = c1.unicode() + 1;
										}
									}

//								new_node = false;

								if (compressed_list)
									// Advance pos by 3
									pos += 3;
							}

							//old_label = false;
							pos ++;
							while (toParse->at(pos).isSpace()) pos++;
						}
						break;

					case openMoves:
					{
						QString tmp_mv;
						while (toParse->at(++pos) != ']')
							tmp_mv += toParse->at(pos);
						tree->getCurrent()->setOpenMoves(tmp_mv.toInt());
						pos++;

						if (!tree->getCurrent()->getTimeinfo())
						{
							tree->getCurrent()->setTimeinfo(true);
							tree->getCurrent()->setTimeLeft(0);
						}
						break;
					}

					case timeLeft:
					{
						QString tmp_mv;
						while (toParse->at(++pos) != ']')
							tmp_mv += toParse->at(pos);
						tree->getCurrent()->setTimeLeft(tmp_mv.toFloat());
						pos++;

						if (!tree->getCurrent()->getTimeinfo())
						{
							tree->getCurrent()->setTimeinfo(true);
							tree->getCurrent()->setOpenMoves(0);
						}
						break;
					}

					case nextMove:
						if (toParse->at(++pos) == 'W')
							tree->getCurrent()->setPLinfo(stoneWhite);
						else if (toParse->at(pos) == 'B')
							tree->getCurrent()->setPLinfo(stoneBlack);

						pos += 2;
						break;

					default:
						break;
		    }

		    while (toParse->at(pos).isSpace())
			    pos++;
        sss= toParse->at(pos);
		} while (setup && toParse->at(pos) == '[');
		
		//tree->getCurrent()->getMatrix()->debug();
		while (toParse->at(pos).isSpace())
			pos++;

	    } while (toParse->at(pos) != ';' && toParse->at(pos) != '(' && toParse->at(pos) != ')' &&
		    static_cast<unsigned int>(pos) < strLength);
	    
	    // Advance pointer
	    pointer = pos;
	    
	    break;
	    
	default:
		delete toParse;
		return corruptSgf(pointer);
	}
	
    } while (pointer < strLength && pos >= 0);
    
    progress.setProgress(strLength);
    
    delete toParse;
    return !cancel;
}