Beispiel #1
0
    //public List<string> removedSelectedGIDs;

    IEnumerator Start()
    {
        this.model = new ChainXModel();
        this.model.SetController(this);
        GameObject anObj = this.CreateVoxel(0, Const.UI_SELECTING_VOXEL_NAME, Vector3.zero);

        anObj.transform.SetParent(GameObject.Find(Const.PAINT_TOOL_PATH).transform);
        anObj.GetComponent <Renderer>().enabled = false;
        anObj.layer = Const.UI_LAYER;

        this.paintTool         = GameObject.Find(Const.PAINT_TOOL_PATH + Const.UI_SELECTING_POINTER_NAME);
        this.paintTool.layer   = Const.UI_LAYER;
        this.screenSize.width  = Screen.width;
        this.screenSize.height = Screen.height;
        this.SetPositionOfPaintTool();
        this.debuggerObj = GameObject.Find("DebugLog/Viewport/Content");

        this.cv = new ChainVoxel(this);
        this.selectedObjects = new List <GameObject> ();
        //this.removedSelectedGIDs = new List<string> ();
        this.socket = new EmulatedWebSocket(this);
        StartCoroutine(this.socket.Connect());
        //Util.START_NANO_TIME = System.DateTime.Now.Ticks; //タイムスタンプ開始
        yield return(this.socket.Listen());
    }
Beispiel #2
0
    void Update()
    {
        //Debug.Log(DateTime.UtcNow.Ticks);

        lock (ChainXController.thisLock) {
            this.UpdateVoxels();
            //this.SetUpGUICompornets ();

            //スクリーンサイズが変更された時、実行される
            if (this.screenSize.width != Screen.width ||
                this.screenSize.height != Screen.height)
            {
                this.SetPositionOfPaintTool();
                this.screenSize.width  = Screen.width;
                this.screenSize.height = Screen.height;
            }

            //マウスクリックの際の処理
            if (Input.GetMouseButtonDown(Const.MOUSE_LEFT_CLICK))
            {
                if (Input.GetKey(KeyCode.LeftAlt))
                {
                    //Do nothing for Orbit, Zoom, etc..
                }
                else if (this.clickUI())
                {
                    this.cleanSelectedObjects();                     //Voxelの選択解除
                }
                else if (this.paintTool.name == Const.UI_SELECTING_POINTER_NAME)
                {
                    this.clickVoxel();                     //マウスクリックしてオブジェクトを選択する
                }
                else
                {
                    //VoxelまたはVoxelsが選択中のとき
                    this.paintVoxels();                     //VoxelまたはVoxelsをペイントする
                }
            }

            //キーボード操作(移動、グループ作成、解除、削除)
            Operation o = null;
            if (this.selectedObjects.Count > 0)
            {
                //3. MOVEの移動方向を追加
                Vector3 arrowV = Vector3.zero;
                if (Input.GetKeyUp(KeyCode.UpArrow))
                {
                    arrowV = new Vector3(1, 0, 0);
                }
                else if (Input.GetKeyUp(KeyCode.DownArrow))
                {
                    arrowV = new Vector3(-1, 0, 0);
                }
                else if (Input.GetKeyUp(KeyCode.RightArrow))
                {
                    arrowV = new Vector3(0, 0, -1);
                }
                else if (Input.GetKeyUp(KeyCode.LeftArrow))
                {
                    arrowV = new Vector3(0, 0, 1);
                }
                else if (Input.GetKeyUp(KeyCode.K))
                {
                    arrowV = new Vector3(0, 1, 0);
                }
                else if (Input.GetKeyUp(KeyCode.J))
                {
                    arrowV = new Vector3(0, -1, 0);
                }

                if (arrowV == Vector3.zero)
                {
                    if (Input.GetKeyUp(KeyCode.D))
                    {
                        //
                        // VoxelまたはGroupVoxelを削除する
                        //
                        if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand) ||
                            Input.GetKey(KeyCode.RightControl) || Input.GetKey(KeyCode.RightCommand))
                        {
                            List <Operation> deleteOps = this.model.CreateDeleteOperation(this.selectedObjects);
                            foreach (Operation op in deleteOps)
                            {
                                this.ApplyChainVoxel(op);
                            }
                        }
                    }
                    else if (Input.GetKeyDown(KeyCode.G))
                    {
                        //
                        // グループの参加、離脱
                        // グループの中にグループは、今は処理しない!
                        //
                        string gid;
                        if (this.selectedObjects.Count == 1)
                        {
                            if (this.selectedObjects [0].transform.childCount > 0)
                            {
                                //選択したオブジェクトが一つで、それがグループである場合、グループを解除
                                gid = this.selectedObjects [0].transform.root.name;
                                o   = new Operation(this.socket.getID(), Operation.LEAVE_ALL, "{\"posIDs\": \"" +
                                                    this.model.getPosIDsFromObj(this.selectedObjects[0]) + "\", \"gid\": \"" + gid +
                                                    "\"}");
                                this.ApplyChainVoxel(o);
                            }
                            else
                            {
                            }                                      //何もしない
                        }
                        else
                        {
                            gid = ChainXModel.CreateGID();
                            o   = new Operation(this.socket.getID(), Operation.JOIN_ALL, "{\"posIDs\": \"" +
                                                this.model.getPosIDsFromObjects(this.selectedObjects) + "\", \"gid\": \"" + gid +
                                                "\"}");
                            this.ApplyChainVoxel(o);
                        }
                    }
                }

                else
                {
                    /*
                     * foreach (GameObject anObj in this.selectedObjects) {
                     *      Debug.Log (anObj.name);
                     * }
                     */
                    //Debug.Log("MOVE");
                    this.selectedObjects = Util.ArrangeGameObjects(this.selectedObjects, arrowV);

                    List <Operation> moveOps = this.model.CreateMoveOperations(this.selectedObjects, arrowV);
                    foreach (Operation moveOp in moveOps)
                    {
                        this.ApplyChainVoxel(moveOp);
                    }
                }
            }
            if (o != null)
            {
                //this.cv.show();
                //this.cv.stt.show();
            }
        }
    }
