
Config = Config or class("DestructionConfig");



function Config:ctor()
    self.m_szJsonGeometry = [[
        {
            "Type" : "Box",
            "HalfLen" : [30.0, 30.0, 30.0]
        }
    ]]

    self.m_tbActor = {};
    -- 划分的方块数
    self.m_nCountX = 8;
    self.m_nCountY = 5;
    self.m_nCountZ = 4;
    self.m_nCount = self.m_nCountX * self.m_nCountY * self.m_nCountZ;
    -- 暂时缩放
    self.m_fScale = 0.1;

    self.m_PlacementBoxLen = KVec3();
    self.m_Origin = KVec3();
end

---
--- 在场景中创建一个可破坏对象
---
--- @param path string
---
function Config:createDestructibleObject(path)
    
    -- -- 读数据
    -- if self:loadData() then
    --      -- 生成已经计算好的actor 节约时间
    --      self:loadPhysicsActor();
    -- else
    --     -- 读取model文件 预处理参数
    --     local LIniFile = ImportScript("ugc_common/script/core/file/inifile.lua").LIniFile;
    --     self.m_tbMeshSet = LIniFile.load(path);
    --     -- 创建物理对象
    --     self:createPhysicsActor();

    --     -- Model与物理Actor绑定
    --     self:bindModel();

    --     --joint
    --     -- self:createPhysicsContrain();
        
    --     self:saveData();
    -- end

    -- test
    self:testVoxelization();
end

function Config:createPhysicsActor()
    local placementBox = self.m_tbMeshSet.placementBox;
    local localBBoxvMax = string.split(placementBox.LocalBBoxvMax, ",");
    local localBBoxvMin = string.split(placementBox.LocalBBoxvMin, ",");

    self.m_PlacementBoxLen = KVec3();
    KVec3Subtract(KVec3(localBBoxvMax[1], localBBoxvMax[2], localBBoxvMax[3]), 
                  KVec3(localBBoxvMin[1], localBBoxvMin[2], localBBoxvMin[3]), 
                  self.m_PlacementBoxLen);
    KVec3MinusNum(self.m_PlacementBoxLen, self.m_fScale, self.m_PlacementBoxLen);

    self.m_GeometryBoxHalfLen = KVec3(self.m_PlacementBoxLen.x / self.m_nCountX / 2,
                                      self.m_PlacementBoxLen.y / self.m_nCountY / 2,
                                      self.m_PlacementBoxLen.z / self.m_nCountZ / 2);

    local tabJsonGeometry = JSON.Loads(self.m_szJsonGeometry);
    tabJsonGeometry.HalfLen = {self.m_GeometryBoxHalfLen.x, 
                               self.m_GeometryBoxHalfLen.y, 
                               self.m_GeometryBoxHalfLen.z};
    self.m_szJsonGeometry = JSON.Dumps(tabJsonGeometry);
    
    local lPlayer = g_ActorManager:GetLocalPlayer();
    local _, originX, originY, originZ = lPlayer:GetWorldPosition();
    self.m_Origin = KVec3(originX + 500 + localBBoxvMin[1] * self.m_fScale + self.m_GeometryBoxHalfLen.x,
                                     20 + localBBoxvMin[2] * self.m_fScale + self.m_GeometryBoxHalfLen.y,
                          originZ + 500 + localBBoxvMin[3] * self.m_fScale + self.m_GeometryBoxHalfLen.z);

    for i = 1, self.m_nCount do
        local x, y, z;
        local actor = g_ActorManager:CreateStaticMeshActor("");
        x = self.m_Origin.x + self.m_GeometryBoxHalfLen.x * 2 * ((i - 1) % self.m_nCountX);
        local n, f = math.modf((i - 1) / self.m_nCountX);
        z = self.m_Origin.z + (n % self.m_nCountZ) * self.m_GeometryBoxHalfLen.z * 2;
        n, f = (math.modf((i - 1) / (self.m_nCountX * self.m_nCountZ)));
        y = self.m_Origin.y + n * self.m_GeometryBoxHalfLen.y * 2;
        actor:SetWorldPosition(x, y, z);

        table.insert(self.m_tbActor, actor);
    end

    -- 保存数据
    self:savePhysicsActors();
