/// <summary> /// Invalidates all cached information. /// </summary> public void Invalidate() { _isDirty = true; _isBonePoseRelativeDirty.SetAll(true); _isBonePoseAbsoluteDirty.SetAll(true); _isSkinningMatrixDirty.SetAll(true); }
private void Initialize(SkeletonPose skeletonPose) { _skeletonPose = skeletonPose; if (_bonePoseRelative == null) { // The SkeletonPoseAccessor is initialized for the first time. int numberOfBones = skeletonPose.Skeleton.NumberOfBones; // Create arrays. (Note: SkinningMatrices are created on demand.) _bonePoseRelative = new SrtTransform[numberOfBones]; _bonePoseAbsolute = new SrtTransform[numberOfBones]; // Set all dirty flags. _isDirty = true; _isBonePoseRelativeDirty = new FastBitArray(numberOfBones); _isBonePoseRelativeDirty.SetAll(true); _isBonePoseAbsoluteDirty = new FastBitArray(numberOfBones); _isBonePoseAbsoluteDirty.SetAll(true); _isSkinningMatrixDirty = new FastBitArray(numberOfBones); _isSkinningMatrixDirty.SetAll(true); } else { Debug.Assert(_bonePoseRelative != null, "SkeletonBoneAccessor is not properly initialized. Array _bonePoseRelative is not set."); Debug.Assert(_bonePoseAbsolute != null, "SkeletonBoneAccessor is not properly initialized. Array _bonePoseAbsolute is not set."); Debug.Assert(_isBonePoseRelativeDirty != null, "SkeletonBoneAccessor is not properly initialized. BitArray _isBonePoseRelativeDirty is not set."); Debug.Assert(_isBonePoseAbsoluteDirty != null, "SkeletonBoneAccessor is not properly initialized. BitArray _isBonePoseAbsoluteDirty is not set."); Debug.Assert(_isSkinningMatrixDirty != null, "SkeletonBoneAccessor is not properly initialized. BitArray _isSkinningMatrixDirty is not set."); Debug.Assert(_bonePoseRelative.Length != skeletonPose.Skeleton.NumberOfBones, "SkeletonBoneAccessor is incompatible. Array _bonePoseRelative has wrong length."); Debug.Assert(_bonePoseAbsolute.Length != skeletonPose.Skeleton.NumberOfBones, "SkeletonBoneAccessor is incompatible. Array _bonePoseAbsolute has wrong length."); Debug.Assert(_isBonePoseRelativeDirty.Length != skeletonPose.Skeleton.NumberOfBones, "SkeletonBoneAccessor is incompatible. BitArray _isBonePoseRelativeDirty has wrong length."); Debug.Assert(_isBonePoseAbsoluteDirty.Length != skeletonPose.Skeleton.NumberOfBones, "SkeletonBoneAccessor is incompatible. BitArray _isBonePoseAbsoluteDirty has wrong length."); Debug.Assert(_isSkinningMatrixDirty.Length != skeletonPose.Skeleton.NumberOfBones, "SkeletonBoneAccessor is incompatible. BitArray _isSkinningMatrixDirty has wrong length."); // Set all dirty flags. Invalidate(); } }
/// <summary>Analyzes the state of the puzzle to determine whether it is a solution or not.</summary> /// <returns>The status of the puzzle.</returns> private PuzzleStatus AnalyzeSolutionStatus() { // Need a way of keeping track of what numbers have been used (in each row, column, box, etc.) // A bit array is a great way to do this, where each bit corresponds to a true/false value // as to whether a number was already used in a particular scenario. FastBitArray numbersUsed = new FastBitArray(_gridSize); // Make sure every column contains the right numbers. It's ok if a column has holes // as long as those cells have possibilities, in which case it's a puzzle in progress. // However, two numbers can't be used in the same column, even if there are holes. for (int i = 0; i < _gridSize; i++) { numbersUsed.SetAll(false); for (int j = 0; j < _gridSize; j++) { if (_grid[i, j].HasValue) { int value = _grid[i, j].Value; if (numbersUsed[value]) { return(PuzzleStatus.CannotBeSolved); } numbersUsed[value] = true; } } } // Same for rows for (int j = 0; j < _gridSize; j++) { numbersUsed.SetAll(false); for (int i = 0; i < _gridSize; i++) { if (_grid[i, j].HasValue) { int value = _grid[i, j].Value; if (numbersUsed[value]) { return(PuzzleStatus.CannotBeSolved); } numbersUsed[value] = true; } } } // Same for boxes for (int boxNumber = 0; boxNumber < _gridSize; boxNumber++) { numbersUsed.SetAll(false); int boxStartX = (boxNumber / _boxSize) * _boxSize; for (int x = boxStartX; x < boxStartX + _boxSize; x++) { int boxStartY = (boxNumber % _boxSize) * _boxSize; for (int y = boxStartY; y < boxStartY + _boxSize; y++) { if (_grid[x, y].HasValue) { int value = _grid[x, y].Value; if (numbersUsed[value]) { return(PuzzleStatus.CannotBeSolved); } numbersUsed[value] = true; } } } } // Now figure out whether this is a solved puzzle or a work in progress // based on whether there are any holes for (int i = 0; i < _gridSize; i++) { for (int j = 0; j < _gridSize; j++) { if (!_grid[i, j].HasValue) { return(PuzzleStatus.InProgress); } } } // If we made it this far, this state is a valid solution! Woo hoo! return(PuzzleStatus.Solved); }