Beispiel #3
0
    /*
     * PaintToolのVoxelまたはグループVoxelが選択されていて、マウスクリックされたときに呼ばれる。
     * ペイントさせ方は、ぶつかったオブジェクト(Plane)よりも手前のオブジェクトを
     * 「後ろ側から手前に」辿っていき、Voxelを挿入する。
     */
    private void paintVoxels()
    {
        string paintToolName = this.model.getCurrentPaintTool();

        List <Operation> ops = new List <Operation>();
        Ray        ray       = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit       = new RaycastHit();

        if (Physics.Raycast(ray, out hit))
        {
            if (paintToolName.IndexOf(ChainXModel.PAINT_TOOL_VOXEL_ID) > -1)
            {
                //
                //単位Voxelをペイントする
                //
                float   distance      = hit.distance - 0.5f; //ヒットしたRayより少し手前のPointをたどる
                Vector3 hitPointShort = ChainXModel.GetRoundIntPoint(ray.GetPoint(distance));
                int     textureType   = int.Parse(this.paintTool.GetComponent <Text>().text);
                ops.Add(new Operation(this.socket.getID(), Operation.INSERT,
                                      "{\"posID\": \"" + ChainXModel.CreatePosID(hitPointShort) +
                                      "\", \"textureType\":\"" + textureType + "\"}"
                                      ));
            }
            else if (paintToolName.IndexOf(ChainXModel.PAINT_TOOL_GROUP_ID) > -1)
            {
                //
                //グループVoxelsをペイントする
                //
                float   cursor_d      = hit.distance - 0.5f;
                Vector3 hitPointShort = ChainXModel.GetRoundIntPoint(ray.GetPoint(cursor_d));

                //もっともヒットポイントに近いオブジェクトをグループVoxelsの中から見つける
                GameObject closeObjToHitPoint = null;
                float      minDistance        = float.MaxValue;
                GameObject groupObj           = GameObject.Find(paintToolName);
                foreach (Transform aPart in groupObj.transform)
                {
                    float d = Vector3.Distance(aPart.gameObject.transform.position, hitPointShort);
                    if (d < minDistance)
                    {
                        minDistance        = d;
                        closeObjToHitPoint = aPart.gameObject;
                    }
                }

                bool    put_enable;
                Vector3 diffV        = Vector3.zero;
                string  posIDs       = "";
                string  textureTypes = "";
                while (cursor_d > 0)
                {
                    posIDs        = "";
                    textureTypes  = "";
                    hitPointShort = ChainXModel.GetRoundIntPoint(ray.GetPoint(cursor_d));
                    diffV         = hitPointShort - closeObjToHitPoint.transform.position;
                    put_enable    = true;
                    foreach (Transform aPart in groupObj.transform)
                    {
                        Vector3 movingV = aPart.gameObject.transform.position + diffV;
                        if (GameObject.Find(Util.CreatePosID(movingV)) != null)
                        {
                            put_enable = false;
                            break;
                        }
                        posIDs       += Util.CreatePosID(movingV) + Const.SPLIT_CHAR;
                        textureTypes += aPart.gameObject.GetComponent <Text>().text + Const.SPLIT_CHAR;
                    }
                    if (put_enable)
                    {
                        break;
                    }
                    cursor_d--;
                }
                posIDs       = posIDs.TrimEnd(Const.SPLIT_CHAR);
                textureTypes = textureTypes.TrimEnd(Const.SPLIT_CHAR);
                this.selectedObjects.Remove(groupObj);

                string gid = ChainXModel.CreateGID();
                ops.Add(new Operation(this.socket.getID(), Operation.INSERT_ALL,
                                      "{\"posIDs\": \"" + posIDs +
                                      "\", \"gid\": \"" + gid +
                                      "\", \"textureTypes\":\"" + textureTypes + "\"}")
                        );
                ops.Add(new Operation(this.socket.getID(), Operation.JOIN_ALL,
                                      "{\"posIDs\": \"" + posIDs +
                                      "\", \"gid\": \"" + gid + "\"}")
                        );
            }

            long ts = ops[0].getTimestamp();
            for (int i = 0; i < ops.Count; i++)
            {
                ops[i].setTimestamp(ts + i);                 //できる限り1に近づけないと間に入り込まれる
                this.ApplyChainVoxel(ops[i]);
            }
            //Debug.DrawLine(ray.origin, hitPointShort, Color.red, 60.0f, true); //レーザービーム
        }
    }