end

function Config:loadPhysicsActor()
    -- to do 各成员变量的值
    local lPlayer = g_ActorManager:GetLocalPlayer();
    local _, x, y, z = lPlayer:GetWorldPosition();

    local tabJsonGeometry = JSON.Loads(self.m_szJsonGeometry);
    local geometryBoxHalfLen = self.m_FileContent.GeometryBoxHalfLen;
    tabJsonGeometry.HalfLen = {geometryBoxHalfLen[1], 
                               geometryBoxHalfLen[2], 
                               geometryBoxHalfLen[3]};
    self.m_szJsonGeometry = JSON.Dumps(tabJsonGeometry);

    for i = 1, self.m_nCount do
        
        local tbActor = self.m_FileContent["Actor"..i];

        local index = 1;
        local tbModel = tbActor["1"];
        if tbModel then
            local actor = g_ActorManager:CreateStaticMeshActor("");
            local localPosition = tbActor.LocalPosition;
            actor:SetWorldPosition(x + localPosition[1], y + localPosition[2], z + localPosition[3]);
            
            while tbModel do
                local t = KTransform();
                t:SetTranslation(KVec3(tbModel.Translation[1], 
                                       tbModel.Translation[2], 
                                       tbModel.Translation[3]));
                t:SetRotation(KQuaternion(tbModel.Rotation[1], 
                                          tbModel.Rotation[2], 
                                          tbModel.Rotation[3],
                                          tbModel.Rotation[4]));
                t:SetScaling(KVec3(tbModel.Scaling[1], 
                                   tbModel.Scaling[2], 
                                   tbModel.Scaling[3]));
                actor:BindMeshRes(tbModel.MeshName, t);

                index = index + 1;
                tbModel = tbActor[tostring(index)];
            end
            
            actor:SetCollisionGeometry(self.m_szJsonGeometry);
            actor:SetCollisionType(Core.QueryAndPhysics);      
            actor:SetSimulatePhysics(true);
        end
    end
end

