/// <summary> /// 指定されたクリッピングマスクがマスクするDrawableの占める矩形を計算する。 /// 現時点でそのクリッピングマスクを使用するDrawableが無い場合はEmptyを返す。 /// </summary> /// <param name="clipping_context">計算対象のクリッピングマスク</param> private RectangleF CalcClippedDrawTotalBounds(CubismClippingContext clipping_context) { RectangleF result = RectangleF.Empty; foreach (var index in clipping_context.ClippedDrawableIndexList) { // Drawableのバウンディングボックスとの和をとる RectangleF bounding_box = Model.GetDrawable(index).BoundingBox; if (bounding_box.IsEmpty == false) { result = RectangleF.Union(result, bounding_box); } } return(result); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="renderer">描画に使用するレンダラー</param> /// <param name="asset">描画するモデルのアセット</param> public CubismRenderingManager(ICubismRenderer renderer, CubismAsset asset) { Renderer = renderer; Asset = asset; Model = Asset.Model; // モデルのテクスチャをレンダラーにコピーする RendererTextures = new ICubismTexture[Asset.TextureByteArrays.Length]; for (int index = 0; index < Asset.TextureByteArrays.Length; index++) { RendererTextures[index] = Renderer.CreateTexture(Asset.TextureByteArrays[index]); } // 各DrawableでどのDrawableをクリッピングマスクとして使用するか調べ、 // もし同じDrawableの組み合わせをマスクとして用いるDrawableがあればマスクを共有するようにする int drawable_count = Model.DrawableCount; List <CubismClippingContext> all_clipping_contexts = new List <CubismClippingContext>(); DrawableClippingContexts = new CubismClippingContext[drawable_count]; for (int index = 0; index < drawable_count; index++) { var drawable = Model.GetDrawable(index); if (drawable.ClippingMaskIndexes.Length <= 0) { DrawableClippingContexts[index] = null; continue; } CubismClippingContext new_clippling_context = null; int[] mask_indexes = drawable.ClippingMaskIndexes.Distinct().OrderBy(x => x).ToArray(); foreach (var target in all_clipping_contexts) { if (mask_indexes.SequenceEqual(target.ClippingIdList) == true) { new_clippling_context = target; break; } } if (new_clippling_context == null) { // クリッピングマスクをレンダラーに作成する new_clippling_context = new CubismClippingContext(Renderer.CreateClippingMask(), mask_indexes); all_clipping_contexts.Add(new_clippling_context); } new_clippling_context.ClippedDrawableIndexList.Add(index); DrawableClippingContexts[index] = new_clippling_context; } AllClippingContexts = all_clipping_contexts.ToArray(); }
/// <summary> /// レンダラーでモデルを描画する。 /// </summary> public void Draw(Matrix4x4 mvp_matrix) { try { // 描画を開始する Renderer.StartDrawingModel(Asset.ModelColor, mvp_matrix); // クリッピングマスクを描画する SetupClippingMasks(); // Drawableの描画順を取得し、描画する順番にインデックスを並べ替えたリストを作成する int drawable_count = Model.DrawableCount; var drawable_render_order = Model.GetDrawableRenderOrders(); int[] reordered_drawable_indexes = new int[drawable_count]; for (int index = 0; index < drawable_count; index++) { reordered_drawable_indexes[drawable_render_order[index]] = index; } // 指定された順番通りにDrawableを描画していく foreach (int drawable_index in reordered_drawable_indexes) { var drawable = Model.GetDrawable(drawable_index); if (drawable.Visible == false) { // Drawableは非表示なので描画しない continue; } // メッシュを描画する var texture = RendererTextures[drawable.TextureIndex]; float[] vertex_buffer = drawable.VertexBuffer; float[] uv_buffer = drawable.UvBuffer; short[] index_buffer = drawable.IndexBuffer; CubismClippingContext clipping_context = DrawableClippingContexts[drawable_index]; ICubismClippingMask clipping_mask = (clipping_context != null) ? clipping_context.Target : null; Matrix4x4 clipping_matrix = (clipping_context != null) ? clipping_context.MatrixForDraw : Matrix4x4.Identity; Renderer.DrawMesh(texture, vertex_buffer, uv_buffer, index_buffer, clipping_mask, clipping_matrix, drawable.BlendMode, drawable.UseCulling, drawable.IsInvertedMask, drawable.Opacity); } } finally { Renderer.EndDrawingModel(); } }