Beispiel #4
0
    public static void Test()
    {
        ChainXModel model = new ChainXModel();

        /*
         * グループボクセルの中心座標を求める
         */
        GameObject aParent = new GameObject("P");

        GameObject[] children = new GameObject[5];
        for (int i = 0; i < children.Length; ++i)
        {
            children[i] = GameObject.CreatePrimitive(PrimitiveType.Cube);
            children[i].SetActive(true);
            children[i].name = "c" + i.ToString();
            children[i].transform.SetParent(aParent.transform);
        }

        //パターン1
        children[0].transform.position = new Vector3(0, 0, 0);
        children[1].transform.position = new Vector3(0, 1, 0);
        children[2].transform.position = new Vector3(0, 2, 0);
        children[3].transform.position = new Vector3(0, 2, 1);
        children[4].transform.position = new Vector3(1, 2, 0);
        Vector3 a, b;

        model.GetMaxMinPositions(aParent, out a, out b);
        Debug.Assert(a == new Vector3(1, 2, 1));
        Debug.Assert(b == new Vector3(0, 0, 0));
        Vector3 res = model.GetBottomCenterPosition(aParent, 0.0f);

        Debug.Assert(res == new Vector3(0.5f, 0, 0.5f));

        //パターン2
        children[0].transform.position = new Vector3(5, 5, 5);
        children[1].transform.position = new Vector3(5, 5, 6);
        children[2].transform.position = new Vector3(6, 5, 5);
        children[3].transform.position = new Vector3(5, 0, 5);
        children[4].transform.position = new Vector3(5, 5, 8);
        model.GetMaxMinPositions(aParent, out a, out b);
        Debug.Assert(a == new Vector3(6, 5, 8));
        Debug.Assert(b == new Vector3(5, 0, 5));
        res = model.GetBottomCenterPosition(aParent, 0.0f);
        Debug.Assert(res == new Vector3(5.5f, 0, 6.5f));

        //パターン3
        children[0].transform.position = new Vector3(-2, 0, 0);
        children[1].transform.position = new Vector3(-1, 1, 0);
        children[2].transform.position = new Vector3(-2, 2, 0);
        children[3].transform.position = new Vector3(-2, 3, 0);
        children[4].transform.position = new Vector3(-2, 4, 0);
        model.GetMaxMinPositions(aParent, out a, out b);
        Debug.Assert(a == new Vector3(-1, 4, 0));
        Debug.Assert(b == new Vector3(-2, 0, 0));
        res = model.GetBottomCenterPosition(aParent, 0.0f);
        Debug.Assert(res == new Vector3(-1.5f, 0, 0));
        //GameObject.Destroy(aParent); //ここで作成した可視化をしないようにしている

        /*
         * Tests for PaintTool
         */
        model.getPaintTool(0, 1);
        Debug.Assert(model.getPaintTool(0, 0) == "voxel0");
        Debug.Assert(model.getPaintTool(1, 0) == "voxel1");
        Debug.Assert(model.getPaintTool(1, 0) == "voxel2");
        Debug.Assert(model.getPaintTool(-1, 0) == "voxel1");
        Debug.Assert(model.getPaintTool(-1, 0) == "voxel0");
        Debug.Assert(model.getPaintTool(-1, 0) == "voxel7");
        Debug.Assert(model.getPaintTool(0, 1) == "pointer");
        model.AddGroupToUI("group1");
        Debug.Assert(model.getPaintTool(0, 1) == "voxel0");
        Debug.Assert(model.getPaintTool(0, 1) == "group1");
        model.AddGroupToUI("group1");
        Debug.Assert(model.getPaintTool(1, 0) == "group1");
        model.RemoveGroupFromUI("group1");
        Debug.Assert(model.getCurrentPaintTool() == "pointer");
        Debug.Assert(model.getPaintTool(-1, 0) == "pointer");
        Debug.Assert(model.getPaintTool(-1, 0) == "pointer");

        Debug.Log("End a ChainXModel class test");
    }