function Config:bindModel()
    local tbModel = self.m_tbMeshSet.Model0;
    local nModelIndex = 1;

    local tbActorBox = {};
    for i = 1, self.m_nCount do
        local box = [[
            {
                "Max" : [0.0, 0.0, 0.0],
                "Min" : [-0.0, -0.0, -0.0]
            }
        ]]
        table.insert(tbActorBox, box);
    end

    while tbModel do
        local translation = string.split(tbModel.Translation, ",");
        local scaling = string.split(tbModel.Scaling, ",");
        local rotation = string.split(tbModel.Rotation, ",");
        local meshName = tbModel.MeshName;

        local minOffset = KVec3(1000.0, 1000.0, 1000.0);
        local minDist = KVec3Distance1Sqr(minOffset);
        local nActorIndex = 1;
        for j = 1, self.m_nCount do
            local _, x, y, z = self.m_tbActor[j]:GetWorldPosition();

            local modelPos = KVec3(self.m_Origin.x + self.m_PlacementBoxLen.x / 2 + translation[1] * self.m_fScale,
                                   self.m_Origin.y +                                translation[2] * self.m_fScale,
                                   self.m_Origin.z + self.m_PlacementBoxLen.z / 2 + translation[3] * self.m_fScale);
            local offset  = KVec3();
            KVec3Subtract(modelPos, KVec3(x, y, z), offset);
            local dist = KVec3Distance1Sqr(offset);
            if dist < minDist then
                minOffset = offset;
                minDist = dist;
                nActorIndex = j;
            end
        end
        local t = KTransform();
        t:SetTranslation(KVec3(minOffset.x, minOffset.y, minOffset.z));
        t:SetRotation(KQuaternion(rotation[1], rotation[2], rotation[3], rotation[4]));
        t:SetScaling(KVec3(scaling[1] * self.m_fScale, scaling[2] * self.m_fScale, scaling[3] * self.m_fScale));
        self.m_tbActor[nActorIndex]:BindMeshRes(meshName, t);
        
        local model = {
            Translation = {minOffset.x, minOffset.y, minOffset.z},
            Rotation = rotation,
            Scaling = {scaling[1] * self.m_fScale, scaling[2] * self.m_fScale, scaling[3] * self.m_fScale},
            MeshName = meshName
        }
        table.insert(self.m_tbPhyciscActors["Actor"..nActorIndex], model);

        local max = string.split(tbModel.LocalBBoxvMax, ",");
        local min = string.split(tbModel.LocalBBoxvMin, ",");
        local maxX = max[1] * scaling[1] * self.m_fScale;
        local maxY = max[2] * scaling[2] * self.m_fScale;
        local maxZ = max[3] * scaling[3] * self.m_fScale;
        local minX = min[1] * scaling[1] * self.m_fScale;
        local minY = min[2] * scaling[2] * self.m_fScale;
        local minZ = min[3] * scaling[3] * self.m_fScale;
        local jsonBox = JSON.Loads(tbActorBox[nActorIndex]);
        if maxX > jsonBox.Max[1] then
            jsonBox.Max[1] = maxX;
        end
        if maxY > jsonBox.Max[2] then
            jsonBox.Max[2] = maxY;
        end
        if maxZ > jsonBox.Max[3] then
            jsonBox.Max[3] = maxZ;
        end
        if minX < jsonBox.Min[1] then
            jsonBox.Min[1] = minX;
        end
        if minY < jsonBox.Min[2] then
            jsonBox.Min[2] = minY;
        end
        if minZ < jsonBox.Min[3] then
            jsonBox.Min[3] = minZ;
        end
        tbActorBox[nActorIndex] = JSON.Dumps(jsonBox);

        tbModel = self.m_tbMeshSet["Model"..nModelIndex];
        nModelIndex = nModelIndex + 1;
    end


    --最底层方块
    -- tabJsonGeometry = JSON.Loads(szJsonGeometry);
    -- tabJsonGeometry.HalfLen[2] = 0;
    -- local szJsonCropGeometry = JSON.Dumps(tabJsonGeometry);
    -- for i = 1, countX * countZ do
    --     tbActor[i]:SetCollisionGeometry(szJsonCropGeometry);
    --     tbActor[i]:SetCollisionType(Core.QueryAndPhysics);
    --     tbActor[i]:SetSimulatePhysics(true);
    -- end

    --根据方块所含的所有model的最大包围盒对方块进行裁剪
    for i = 1, self.m_nCount do
        local jsonBox = JSON.Loads(tbActorBox[i]);
        local tabJsonGeometry = JSON.Loads(self.m_szJsonGeometry);
        if jsonBox.Max[1] ~= 0 or jsonBox.Max[2] ~= 0 or jsonBox.Max[3] ~= 0 
            or jsonBox.Min[1] ~= 0 or jsonBox.Min[2] ~= 0 or jsonBox.Min[3] ~= 0 then
            -- if jsonBox.Max[1] < tabJsonGeometry.HalfLen[1] then
            --     tabJsonGeometry.HalfLen[1] = jsonBox.Max[1];
            -- end
            -- if jsonBox.Max[2] < tabJsonGeometry.HalfLen[2] then
            --     tabJsonGeometry.HalfLen[2] = jsonBox.Max[2];
            -- end
            -- if jsonBox.Max[3] < tabJsonGeometry.HalfLen[3] then
            --     tabJsonGeometry.HalfLen[3] = jsonBox.Max[3];
            -- end
            -- if -jsonBox.Min[1] < tabJsonGeometry.HalfLen[1] then
            --     tabJsonGeometry.HalfLen[1] = jsonBox.Min[1];
            -- end
            -- if -jsonBox.Min[2] < tabJsonGeometry.HalfLen[2] then
            --     tabJsonGeometry.HalfLen[2] = jsonBox.Min[2];
            -- end
            -- if -jsonBox.Min[3] < tabJsonGeometry.HalfLen[3] then
            --     tabJsonGeometry.HalfLen[3] = jsonBox.Min[3];
            -- end
            local jsonCropGeometry = JSON.Dumps(tabJsonGeometry);
            self.m_tbActor[i]:SetCollisionGeometry(jsonCropGeometry);
            self.m_tbActor[i]:SetCollisionType(Core.QueryAndPhysics);
            self.m_tbActor[i]:SetSimulatePhysics(true);
        else
            self.m_tbActor[i] = nil;
        end

        -- 暂时不删去块

    end
