void TransformPositionAll(char *label){ FILE *fp; if((fp = fopen("../plot/Tetra-Triprism.stl", "w"))==NULL){ printf("ファイルをオープンできません\n"); } else { srand((unsigned)time(NULL)); prStlProlog(label, fp); TransformPosition((char*)"Tetra", fp); TransformPosition((char*)"Triprism", fp); prStlEpilog(label, fp); fclose(fp); } }
void CBody::Draw(CLensFlare *flare) { TransformPosition(); if (mainbody) { ringchain.nextring=ringchain.prevring=&ringchain; } for (int i=0;i<numsubbodies;i++) { glPushMatrix(); subbodies[i].Draw(NULL); glPopMatrix(); } if (mainbody) { if (flare) flare->UpdatePos(); } glRotatef((type!=rings?own_rot:orbit_rot),0.0f,0.0f,1.0f); if (type!=rings) { if (textures[3]>0) TransformClouds(); DrawGFX(); } else { SortNonSolidObject(); } if (mainbody) { DrawSortedNonSolids(); } }
Light::Light(LightType t, float x, float y, float z, float r, float g, float b, float konst/* =1.0f */, float linear/* =0.0f */, float quad/* =0.0f */) { type = t; position = vec3(x, y, z); if(t == DIRECTIONAL) TransformDirection(position, currMatrix); else TransformPosition(position, currMatrix); color = Color(r, g, b); attenuation = vec3(konst, linear, quad); if(type == DIRECTIONAL) lightDir = glm::normalize(position); }
void CPHShell::Activate(const Fmatrix &m0,float dt01,const Fmatrix &m2,bool disable){ if(isActive())return; activate(disable); // ELEMENT_I i; mXFORM.set(m0); //for(i=elements.begin();elements.end() != i;++i){ // (*i)->Activate(m0,dt01, m2, disable); //} { ELEMENT_I i=elements.begin(),e=elements.end(); for(;i!=e;++i)(*i)->Activate(mXFORM,disable); } { JOINT_I i=joints.begin(),e=joints.end(); for(;i!=e;++i) (*i)->Activate(); } Fmatrix m; { Fmatrix old_m = mXFORM;//+GetGlobalTransformDynamic update mXFORM; GetGlobalTransformDynamic (&m); mXFORM = old_m; } m.invert();m.mulA_43 (mXFORM); TransformPosition(m); if(PKinematics()) { SetCallbacks( ); } //bActive=true; //bActivating=true; m_flags.set(flActive,TRUE); m_flags.set(flActivating,TRUE); spatial_register(); /////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //mXFORM.set(m0); //Activate(disable); Fvector lin_vel; lin_vel.sub(m2.c,m0.c); set_LinearVel(lin_vel); }
bool CMotionControl::Test(const mm1000_t src[NUM_AXIS],const mm1000_t ofs[NUM_AXIS],mm1000_t dest[NUM_AXIS], bool printOK, std::function<void()> print) { udist_t to_m[NUM_AXIS]; mm1000_t toorig[NUM_AXIS]; memcpy(dest,src,sizeof(toorig)); bool isError = false; if (TransformPosition(src,dest)) { ToMachine(dest, to_m); TransformFromMachinePosition(to_m,toorig); for (uint8_t i = 0; i < NUM_AXIS && !isError; i++) isError = CompareMaxDiff(src[i], toorig[i]); } else { isError = true; } if (printOK || isError) { DumpArray<mm1000_t, NUM_AXIS>(F("Src"), src, false); DumpArray<mm1000_t, NUM_AXIS>(F("Ofs"), ofs, false); print(); DumpArray<mm1000_t, NUM_AXIS>(F(" =>"), dest, false); DumpArray<mm1000_t, NUM_AXIS>(F("Back"), toorig, false); if (isError) printf(" ERROR"); printf("\n"); } return isError; }
void CBody::Predict(int bodyid, bool now, float seconds, float *x, float *y, float *z) { if (mainbody) glLoadIdentity(); if (!now) UpdateOrbit(seconds); //no glLoadIdentity call, so coords are relative to camera TransformPosition(); if (bodyid==id) { glPushMatrix(); glGetFloatv(GL_MODELVIEW_MATRIX,objectmatrix); *x=objectmatrix[12]; *y=objectmatrix[13]; *z=objectmatrix[14]; glPopMatrix(); return; } // note: no error checking for incorrect results or protection faults int i; for (i=0; i<numsubbodies;i++) if (subbodies[i].id>bodyid) break; subbodies[--i].Predict(bodyid,now,seconds,x,y,z); }
static void ExportAnimations(ExportContext& Context, FArchive& Ar) { guard(ExportAnimations); const CAnimSet* Anim = Context.SkelMesh->Anim; int NumBones = Context.SkelMesh->RefSkeleton.Num(); // Build mesh to anim bone map TArray<int> BoneMap; BoneMap.Init(-1, NumBones); TArray<int> AnimBones; AnimBones.Empty(NumBones); for (int i = 0; i < NumBones; i++) { const CSkelMeshBone &B = Context.SkelMesh->RefSkeleton[i]; for (int j = 0; j < Anim->TrackBoneNames.Num(); j++) { if (!stricmp(B.Name, Anim->TrackBoneNames[j])) { BoneMap[i] = j; // lookup CAnimSet bone by mesh bone index AnimBones.Add(i); // indicate that the bone has animation break; } } } Ar.Printf( " \"animations\" : [\n" ); int FirstDataIndex = Context.Data.Num(); // Iterate over all animations for (int SeqIndex = 0; SeqIndex < Anim->Sequences.Num(); SeqIndex++) { const CAnimSequence &Seq = *Anim->Sequences[SeqIndex]; Ar.Printf( " {\n" " \"name\" : \"%s\",\n", *Seq.Name ); struct AnimSampler { enum ChannelType { TRANSLATION, ROTATION }; int BoneNodeIndex; ChannelType Type; const CAnimTrack* Track; }; TArray<AnimSampler> Samplers; Samplers.Empty(AnimBones.Num() * 2); //!! Optimization: //!! 1. there will be missing tracks (AnimRotationOnly etc) - drop such samplers //!! 2. store all time tracks in a single BufferView, all rotation tracks in another, and all position track in 3rd one - this //!! will reduce amount of BufferViews in json text (combine them by data type) // Prepare channels array Ar.Printf(" \"channels\" : [\n"); for (int BoneIndex = 0; BoneIndex < AnimBones.Num(); BoneIndex++) { int MeshBoneIndex = AnimBones[BoneIndex]; int AnimBoneIndex = BoneMap[MeshBoneIndex]; const CAnimTrack* Track = Seq.Tracks[AnimBoneIndex]; int TranslationSamplerIndex = Samplers.Num(); AnimSampler* Sampler = new (Samplers) AnimSampler; Sampler->Type = AnimSampler::TRANSLATION; Sampler->BoneNodeIndex = MeshBoneIndex + FIRST_BONE_NODE; Sampler->Track = Track; int RotationSamplerIndex = Samplers.Num(); Sampler = new (Samplers) AnimSampler; Sampler->Type = AnimSampler::ROTATION; Sampler->BoneNodeIndex = MeshBoneIndex + FIRST_BONE_NODE; Sampler->Track = Track; // Print glTF information. Not using usual formatting here to make output a little bit more compact. Ar.Printf( " { \"sampler\" : %d, \"target\" : { \"node\" : %d, \"path\" : \"%s\" } },\n", TranslationSamplerIndex, MeshBoneIndex + FIRST_BONE_NODE, "translation" ); Ar.Printf( " { \"sampler\" : %d, \"target\" : { \"node\" : %d, \"path\" : \"%s\" } }%s\n", RotationSamplerIndex, MeshBoneIndex + FIRST_BONE_NODE, "rotation", BoneIndex == AnimBones.Num()-1 ? "" : "," ); } Ar.Printf(" ],\n"); // Prepare samplers Ar.Printf(" \"samplers\" : [\n"); for (int SamplerIndex = 0; SamplerIndex < Samplers.Num(); SamplerIndex++) { const AnimSampler& Sampler = Samplers[SamplerIndex]; // Prepare time array const TArray<float>* TimeArray = (Sampler.Type == AnimSampler::TRANSLATION) ? &Sampler.Track->KeyPosTime : &Sampler.Track->KeyQuatTime; if (TimeArray->Num() == 0) { // For this situation, use track's time array TimeArray = &Sampler.Track->KeyTime; } int NumKeys = Sampler.Type == (AnimSampler::TRANSLATION) ? Sampler.Track->KeyPos.Num() : Sampler.Track->KeyQuat.Num(); int TimeBufIndex = Context.Data.AddZeroed(); BufferData& TimeBuf = Context.Data[TimeBufIndex]; TimeBuf.Setup(NumKeys, "SCALAR", BufferData::FLOAT, sizeof(float)); float RateScale = 1.0f / Seq.Rate; float LastFrameTime = 0; if (TimeArray->Num() == 0 || NumKeys == 1) { // Fill with equally spaced values for (int i = 0; i < NumKeys; i++) { TimeBuf.Put(i * RateScale); } LastFrameTime = NumKeys-1; } else { for (int i = 0; i < TimeArray->Num(); i++) { TimeBuf.Put((*TimeArray)[i] * RateScale); } LastFrameTime = (*TimeArray)[TimeArray->Num()-1]; } // Prepare min/max values for time track, it's required by glTF standard TimeBuf.BoundsMin = "[ 0 ]"; char buf[64]; appSprintf(ARRAY_ARG(buf), "[ %g ]", LastFrameTime * RateScale); TimeBuf.BoundsMax = buf; // Try to reuse TimeBuf from previous tracks TimeBufIndex = Context.GetFinalIndexForLastBlock(FirstDataIndex); // Prepare data int DataBufIndex = Context.Data.AddZeroed(); BufferData& DataBuf = Context.Data[DataBufIndex]; if (Sampler.Type == AnimSampler::TRANSLATION) { // Translation track DataBuf.Setup(NumKeys, "VEC3", BufferData::FLOAT, sizeof(CVec3)); for (int i = 0; i < NumKeys; i++) { CVec3 Pos = Sampler.Track->KeyPos[i]; TransformPosition(Pos); DataBuf.Put(Pos); } } else { // Rotation track DataBuf.Setup(NumKeys, "VEC4", BufferData::FLOAT, sizeof(CQuat)); for (int i = 0; i < NumKeys; i++) { CQuat Rot = Sampler.Track->KeyQuat[i]; TransformRotation(Rot); if (Sampler.BoneNodeIndex - FIRST_BONE_NODE == 0) { Rot.Conjugate(); } DataBuf.Put(Rot); } } // Try to reuse data block as well DataBufIndex = Context.GetFinalIndexForLastBlock(FirstDataIndex); // Write glTF info Ar.Printf( " { \"input\" : %d, \"output\" : %d }%s\n", TimeBufIndex, DataBufIndex, SamplerIndex == Samplers.Num()-1 ? "" : "," ); } Ar.Printf(" ]\n"); Ar.Printf(" }%s\n", SeqIndex == Anim->Sequences.Num()-1 ? "" : ","); } Ar.Printf(" ],\n"); unguard; }
static void ExportSkinData(ExportContext& Context, const CSkelMeshLod& Lod, FArchive& Ar) { guard(ExportSkinData); int numBones = Context.SkelMesh->RefSkeleton.Num(); int MatrixBufIndex = Context.Data.AddZeroed(); BufferData& MatrixBuf = Context.Data[MatrixBufIndex]; MatrixBuf.Setup(numBones, "MAT4", BufferData::FLOAT, sizeof(CMat4)); Ar.Printf( " \"nodes\" : [\n" " {\n" " \"name\" : \"%s\",\n" " \"mesh\" : 0,\n" " \"skin\" : 0,\n" " \"children\" : [ 1 ]\n" " },\n", Context.MeshName); TArray<CCoords> BoneCoords; BoneCoords.AddZeroed(numBones); for (int boneIndex = 0; boneIndex < numBones; boneIndex++) { const CSkelMeshBone& B = Context.SkelMesh->RefSkeleton[boneIndex]; // Find all children TStaticArray<int, 32> children; for (int j = 0; j < numBones; j++) { if (boneIndex == j) continue; const CSkelMeshBone& B2 = Context.SkelMesh->RefSkeleton[j]; if (B2.ParentIndex == boneIndex) { children.Add(j); } } Ar.Printf( " {\n" " \"name\" : \"%s\",\n", *B.Name ); // Write children if (children.Num()) { Ar.Printf(" \"children\" : [ %d", children[0]+FIRST_BONE_NODE); for (int j = 1; j < children.Num(); j++) { Ar.Printf(", %d", children[j]+FIRST_BONE_NODE); } Ar.Printf(" ],\n"); } // Bone transform CVec3 bonePos = B.Position; CQuat boneRot = B.Orientation; if (boneIndex == 0) { boneRot.Conjugate(); } TransformPosition(bonePos); TransformRotation(boneRot); Ar.Printf( " \"translation\" : [ %g, %g, %g ],\n" " \"rotation\" : [ %g, %g, %g, %g ]\n", bonePos[0], bonePos[1], bonePos[2], boneRot.x, boneRot.y, boneRot.z, boneRot.w ); boneRot.w *= -1; CCoords& BC = BoneCoords[boneIndex]; BC.origin = bonePos; boneRot.ToAxis(BC.axis); if (boneIndex) { // World coordinate BoneCoords[B.ParentIndex].UnTransformCoords(BC, BC); } CCoords InvCoords; InvertCoords(BC, InvCoords); CMat4 BC4x4(InvCoords); MatrixBuf.Put(BC4x4); // Closing brace Ar.Printf( " }%s\n", boneIndex == (numBones-1) ? "" : "," ); } // Close "nodes" array Ar.Printf(" ],\n"); // Make "skins" Ar.Printf( " \"skins\" : [\n" " {\n" " \"inverseBindMatrices\" : %d,\n" " \"skeleton\" : 1,\n" " \"joints\" : [", MatrixBufIndex ); for (int i = 0; i < numBones; i++) { if ((i & 31) == 0) Ar.Printf("\n "); Ar.Printf("%d%s", i+FIRST_BONE_NODE, (i == numBones-1) ? "" : ","); } Ar.Printf( "\n" " ]\n" " }\n" " ],\n" ); unguard; }
static void ExportSection(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, int SectonIndex, FArchive& Ar) { guard(ExportSection); int VertexSize = Context.IsSkeletal() ? sizeof(CSkelMeshVertex) : sizeof(CStaticMeshVertex); const CMeshSection& S = Lod.Sections[SectonIndex]; bool bLast = (SectonIndex == Lod.Sections.Num()-1); // Remap section indices to local indices CIndexBuffer::IndexAccessor_t GetIndex = Lod.Indices.GetAccessor(); TArray<int> indexRemap; // old vertex index -> new vertex index indexRemap.Init(-1, Lod.NumVerts); int numLocalVerts = 0; int numLocalIndices = S.NumFaces * 3; for (int idx = 0; idx < numLocalIndices; idx++) { int vertIndex = GetIndex(S.FirstIndex + idx); if (indexRemap[vertIndex] == -1) { indexRemap[vertIndex] = numLocalVerts++; } } // Prepare buffers int IndexBufIndex = Context.Data.AddZeroed(); int PositionBufIndex = Context.Data.AddZeroed(); int NormalBufIndex = Context.Data.AddZeroed(); int TangentBufIndex = Context.Data.AddZeroed(); int BonesBufIndex = -1; int WeightsBufIndex = -1; if (Context.IsSkeletal()) { BonesBufIndex = Context.Data.AddZeroed(); WeightsBufIndex = Context.Data.AddZeroed(); } int UVBufIndex[MAX_MESH_UV_SETS]; for (int i = 0; i < Lod.NumTexCoords; i++) { UVBufIndex[i] = Context.Data.AddZeroed(); } BufferData& IndexBuf = Context.Data[IndexBufIndex]; BufferData& PositionBuf = Context.Data[PositionBufIndex]; BufferData& NormalBuf = Context.Data[NormalBufIndex]; BufferData& TangentBuf = Context.Data[TangentBufIndex]; BufferData* UVBuf[MAX_MESH_UV_SETS]; BufferData* BonesBuf = NULL; BufferData* WeightsBuf = NULL; PositionBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); NormalBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); TangentBuf.Setup(numLocalVerts, "VEC4", BufferData::FLOAT, sizeof(CVec4)); for (int i = 0; i < Lod.NumTexCoords; i++) { UVBuf[i] = &Context.Data[UVBufIndex[i]]; UVBuf[i]->Setup(numLocalVerts, "VEC2", BufferData::FLOAT, sizeof(CMeshUVFloat)); } if (Context.IsSkeletal()) { BonesBuf = &Context.Data[BonesBufIndex]; WeightsBuf = &Context.Data[WeightsBufIndex]; BonesBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_SHORT, sizeof(uint16)*4); WeightsBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_BYTE, sizeof(uint32), /*InNormalized=*/ true); } // Prepare and build indices TArray<int> localIndices; localIndices.AddUninitialized(numLocalIndices); int* pIndex = localIndices.GetData(); for (int i = 0; i < numLocalIndices; i++) { *pIndex++ = GetIndex(S.FirstIndex + i); } if (numLocalVerts <= 65536) { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_SHORT, sizeof(uint16)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint16>(indexRemap[localIndices[idx]]); } } else { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_INT, sizeof(uint32)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint32>(indexRemap[localIndices[idx]]); } } // Build reverse index map for fast lookup of vertex by its new index. // It maps new vertex index to old vertex index. TArray<int> revIndexMap; revIndexMap.AddUninitialized(numLocalVerts); for (int i = 0; i < indexRemap.Num(); i++) { int newIndex = indexRemap[i]; if (newIndex != -1) { revIndexMap[newIndex] = i; } } // Build vertices for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V = VERT(vertIndex); CVec3 Position = V.Position; CVec4 Normal, Tangent; Unpack(Normal, V.Normal); Unpack(Tangent, V.Tangent); // Unreal (and we are) using normal.w for computing binormal. glTF // uses tangent.w for that. Make this value exactly 1.0 of -1.0 to make glTF // validator happy. #if 0 // There's some problem: V.Normal.W == 0x80 -> -1.008 instead of -1.0 if (Normal.w > 1.001 || Normal.w < -1.001) { appError("%X -> %g\n", V.Normal.Data, Normal.w); } #endif Tangent.w = (Normal.w < 0) ? -1 : 1; TransformPosition(Position); TransformDirection(Normal); TransformDirection(Tangent); Normal.Normalize(); Tangent.Normalize(); // Fill buffers PositionBuf.Put(Position); NormalBuf.Put(Normal.xyz); TangentBuf.Put(Tangent); UVBuf[0]->Put(V.UV); } // Compute bounds for PositionBuf CVec3 Mins, Maxs; ComputeBounds((CVec3*)PositionBuf.Data, numLocalVerts, sizeof(CVec3), Mins, Maxs); char buf[256]; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Mins)); PositionBuf.BoundsMin = buf; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Maxs)); PositionBuf.BoundsMax = buf; if (Context.IsSkeletal()) { for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V0 = VERT(vertIndex); const CSkelMeshVertex& V = static_cast<const CSkelMeshVertex&>(V0); int16 Bones[NUM_INFLUENCES]; static_assert(NUM_INFLUENCES == 4, "Code designed for 4 influences"); static_assert(sizeof(Bones) == sizeof(V.Bone), "Unexpected V.Bones size"); memcpy(Bones, V.Bone, sizeof(Bones)); for (int j = 0; j < NUM_INFLUENCES; j++) { // We have INDEX_NONE as list terminator, should replace with something else for glTF if (Bones[j] == INDEX_NONE) { Bones[j] = 0; } } BonesBuf->Put(*(uint64*)&Bones); WeightsBuf->Put(V.PackedWeights); } } // Secondary UVs for (int uvIndex = 1; uvIndex < Lod.NumTexCoords; uvIndex++) { BufferData* pBuf = UVBuf[uvIndex]; const CMeshUVFloat* srcUV = Lod.ExtraUV[uvIndex-1]; for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; pBuf->Put(srcUV[vertIndex]); } } // Write primitive information to json Ar.Printf( " {\n" " \"attributes\" : {\n" " \"POSITION\" : %d,\n" " \"NORMAL\" : %d,\n" " \"TANGENT\" : %d,\n", PositionBufIndex, NormalBufIndex, TangentBufIndex ); if (Context.IsSkeletal()) { Ar.Printf( " \"JOINTS_0\" : %d,\n" " \"WEIGHTS_0\" : %d,\n", BonesBufIndex, WeightsBufIndex ); } for (int i = 0; i < Lod.NumTexCoords; i++) { Ar.Printf( " \"TEXCOORD_%d\" : %d%s\n", i, UVBufIndex[i], i < (Lod.NumTexCoords-1) ? "," : "" ); } Ar.Printf( " },\n" " \"indices\" : %d,\n" " \"material\" : %d\n" " }%s\n", IndexBufIndex, SectonIndex, SectonIndex < (Lod.Sections.Num()-1) ? "," : "" ); unguard; }
void TransformRay(Ray &ray, const mat4 &matrix) { TransformPosition(ray.origin, matrix); TransformDirection(ray.direction, matrix); ray.direction = glm::normalize(ray.direction); }