Beispiel #5
0
    /*
     *
     */
    public List <Operation> CreateMoveOperations(List <GameObject> objects, Vector3 transMatrix)
    {
        List <Operation> operations = new List <Operation>();

        foreach (GameObject anObj in objects)
        {
            if (anObj.transform.childCount > 0)
            {
                //
                //When selecting multiple voxels or polygon
                //
                if (anObj.transform.childCount == 1)
                {
                    //When selecting polygon

                    /*
                     * foreach (Transform child in anObj.transform) {
                     *      string[] posIDs = ObjLoadHelper.GetEmptyVoxels(child.gameObject);
                     *      //Debug.Log ("posID(emptyVoxel)" + posIDs [posIDs.Length-1]);
                     *      operations.Add (new Operation (this.controller.socket.getID(), Operation.MOVE_POLYGON, "{\"gid\": \"" + anObj.name +
                     *              "\", \"posIDs\": \"" + Util.GetCommaLineFrom (posIDs) +
                     *              "\", \"transMatrix\": \"" + ChainXModel.CreatePosID (transMatrix) + "\"}")
                     *      );
                     * }
                     */
                }
                else
                {
                    //When selecting multiple voxels
                    List <string> posIDs           = new List <string> ();
                    List <string> destPosIDs       = new List <string> ();
                    List <string> destTextureTypes = new List <string> ();
                    foreach (Transform child in anObj.transform)
                    {
                        //Debug.Assert (Util.CreatePosID (child.position) == child.name);
                        Vector3 destPosition = Util.SplitPosID(child.name) + transMatrix;
                        posIDs.Add(child.name);
                        destPosIDs.Add(Util.CreatePosID(destPosition));
                        Voxel aVoxel = this.controller.cv.getVoxel(child.name);
                        destTextureTypes.Add(aVoxel.getTextureType().ToString());
                    }

                    string      posIDsLine     = Util.GetCommaLineFrom(posIDs);
                    string      destPosIDsLine = Util.GetCommaLineFrom(destPosIDs);
                    Operation[] ops            = new Operation[4];
                    ops[0] = new Operation(
                        this.controller.socket.getID(), Operation.LEAVE_ALL,
                        "{\"gid\": \"" + anObj.name + "\", \"posIDs\": \"" + posIDsLine + "\"}"
                        );
                    ops[1] = new Operation(
                        this.controller.socket.getID(), Operation.DELETE_ALL,
                        "{\"gid\": \"" + anObj.name + "\", \"posIDs\": \"" + posIDsLine + "\"}"
                        );
                    ops[2] = new Operation(
                        this.controller.socket.getID(), Operation.INSERT_ALL,
                        "{\"gid\": \"" + anObj.name +
                        "\", \"textureTypes\": \"" + Util.GetCommaLineFrom(destTextureTypes) +
                        "\", \"posIDs\": \"" + destPosIDsLine + "\"}"
                        );
                    ops[3] = new Operation(
                        this.controller.socket.getID(), Operation.JOIN_ALL,
                        "{\"gid\": \"" + anObj.name + "\", \"posIDs\": \"" + destPosIDsLine + "\"}"
                        );
                    long ts = ops[0].getTimestamp();
                    for (int i = 0; i < ops.Length; i++)
                    {
                        ops[i].setTimestamp(ts + i);                         //できる限り1に近づけないと間に入り込まれる
                        operations.Add(ops[i]);
                    }
                }
            }
            else
            {
                //Debug.Log (anObj.name);
                //Debug.Log (anObj.transform.childCount);
                operations.Add(new Operation(
                                   this.controller.socket.getID(),
                                   Operation.MOVE,
                                   "{\"posID\": \"" + anObj.name +
                                   "\", \"transMatrix\": \"" + ChainXModel.CreatePosID(transMatrix) + "\"}")
                               );
            }
        }
        return(operations);
    }