end

function Config:testVoxelization()
    
    local LIniFile = ImportScript("ugc_common/script/core/file/inifile.lua").LIniFile;
    self.m_tbMeshSet = LIniFile.load("data/source/Home/building/AREA/JN/JN_house_M_house01_L_01_16_20_02_HD.Group");
    -- 划分大方块
    local placementBox = self.m_tbMeshSet.placementBox;
    local localBBoxvMax = string.split(placementBox.LocalBBoxvMax, ",");
    local localBBoxvMin = string.split(placementBox.LocalBBoxvMin, ",");

    self.m_PlacementBoxLen = KVec3();
    KVec3Subtract(KVec3(localBBoxvMax[1], localBBoxvMax[2], localBBoxvMax[3]), 
                  KVec3(localBBoxvMin[1], localBBoxvMin[2], localBBoxvMin[3]), 
                  self.m_PlacementBoxLen);
    KVec3MinusNum(self.m_PlacementBoxLen, self.m_fScale, self.m_PlacementBoxLen);

    self.m_GeometryBoxHalfLen = KVec3(self.m_PlacementBoxLen.x / self.m_nCountX / 2,
                                      self.m_PlacementBoxLen.y / self.m_nCountY / 2,
                                      self.m_PlacementBoxLen.z / self.m_nCountZ / 2);

    local tabJsonGeometry = JSON.Loads(self.m_szJsonGeometry);
    tabJsonGeometry.HalfLen = {self.m_GeometryBoxHalfLen.x, 
                               self.m_GeometryBoxHalfLen.y, 
                               self.m_GeometryBoxHalfLen.z};
    self.m_szJsonGeometry = JSON.Dumps(tabJsonGeometry);
    
    local lPlayer = g_ActorManager:GetLocalPlayer();
    local _, originX, originY, originZ = lPlayer:GetWorldPosition();
    self.m_Origin = KVec3(originX + 500 + localBBoxvMin[1] * self.m_fScale + self.m_GeometryBoxHalfLen.x,
                                     20 + localBBoxvMin[2] * self.m_fScale + self.m_GeometryBoxHalfLen.y,
                          originZ + 500 + localBBoxvMin[3] * self.m_fScale + self.m_GeometryBoxHalfLen.z);

    -- 存所有大方块的坐标
    local tbBlockPos = {};
    -- 存每个大方块内的所有models
    local tbBlockModels = {};
    -- 存每个大方块内的所有models的每个相对位置
    local tbBlockModelsLocalPos = {};
    for i = 1, self.m_nCount do
        local x, y, z;
        x = self.m_Origin.x + self.m_GeometryBoxHalfLen.x * 2 * ((i - 1) % self.m_nCountX);
        local n, f = math.modf((i - 1) / self.m_nCountX);
        z = self.m_Origin.z + (n % self.m_nCountZ) * self.m_GeometryBoxHalfLen.z * 2;
        n, f = (math.modf((i - 1) / (self.m_nCountX * self.m_nCountZ)));
        y = self.m_Origin.y + n * self.m_GeometryBoxHalfLen.y * 2;
        local pos = KVec3(x, y, z);
        table.insert(tbBlockPos, pos);
        local models = {};
        table.insert(tbBlockModels, models);
        local modelsLocalPos = {};
        table.insert(tbBlockModelsLocalPos, modelsLocalPos);
    end

    local tbModel = self.m_tbMeshSet.Model0;
    local nModelIndex = 1;
    -- local tbModelBBoxMax = {};
    -- local tbModelBBoxMin = {};
    local tb

    while tbModel do
        local tbTranslation = string.split(tbModel.Translation, ",");
        local tbScaling = string.split(tbModel.Scaling, ",");
        local tbRotation = string.split(tbModel.Rotation, ",");
        local tbMax = string.split(tbModel.LocalBBoxvMax, ",");
        local tbMin = string.split(tbModel.LocalBBoxvMin, ",");

        -- 计算包围盒角点的global坐标
        -- local max = KVec3(tbMax[1] * tbScaling[1], tbMax[2] * tbScaling[2], tbMax[3] * tbScaling[3]);
        -- local min = KVec3(tbMin[1] * tbScaling[1], tbMin[2] * tbScaling[2], tbMin[3] * tbScaling[3]);
        -- KVec3MinusNum(max, self.m_fScale, max);
        -- KVec3MinusNum(min, self.m_fScale, min);
        -- local translation = KVec3(tbTranslation[1], tbTranslation[2], tbTranslation[3]);
        -- KVec3MinusNum(translation, self.m_fScale, translation);
        -- KVec3AddVec3(max, translation, max);
        -- KVec3AddVec3(min, translation, min);
        -- local rotation = KQuaternion(tbRotation[1], tbRotation[2], tbRotation[3], tbRotation[4]);
        -- max = rotation:RotateVector(max);
        -- min = rotation:RotateVector(min);
        -- table.insert(tbModelBBoxMax, max);
        -- table.insert(tbModelBBoxMin, min);

        -- -- 每个模型归属到离其最近的方块里
        local minOffset = KVec3(1000.0, 1000.0, 1000.0);
        local minDist = KVec3Distance1Sqr(minOffset);
        local nActorIndex = 1;
        for i = 1, self.m_nCount do
            local modelPos = KVec3(self.m_Origin.x + self.m_PlacementBoxLen.x / 2 + tbTranslation[1] * self.m_fScale,
                                   self.m_Origin.y +                                tbTranslation[2] * self.m_fScale,
                                   self.m_Origin.z + self.m_PlacementBoxLen.z / 2 + tbTranslation[3] * self.m_fScale);
            local offset  = KVec3();
            KVec3Subtract(modelPos, tbBlockPos[i], offset);
            local dist = KVec3Distance1Sqr(offset);
            if dist < minDist then
                minOffset = offset;
                minDist = dist;
                nActorIndex = i;
            end
        end
        table.insert(tbBlockModels[nActorIndex], nModelIndex);
        table.insert(tbBlockModelsLocalPos[nActorIndex], minOffset);

        tbModel = self.m_tbMeshSet["Model"..nModelIndex];
        nModelIndex = nModelIndex + 1;
    end

    -- 以大块为单位进行体素化 处于大块之外的暂时不管（穿模） 大块之内非模型区域无体素（解决浮空问题）
    for i = 1, self.m_nCount do
        -- 当前大方块内包含models
        if #tbBlockModels[i] > 0 then
            self:voxelizationInBlock(tbBlockModels[i], 
                                     tbBlockModelsLocalPos[i],
                                     tbBlockPos[i], 
                                     8);
            -- test 只算一个大方块
            break;
        end
    end

    -- 以大块为单位 连接所有体素 disbreakable
    -- 大块之间添加breakable joint
