Exemplo n.º 1
0
int MidEvaluator::evaluate(const Board& board)
{
	EdgeStat edgestat;
	CornerStat cornerstat;
	int result;

	//
	//	辺の評価
	//

	edgestat  = EdgeTable[idxTop(board)];
	edgestat += EdgeTable[idxBottom(board)];
	edgestat += EdgeTable[idxRight(board)];
	edgestat += EdgeTable[idxLeft(board)];

	//
	//	隅の評価
	//

	cornerstat = evalCorner(board);

	// 確定石に関して、隅の石を2回数えてしまっているので補正。

	edgestat[BLACK].stable -= cornerstat[BLACK].corner;
	edgestat[WHITE].stable -= cornerstat[WHITE].corner;

	//
	//	パラメータの線形結合
	//

	result =
		  edgestat[BLACK].stable * EvalWeight.stable_w
		- edgestat[WHITE].stable * EvalWeight.stable_w
		+ edgestat[BLACK].wing * EvalWeight.wing_w
		- edgestat[WHITE].wing * EvalWeight.wing_w
		+ cornerstat[BLACK].Xmove * EvalWeight.Xmove_w
		- cornerstat[WHITE].Xmove * EvalWeight.Xmove_w
		+ edgestat[BLACK].Cmove * EvalWeight.Cmove_w
		- edgestat[WHITE].Cmove * EvalWeight.Cmove_w
		;

	// 開放度・着手可能手数の評価

	if(EvalWeight.liberty_w != 0)
	{
		ColorStorage<unsigned> liberty = countLiberty(board);
		result += liberty[BLACK] * EvalWeight.liberty_w;
		result -= liberty[WHITE] * EvalWeight.liberty_w;
	}

	// 現在の手番の色についてのみ、着手可能手数を数える
	result +=
		  board.getCurrentColor()
		* board.getMovablePos().size()
		* EvalWeight.mobility_w;

	return board.getCurrentColor() * result;

}
int 
OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords, 
                                             OsdCpuEvalLimitContext * context,
                                             unsigned int index ) {
    float u=coords.u,
          v=coords.v;
          
    FarPatchMap::Handle const * handle = context->GetPatchMap().FindPatch( coords.face, u, v );

    // the map may not be able to return a handle if there is a hole or the face
    // index is incorrect
    if (not handle)
        return 0;

    FarPatchParam::BitField bits = context->GetPatchBitFields()[ handle->patchIdx ];
    
    bits.Normalize( u, v );

    bits.Rotate( u, v );

    FarPatchTables::PatchArray const & parray = context->GetPatchArrayVector()[ handle->patchArrayIdx ];
    
    unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle->vertexOffset ];
    
    OsdCpuEvalLimitContext::VertexData & vertexData = context->GetVertexData();

    if (vertexData.IsBound()) {
    
        int offset = vertexData.outDesc.stride * index;
        
        // Based on patch type - go execute interpolation
        switch( parray.GetDescriptor().GetType() ) {

            case FarPatchTables::REGULAR  : if (vertexData.IsBound()) {
                                                evalBSpline( v, u, cvs,
                                                             vertexData.inDesc,
                                                             vertexData.in.GetData(),
                                                             vertexData.outDesc,
                                                             vertexData.out.GetData()+offset, 
                                                             vertexData.outDu.GetData()+offset, 
                                                             vertexData.outDv.GetData()+offset );
                                            } break;

            case FarPatchTables::BOUNDARY : if (vertexData.IsBound()) {
                                                evalBoundary( v, u, cvs,
                                                              vertexData.inDesc,
                                                              vertexData.in.GetData(),
                                                              vertexData.outDesc,
                                                              vertexData.out.GetData()+offset, 
                                                              vertexData.outDu.GetData()+offset, 
                                                              vertexData.outDv.GetData()+offset );
                                            } break;

            case FarPatchTables::CORNER   : if (vertexData.IsBound()) {
                                                evalCorner( v, u, cvs,
                                                            vertexData.inDesc,
                                                            vertexData.in.GetData(),
                                                            vertexData.outDesc,
                                                            vertexData.out.GetData()+offset,
                                                            vertexData.outDu.GetData()+offset,
                                                            vertexData.outDv.GetData()+offset );
                                            } break;


            case FarPatchTables::GREGORY  : if (vertexData.IsBound()) {
                                                evalGregory( v, u, cvs,
                                                             &context->GetVertexValenceTable()[0],
                                                             &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ],  
                                                             context->GetMaxValence(),
                                                             vertexData.inDesc,
                                                             vertexData.in.GetData(),
                                                             vertexData.outDesc,
                                                             vertexData.out.GetData()+offset, 
                                                             vertexData.outDu.GetData()+offset, 
                                                             vertexData.outDv.GetData()+offset );
                                            } break;

            case FarPatchTables::GREGORY_BOUNDARY :
                                            if (vertexData.IsBound()) {
                                                evalGregoryBoundary(v, u, cvs,
                                                                    &context->GetVertexValenceTable()[0],
                                                                    &context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ],
                                                                    context->GetMaxValence(),
                                                                    vertexData.inDesc,
                                                                    vertexData.in.GetData(),
                                                                    vertexData.outDesc,
                                                                    vertexData.out.GetData()+offset,
                                                                    vertexData.outDu.GetData()+offset,
                                                                    vertexData.outDv.GetData()+offset );
                                            } break;

            default:
                assert(0);
        }
    }
    
    OsdCpuEvalLimitContext::VaryingData & varyingData = context->GetVaryingData();

    if (varyingData.IsBound()) {

        static int indices[5][4] = { {5, 6,10, 9},  // regular
                                     {1, 2, 6, 5},  // boundary
                                     {1, 2, 5, 4},  // corner
                                     {0, 1, 2, 3},  // gregory
                                     {0, 1, 2, 3} };// gregory boundary

        int type = (int)(parray.GetDescriptor().GetType() - FarPatchTables::REGULAR);

        int offset = varyingData.outDesc.stride * index;

        unsigned int zeroRing[4] = { cvs[indices[type][0]],
                                     cvs[indices[type][1]],  
                                     cvs[indices[type][2]],  
                                     cvs[indices[type][3]]  };

        evalBilinear( v, u, zeroRing,
                      varyingData.inDesc,
                      varyingData.in.GetData(),
                      varyingData.outDesc,
                      varyingData.out.GetData()+offset);

    }
    
    // Note : currently we only support bilinear boundary interpolation rules
    // for face-varying data. Although Hbr supports 3 additional smooth rule
    // sets, the feature-adaptive patch interpolation code currently does not
    // support them, and neither does this EvalContext.
    OsdCpuEvalLimitContext::FaceVaryingData & faceVaryingData = context->GetFaceVaryingData();
    if (faceVaryingData.IsBound()) {

        FarPatchTables::FVarDataTable const & fvarData = context->GetFVarData();

        if (not fvarData.empty()) {

            int offset = faceVaryingData.outDesc.stride * index;

            static unsigned int zeroRing[4] = {0,1,2,3};

            evalBilinear( v, u, zeroRing,
                          faceVaryingData.inDesc,
                          &fvarData[ handle->patchIdx * 4 * context->GetFVarWidth() ],
                          faceVaryingData.outDesc,
                          faceVaryingData.out.GetData()+offset);
        }
    }
    
    return 1;
}