Beispiel #6
0
    public IEnumerator Listen()
    {
        //this.SendBinary(-1, Const.START_BINARY_HEADER);

        byte[]   msgBinary = null;
        string[] filepaths = { "", "" };

        while (true)
        {
            msgBinary = this.ws.Recv();
            if (msgBinary != null)
            {
                //Debug.Log (Encoding.ASCII.GetString(msgBinary));
                //byte[] idBinary = this.getIdFromEndUntilAt(ref receivedBinary);
                //int destID = System.BitConverter.ToInt32(idBinary, 0); //送り先!!
                //byte[] msgBinary = this.getOperationFromEndUntilAt(ref receivedBinary);

                if (this.partEqual(ref msgBinary, ref Const.OPERATION_BINARY_HEADER))
                {
                    string line = Encoding.UTF8.GetString(msgBinary);
                    line = line.Remove(0, Const.OPERATION_HEADER.Length).Trim();
                    Operation op = Operation.FromJson(line);
                    this.controller.cv.apply(op, ChainVoxel.REMOTE_OPERATION);
                }
                else if (this.partEqual(ref msgBinary, ref Const.JOIN_BINARY_HEADER))
                {
                    string msg = Encoding.UTF8.GetString(msgBinary);
                    msg = msg.Replace(Const.JOIN_HEADER, "");
                    int intID = int.Parse(msg);
                    if (!this.siteIDs.Contains(intID))
                    {
                        this.siteIDs.Add(intID);
                    }
                    //foreach (int sid in this.siteIDs) { Debug.Log("sid: " + sid); }
                    //Debug.Log("this.id:" + this.id);
                    //Debug.Log("joined id:" + intID);
                }
                else if (this.partEqual(ref msgBinary, ref Const.ID_LIST_BINARY_HEADER))
                {
                    string   msg     = Encoding.UTF8.GetString(msgBinary);
                    int      atIndex = msg.IndexOf(Const.MSG_SPLIT_CHAR);
                    string   idsLine = msg.Substring(atIndex + 1);                   //atIndex+1から最後まで
                    String[] strIDs  = idsLine.Split(Const.SPLIT_CHAR);
                    foreach (string strID in strIDs)
                    {
                        int intID = int.Parse(strID);
                        if (!this.siteIDs.Contains(intID))
                        {
                            this.siteIDs.Add(intID);
                        }
                    }
                    this.leaderID = this.siteIDs[0];
                    this.id       = this.siteIDs[this.siteIDs.Count - 1];
                }
                else if (this.partEqual(ref msgBinary, ref Const.SOME_FILE_BINARY_HEADER))
                {
                    string     filepath = this.getPathUntilAt(ref msgBinary);
                    int        start_i  = Const.SOME_FILE_HEADER.Length + filepath.Length + 1;             //1='@'
                    string     path     = Application.persistentDataPath + "/" + filepath;
                    FileStream fs       = new FileStream(path, FileMode.Create, FileAccess.Write);
                    fs.Write(msgBinary, start_i, msgBinary.Length - start_i);
                    fs.Close();

                    if (Path.GetExtension(path) == ".txt")
                    {
                        //Debug.Log (path);
                        this.controller.cv.LoadSavedData(path);
                    }
                    else if (Path.GetExtension(path) == ".obj")
                    {
                        filepaths[0] = path;
                    }
                    else if (Path.GetExtension(path) == ".jpg")
                    {
                        filepaths[1] = path;
                    }

                    if (filepaths[0] != "" && filepaths[1] != "")
                    {
                        //
                        // When all dependent files of a 3d obj have been collected,
                        // Build the 3d obj.
                        //
                        string[] posIDs = ObjLoadHelper.LoadObj(filepaths, new Vector3(0, 5, 0));
                        //string[] posIDs = ObjLoadHelper.LoadOnlyObj(filepaths[0], new Vector3 (0,5,0));
                        Operation op = new Operation(0, Operation.INSERT_POLYGON,
                                                     "{\"posIDs\": \"" + Util.GetCommaLineFrom(posIDs) +
                                                     "\", \"gid\": \"" + ChainXModel.CreateGID() +
                                                     "\", \"objPath\":\"" + filepaths[0] + "\"}");
                        //Debug.Log(Operation.ToJson(op));
                        this.controller.cv.apply(op, ChainVoxel.LOCAL_OPERATION);

                        filepaths = new string[] { "", "" };                      //Clear for the next 3d objs
                    }
                }
            }

            if (this.ws.error != null)
            {
                Debug.LogError("Error: " + this.ws.error);
                break;
            }
            yield return(0);
        }
        this.ws.Close();
    }