end

-- parameters
-- 大方块内的所有model的索引  从1开始
-- 大方块内的所有model的相对位置
-- 大方块的位置
-- 素体的分辨率n * n * n
function Config:voxelizationInBlock(tbModelIndexes, tbModellocalPositions, position, size)
    -- 外壳体素化
    -- 遍历每个model
    for i = 1, #tbModelIndexes do
        local model = self.m_tbMeshSet["Model"..tbModelIndexes[i] - 1];
        local modelPos = KVec3();
        local modelLocalPos = tbModellocalPositions[i];
        KVec3AddVec3(position, modelLocalPos, modelPos);
        local tabJsonMeshGeometry = {};
        tabJsonMeshGeometry["Type"] = "TriangleMesh";
        tabJsonMeshGeometry["MeshRes"] = model.MeshName;
        local szJsonMeshGeometry = cjson.encode(tabJsonMeshGeometry);
        local meshActor = g_ActorManager:CreateStaticMeshActor("");
        meshActor:SetWorldPosition(modelPos.x, modelPos.y, modelPos.z);
        meshActor:SetCollisionGeometry(szJsonMeshGeometry);
        meshActor:SetCollisionType(Core.QueryAndPhysics);
        
        -- 生成小方块
        local unitHalfLen = KVec3(size / 2, size / 2, size / 2);

        local tabJsonBoxGeometry = {};
        tabJsonBoxGeometry["Type"] = "Box";
        tabJsonBoxGeometry["HalfLen"] = {unitHalfLen.z, unitHalfLen.z, unitHalfLen.z};
        local szJsonBoxGeometry = cjson.encode(tabJsonBoxGeometry);

        local resolution = KVec3();
        KVec3MinusNum(self.m_GeometryBoxHalfLen, 2 / size, resolution);
        resolution.x = math.floor(resolution.x);
        resolution.y = math.floor(resolution.y);
        resolution.z = math.floor(resolution.z);
        local origin = KVec3();
        KVec3Subtract(position, self.m_GeometryBoxHalfLen, origin);
        for a = 0, resolution.x do
            for b = 0, resolution.y do
                for c = 0, resolution.z do
                    local actor = g_ActorManager:CreateStaticMeshActor("");
                    local unitPos = KVec3();
                    local offset = KVec3(a * size, b * size, c * size);
                    KVec3AddVec3(origin, offset, unitPos);
                    KVec3AddVec3(unitPos, unitHalfLen, unitPos);
                    actor:SetWorldPosition(unitPos.x, unitPos.y, unitPos.z);
                    actor:SetCollisionGeometry(szJsonBoxGeometry);
                    actor:SetCollisionType(Core.QueryAndPhysics);
                    actor:SetSimulatePhysics(true);
                    -- 小方块与mesh做碰撞检测
                    local t = KTransform();
                    t:SetTranslation(modelLocalPos);
                    -- 暂时缩小房子
                    t:SetScaling(KVec3(self.m_fScale, self.m_fScale, self.m_fScale));
                    actor:CollisionDetectionWithMesh(meshActor.m_kStaticMeshActor, t);
                    -- 不相交小方块删去
                end
            end
        end
    end
end

function Config:createPhysicsContrain()
    for i = 1, self.m_nCount do
        if self.m_tbActor[i] ~= nil then
            if (i % self.m_nCountX) ~= 0 then
                local k, f = math.modf(i / self.m_nCountX);
                local j = i + 1;
                local n = 1;
                while j < (k + 1) * self.m_nCountX and self.m_tbActor[j] == nil do
                    j = j + 1;
                    n = n + 1;
                end
                if j <= (k + 1) * self.m_nCountX and self.m_tbActor[j] ~= nil then
                    local t1 = KTransform();
                    local t2 = KTransform();
                    t1:SetTranslation(KVec3(self.m_GeometryBoxHalfLen.x * n, 0, 0));
                    t2:SetTranslation(KVec3(-self.m_GeometryBoxHalfLen.x * n, 0, 0));
                    local joint = g_ActorManager:CreateConstraintActor(self.m_tbActor[i], t1, self.m_tbActor[j], t2);
                    joint:SetLinearXMotion(ELCM_LIMITED);
                    joint:SetLinearYMotion(ELCM_LOCKED);
                    joint:SetLinearZMotion(ELCM_LOCKED);
                    joint:SetLinearLimit(0.0, self.m_GeometryBoxHalfLen.x * 2 * (n - 1), 0.0);
                    joint:SetBreakForce(100.0, 100.0);
                    joint:SetAngularTwistMotion(ELCM_LOCKED);
                end
            end
            if i <= self.m_nCount - self.m_nCountX * self.m_nCountZ then
                local j = i + self.m_nCountX * self.m_nCountZ;
                local n = 1;
                while j < self.m_nCount and self.m_tbActor[j] == nil do
                    j = j + self.m_nCountX * self.m_nCountZ;
                    n = n + 1;
                end
                if j <= self.m_nCount and self.m_tbActor[j] ~= nil then
                    local t1 = KTransform();
                    local t2 = KTransform();
                    t1:SetTranslation(KVec3(0, self.m_GeometryBoxHalfLen.y * n, 0));
                    t2:SetTranslation(KVec3(0, -self.m_GeometryBoxHalfLen.y * n, 0));
                    local joint = g_ActorManager:CreateConstraintActor(self.m_tbActor[i], t1, self.m_tbActor[j], t2);
                    joint:SetLinearXMotion(ELCM_LOCKED);
                    joint:SetLinearYMotion(ELCM_LIMITED);
                    joint:SetLinearZMotion(ELCM_LOCKED);
                    joint:SetLinearLimit(0.0, self.m_GeometryBoxHalfLen.y * 2 * (n - 1), 0.0);
                    joint:SetBreakForce(100.0, 100.0);
                    joint:SetAngularTwistMotion(ELCM_LOCKED);
                end
            end
            local k, f = math.modf((i - 1) / self.m_nCountX);
            if ((k + 1) % self.m_nCountZ) ~= 0 then
                local j = i + self.m_nCountX;
                local n = 1;
                k, f = math.modf((i - 1) / (self.m_nCountX * self.m_nCountZ));
                while j < (k + 1) * self.m_nCountX * self.m_nCountZ and self.m_tbActor[j] == nil do
                    j = j + self.m_nCountX;
                    n = n + 1;
                end
                if j <= (k + 1) * self.m_nCountX * self.m_nCountZ and self.m_tbActor[j] ~= nil then
                    local t1 = KTransform();
                    local t2 = KTransform();
                    t1:SetTranslation(KVec3(0, 0, self.m_GeometryBoxHalfLen.z * n));
                    t2:SetTranslation(KVec3(0, 0, -self.m_GeometryBoxHalfLen.z * n));
                    local joint = g_ActorManager:CreateConstraintActor(self.m_tbActor[i], t1, self.m_tbActor[j], t2);
                    joint:SetLinearXMotion(ELCM_LOCKED);
                    joint:SetLinearYMotion(ELCM_LOCKED);
                    joint:SetLinearZMotion(ELCM_LIMITED);
                    joint:SetLinearLimit(0.0, self.m_GeometryBoxHalfLen.z * 2 * (n - 1), 0.0);
                    joint:SetBreakForce(100.0, 100.0);
                    joint:SetAngularTwistMotion(ELCM_LOCKED);
                end
            end
        end
    end