Beispiel #7
0
    /**
     * Test an Operation class
     */
    public static void Test()
    {
        int numberOfTest = Const.TEST_QUALITY;

        //
        // A test for Operation.CombinePosition().
        //
        for (int t = 0; t < numberOfTest; ++t)
        {
            Vector3 posIDVector       = Util.CreateRandomVector3(-10000, 10000);
            Vector3 transMatrixVector = Util.CreateRandomTransMatrix();
            Debug.Assert(
                ChainXModel.CreatePosID(posIDVector + transMatrixVector)
                == Operation.CombinePosition(
                    ChainXModel.CreatePosID(posIDVector), ChainXModel.CreatePosID(transMatrixVector)
                    )
                );
        }

        //
        // Jsonへの変換とその逆ができているかをチェック
        // Operationへの初期値の値の変化がないかをチェック at CreateRandomOperation()
        //
        string    json = "";
        Operation o1, o2;

        for (int t = 0; t < numberOfTest; ++t)
        {
            o1   = Operation.CreateRandomOperation();
            json = Operation.ToJson(o1);
            o2   = Operation.FromJson(json);
            Debug.Assert(o1.getSID() == o2.getSID());
            Debug.Assert(o1.getOpType() == o2.getOpType());
            Debug.Assert(o1.getTimestamp() == o2.getTimestamp());

            switch (o1.getOpType())
            {
            case Operation.INSERT:
                Debug.Assert(o1.getPosID() == o2.getPosID());
                Debug.Assert(o1.getTextureType() == o2.getTextureType());
                break;

            case Operation.DELETE:
                Debug.Assert(o1.getPosID() == o2.getPosID());
                break;

            case Operation.MOVE:
                Debug.Assert(o1.getPosID() == o2.getPosID());
                Debug.Assert(o1.getTransMatrix() == o2.getTransMatrix());
                Debug.Assert(o1.getDestPosID() == o2.getDestPosID());
                break;

            case Operation.CREATE:
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.JOIN:
            case Operation.LEAVE:
                Debug.Assert(o1.getGID() == o2.getGID());
                Debug.Assert(o1.getPosID() == o2.getPosID());
                break;

            case Operation.JOIN_ALL:
            case Operation.LEAVE_ALL:
                Debug.Assert(o1.getGID() == o2.getGID());
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                break;

            case Operation.MOVE_ALL:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getTransMatrix() == o2.getTransMatrix());
                Debug.Assert(Util.GetCommaLineFrom(o1.getDestPosIDs())
                             == Util.GetCommaLineFrom(o2.getDestPosIDs()));
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.INSERT_ALL:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getTextureType() == o2.getTextureType());
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.DELETE_ALL:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.INSERT_POLYGON:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getObjPath() == o2.getObjPath());
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.DELETE_POLYGON:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            case Operation.MOVE_POLYGON:
                Debug.Assert(Util.GetCommaLineFrom(o1.getPosIDs()) == Util.GetCommaLineFrom(o2.getPosIDs()));
                Debug.Assert(o1.getTransMatrix() == o2.getTransMatrix());
                Debug.Assert(Util.GetCommaLineFrom(o1.getDestPosIDs())
                             == Util.GetCommaLineFrom(o2.getDestPosIDs()));
                Debug.Assert(o1.getGID() == o2.getGID());
                break;

            default:
                throw new System.InvalidOperationException(
                          String.Format("Operation{0} at CreateRandomOperation()",
                                        o1.getOpType())
                          );
            }
        }
        Debug.Log("End an Operation class test");
    }