end

---@return isSuccessful 
function Config:loadData()
    self.m_FileContent = JSON.Loadf("ugc_common/script/cases/destruction/test.json", nil);
    if self.m_FileContent == nil then
        return false;
    else
        return true;
    end
end

function Config:savePhysicsActors()

    -- 物理对象的位置、selflent
    -- 模型的位置、大小、旋转、对应的物理块
    self.m_tbPhyciscActors = {
        GeometryBoxHalfLen = {self.m_GeometryBoxHalfLen.x,
                              self.m_GeometryBoxHalfLen.y,
                              self.m_GeometryBoxHalfLen.z}
    }

    for i = 1, self.m_nCount do
        if self.m_tbActor[i] ~= nil then 
            local lPlayer = g_ActorManager:GetLocalPlayer();
            local _, originX, originY, originZ = lPlayer:GetWorldPosition();
            local _, x, y, z = self.m_tbActor[i]:GetWorldPosition();
            local actor = {
                LocalPosition = {x - originX, y - originY, z - originZ}
            }
            self.m_tbPhyciscActors["Actor"..i] = actor;
        end
    end
end

function Config:saveData()
    JSON.Dumpf(self.m_tbPhyciscActors, "ugc_common/script/cases/destruction/test.json");
end

Cfg = Config:new();


